View Javadoc

1   /*
2    * This file is part of Domingo
3    * an Open Source Java-API to Lotus Notes/Domino
4    * hosted at http://domingo.sourceforge.net
5    *
6    * Copyright (c) 2003-2007 Beck et al. projects GmbH Munich, Germany (http://www.bea.de)
7    *
8    * This library is free software; you can redistribute it and/or
9    * modify it under the terms of the GNU Lesser General Public
10   * License as published by the Free Software Foundation; either
11   * version 2.1 of the License, or (at your option) any later version.
12   *
13   * This library is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   * Lesser General Public License for more details.
17   *
18   * You should have received a copy of the GNU Lesser General Public
19   * License along with this library; if not, write to the Free Software
20   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21   */
22  
23  package de.bea.domingo.proxy;
24  
25  import java.util.Calendar;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.NoSuchElementException;
29  import java.util.Vector;
30  
31  import lotus.domino.DateRange;
32  import lotus.domino.DateTime;
33  import lotus.domino.Document;
34  import lotus.domino.DocumentCollection;
35  import lotus.domino.NotesException;
36  import lotus.domino.View;
37  import lotus.domino.ViewColumn;
38  import lotus.domino.ViewEntry;
39  import lotus.domino.ViewEntryCollection;
40  import lotus.domino.ViewNavigator;
41  import de.bea.domingo.DBase;
42  import de.bea.domingo.DDatabase;
43  import de.bea.domingo.DDocument;
44  import de.bea.domingo.DNotesIterator;
45  import de.bea.domingo.DNotesMonitor;
46  import de.bea.domingo.DNotesRuntimeException;
47  import de.bea.domingo.DView;
48  import de.bea.domingo.DViewColumn;
49  import de.bea.domingo.DViewEntry;
50  
51  /***
52   * Represents the Domino-Class <code>View</code>.
53   *
54   * @author <a href=mailto:kriede@users.sourceforge.net>Kurt Riede</a>
55   */
56  public final class ViewProxy extends BaseCollectionProxy implements DView {
57  
58      /*** serial version ID for serialization. */
59      private static final long serialVersionUID = 3832616283597780788L;
60  
61      /*** The name of the view for fast access. */
62      private String name = null;
63  
64      /***
65       * Constructor.
66       *
67       * @param theFactory the controlling factory
68       * @param database Notes database
69       * @param view the Notes View
70       * @param monitor the monitor
71       */
72      private ViewProxy(final NotesProxyFactory theFactory, final DDatabase database,
73                        final View view, final DNotesMonitor monitor) {
74          super(theFactory, database, view, monitor);
75          name = getNameIntern();
76      }
77  
78      /***
79       * Returns a view object.
80       *
81       * @param theFactory the controlling factory
82       * @param database Notes database
83       * @param view the notes view object
84       * @param monitor the monitor
85       * @return a view object
86       */
87      static ViewProxy getInstance(final NotesProxyFactory theFactory, final DDatabase database,
88                                   final View view, final DNotesMonitor monitor) {
89          if (view == null) {
90              return null;
91          }
92          ViewProxy viewProxy = (ViewProxy) theFactory.getBaseCache().get(view);
93          if (viewProxy == null) {
94              viewProxy = new ViewProxy(theFactory, database, view, monitor);
95              viewProxy.setMonitor(monitor);
96              theFactory.getBaseCache().put(view, viewProxy);
97          }
98          return viewProxy;
99      }
100 
101     /***
102      * Returns the associated Notes view.
103      *
104      * @return associated Notes view
105      */
106     private View getView() {
107         return (View) getNotesObject();
108     }
109 
110     /***
111      * @see de.bea.domingo.DView#refresh()
112      */
113     public void refresh() {
114         getFactory().preprocessMethod();
115         try {
116             getView().refresh();
117         } catch (NotesException e) {
118             throw newRuntimeException("Cannot refresh view", e);
119         }
120     }
121 
122     /***
123      * {@inheritDoc}
124      * @see de.bea.domingo.DView#getName()
125      */
126     public String getName() {
127         return name;
128     }
129 
130     /***
131      * {@inheritDoc}
132      * @see de.bea.domingo.DView#getName()
133      */
134     private String getNameIntern() {
135         getFactory().preprocessMethod();
136         try {
137             return getView().getName();
138         } catch (NotesException e) {
139             throw newRuntimeException("Cannot get name", e);
140         }
141     }
142 
143     /***
144      * {@inheritDoc}
145      * @see de.bea.domingo.DView#getDocumentByKey(String, boolean)
146      */
147     public DDocument getDocumentByKey(final String key, final boolean exact) {
148         getFactory().preprocessMethod();
149         try {
150             final Document doc = getView().getDocumentByKey(key, exact);
151             return (DDocument) BaseDocumentProxy.getInstance(getFactory(), this, doc, getMonitor());
152         } catch (NotesException e) {
153             throw newRuntimeException("Cannot get document by key", e);
154         }
155     }
156 
157     /***
158      * {@inheritDoc}
159      * @see de.bea.domingo.DView#getDocumentByKey(List,boolean)
160      */
161     public DDocument getDocumentByKey(final List keys, final boolean exact) {
162         getFactory().preprocessMethod();
163         final List convertedKeys = convertCalendarsToNotesDateTime(keys);
164         final Vector vector = convertListToVector(convertedKeys);
165         try {
166             final Document document = getView().getDocumentByKey(vector, exact);
167             return (DDocument) BaseDocumentProxy.getInstance(getFactory(), this, document, getMonitor());
168         } catch (NotesException e) {
169             throw newRuntimeException("Cannot get document by key list", e);
170         } finally {
171             recycleDateTimeList(convertedKeys);
172         }
173     }
174 
175     /***
176      * {@inheritDoc}
177      * @see de.bea.domingo.DView#getAllDocumentsByKey(java.util.List)
178      */
179     public Iterator getAllDocumentsByKey(final List keys) {
180         getFactory().preprocessMethod();
181         final List convertedKeys = convertCalendarsToNotesDateTime(keys);
182         final Vector vector = convertListToVector(convertedKeys);
183         try {
184             final DocumentCollection coll = getView().getAllDocumentsByKey(vector);
185             return new DocumentCollectionIterator(getFactory(), getParent(), coll, getMonitor());
186         } catch (NotesException e) {
187             throw newRuntimeException("Cannot get all documents by key list", e);
188         } finally {
189             recycleDateTimeList(convertedKeys);
190         }
191     }
192 
193     /***
194      * {@inheritDoc}
195      * @see de.bea.domingo.DView#getAllDocumentsByKey(java.lang.String)
196      */
197     public Iterator getAllDocumentsByKey(final String key) {
198         return getAllDocumentsByKey(key, false);
199     }
200 
201     /***
202      * {@inheritDoc}
203      * @see de.bea.domingo.DView#getAllDocumentsByKey(java.lang.String, boolean)
204      */
205     public Iterator getAllDocumentsByKey(final String key, final boolean exact) {
206         getFactory().preprocessMethod();
207         try {
208             final DocumentCollection collection = getView().getAllDocumentsByKey(key, exact);
209             return new DocumentCollectionIterator(getFactory(), getParent(), collection, getMonitor());
210         } catch (NotesException e) {
211             throw newRuntimeException("Cannot get all documents by key", e);
212         }
213     }
214 
215     /***
216      * {@inheritDoc}
217      * @see de.bea.domingo.DView#getAllDocumentsByKey(java.util.List, boolean)
218      */
219     public Iterator getAllDocumentsByKey(final List keys, final boolean exact) {
220         getFactory().preprocessMethod();
221         final List convertedKeys = convertCalendarsToNotesDateTime(keys);
222         final Vector vector = convertListToVector(convertedKeys);
223         try {
224             final DocumentCollection coll = getView().getAllDocumentsByKey(vector, exact);
225             return new DocumentCollectionIterator(getFactory(), getParent(), coll, getMonitor());
226         } catch (NotesException e) {
227             throw newRuntimeException("Cannot get all documents by list", e);
228         } finally {
229             recycleDateTimeList(convertedKeys);
230         }
231     }
232 
233     /***
234      * {@inheritDoc}
235      * @see de.bea.domingo.DView#getAllDocumentsByKey(java.util.Calendar)
236      */
237     public Iterator getAllDocumentsByKey(final Calendar key) {
238         return getAllDocumentsByKey(key, false);
239     }
240 
241     /***
242      * {@inheritDoc}
243      * @see de.bea.domingo.DView#getAllDocumentsByKey(double)
244      */
245     public Iterator getAllDocumentsByKey(final double key) {
246         return getAllDocumentsByKey(key, false);
247     }
248 
249     /***
250      * {@inheritDoc}
251      * @see de.bea.domingo.DView#getAllDocumentsByKey(int)
252      */
253     public Iterator getAllDocumentsByKey(final int key) {
254         return getAllDocumentsByKey(key, false);
255     }
256 
257     /***
258      * {@inheritDoc}
259      * @see de.bea.domingo.DView#getAllDocumentsByKey(java.util.Calendar, boolean)
260      */
261     public Iterator getAllDocumentsByKey(final Calendar key, final boolean exact) {
262         getFactory().preprocessMethod();
263         try {
264             final DateTime dateTime = createDateTime(key);
265             final DocumentCollection collection = getView().getAllDocumentsByKey(dateTime, exact);
266             getFactory().recycle(dateTime);
267             return new DocumentCollectionIterator(getFactory(), getParent(), collection, getMonitor());
268         } catch (NotesException e) {
269             throw newRuntimeException("Cannot get all documents by key", e);
270         }
271     }
272 
273     /***
274      * {@inheritDoc}
275      * @see de.bea.domingo.DView#getAllDocumentsByKey(double, boolean)
276      */
277     public Iterator getAllDocumentsByKey(final double key, final boolean exact) {
278         getFactory().preprocessMethod();
279         try {
280             final DocumentCollection collection = getView().getAllDocumentsByKey(new Double(key), exact);
281             return new DocumentCollectionIterator(getFactory(), getParent(), collection, getMonitor());
282         } catch (NotesException e) {
283             throw newRuntimeException("Cannot get all documents by key", e);
284         }
285     }
286 
287     /***
288      * {@inheritDoc}
289      * @see de.bea.domingo.DView#getAllDocumentsByKey(int, boolean)
290      */
291     public Iterator getAllDocumentsByKey(final int key, final boolean exact) {
292         getFactory().preprocessMethod();
293         try {
294             final DocumentCollection collection = getView().getAllDocumentsByKey(new Integer(key), exact);
295             return new DocumentCollectionIterator(getFactory(), getParent(), collection, getMonitor());
296         } catch (NotesException e) {
297             throw newRuntimeException("Cannot get all documents by key", e);
298         }
299     }
300 
301     /***
302      * {@inheritDoc}
303      * @see de.bea.domingo.DView#getAllDocuments()
304      */
305     public Iterator getAllDocuments() {
306         return new ViewIterator(this);
307     }
308 
309     /***
310      * {@inheritDoc}
311      * @see de.bea.domingo.proxy.BaseProxy#toString()
312      */
313     public String toString() {
314         return getName();
315     }
316 
317     /***
318      * {@inheritDoc}
319      * @see de.bea.domingo.DView#getAllEntries()
320      */
321     public Iterator getAllEntries() {
322         getFactory().preprocessMethod();
323         try {
324             final ViewEntryCollection coll = getView().getAllEntries();
325             return new ViewEntriesIterator(coll);
326         } catch (NotesException e) {
327             throw newRuntimeException("Cannot get all entries", e);
328         }
329     }
330 
331     /***
332      * {@inheritDoc}
333      * @see de.bea.domingo.DView#getAllEntriesReverse()()
334      */
335     public Iterator getAllEntriesReverse() {
336         getFactory().preprocessMethod();
337         try {
338             final ViewEntryCollection coll = getView().getAllEntries();
339             return new ViewEntriesReverseIterator(coll);
340         } catch (NotesException e) {
341             throw newRuntimeException("Cannot get all entries", e);
342         }
343     }
344 
345     /***
346      * {@inheritDoc}
347      * @see de.bea.domingo.DView#getEntryByKey(java.lang.String)
348      */
349     public DViewEntry getEntryByKey(final String key) {
350         getFactory().preprocessMethod();
351         try {
352             final ViewEntry entry = getView().getEntryByKey(key);
353             return (DViewEntry) ViewEntryProxy.getInstance(getFactory(), this, entry, getMonitor());
354         } catch (NotesException e) {
355             throw newRuntimeException("Cannot get all entries", e);
356         }
357     }
358 
359     /***
360      * {@inheritDoc}
361      * @see de.bea.domingo.DView#getEntryByKey(java.lang.String, boolean)
362      */
363     public DViewEntry getEntryByKey(final String key, final boolean exact) {
364         getFactory().preprocessMethod();
365         try {
366             final ViewEntry entry = getView().getEntryByKey(key, exact);
367             return (DViewEntry) ViewEntryProxy.getInstance(getFactory(), this, entry, getMonitor());
368         } catch (NotesException e) {
369             throw newRuntimeException("Cannot get all entries", e);
370         }
371     }
372 
373     /***
374      * {@inheritDoc}
375      * @see de.bea.domingo.DView#getEntryByKey(java.util.List)
376      */
377     public DViewEntry getEntryByKey(final List keys) {
378         getFactory().preprocessMethod();
379         final List convertedKeys = convertCalendarsToNotesDateTime(keys);
380         final Vector vector = convertListToVector(convertedKeys);
381         try {
382             final ViewEntry entry = getView().getEntryByKey(vector);
383             return (DViewEntry) ViewEntryProxy.getInstance(getFactory(), this, entry, getMonitor());
384         } catch (NotesException e) {
385             throw newRuntimeException("Cannot get all entries", e);
386         }
387     }
388 
389     /***
390      * {@inheritDoc}
391      * @see de.bea.domingo.DView#getEntryByKey(java.util.List, boolean)
392      */
393     public DViewEntry getEntryByKey(final List keys, final boolean exact) {
394         getFactory().preprocessMethod();
395         final List convertedKeys = convertCalendarsToNotesDateTime(keys);
396         final Vector vector = convertListToVector(convertedKeys);
397         try {
398             final ViewEntry entry = getView().getEntryByKey(vector, exact);
399             return (DViewEntry) ViewEntryProxy.getInstance(getFactory(), this, entry, getMonitor());
400         } catch (NotesException e) {
401             throw newRuntimeException("Cannot get all entries", e);
402         }
403     }
404     /***
405      * {@inheritDoc}
406      * @see de.bea.domingo.DView#getAllEntries(de.bea.domingo.DViewEntry)
407      */
408     public Iterator getAllEntries(final DViewEntry entry) {
409         getFactory().preprocessMethod();
410         if (entry == null) {
411             return new EmptyIterator();
412         }
413         try {
414             final ViewEntry notesViewEntry = (ViewEntry) ((ViewEntryProxy) entry).getNotesObject();
415             final ViewNavigator navigator = getView().createViewNavFrom(notesViewEntry);
416             return new ViewNavigatorIterator(navigator, entry);
417         } catch (NotesException e) {
418             throw newRuntimeException("Cannot get all entries by key", e);
419         }
420     }
421 
422     /***
423      * {@inheritDoc}
424      * @see de.bea.domingo.DView#getAllEntriesByKey(java.lang.String)
425      */
426     public Iterator getAllEntriesByKey(final String key) {
427         getFactory().preprocessMethod();
428         try {
429             final ViewEntryCollection coll = getView().getAllEntriesByKey(key);
430             return new ViewEntriesIterator(coll);
431         } catch (NotesException e) {
432             throw newRuntimeException("Cannot get all entries by key", e);
433         }
434     }
435 
436     /***
437      * {@inheritDoc}
438      * @see de.bea.domingo.DView#getAllEntriesByKey(java.lang.String, boolean)
439      */
440     public Iterator getAllEntriesByKey(final String key, final boolean exact) {
441         getFactory().preprocessMethod();
442         try {
443             final ViewEntryCollection coll = getView().getAllEntriesByKey(key, exact);
444             return new ViewEntriesIterator(coll);
445         } catch (NotesException e) {
446             throw newRuntimeException("Cannot get all entries by key", e);
447         }
448     }
449 
450     /***
451      * {@inheritDoc}
452      * @see de.bea.domingo.DView#getAllEntriesByKey(java.util.List)
453      */
454     public Iterator getAllEntriesByKey(final List keys) {
455         getFactory().preprocessMethod();
456         final List convertedKeys = convertCalendarsToNotesDateTime(keys);
457         final Vector vector = convertListToVector(convertedKeys);
458         try {
459             final ViewEntryCollection coll = getView().getAllEntriesByKey(vector);
460             return new ViewEntriesIterator(coll);
461         } catch (NotesException e) {
462             throw newRuntimeException("Cannot get all entries by key list", e);
463         } finally {
464             recycleDateTimeList(convertedKeys);
465         }
466     }
467 
468     /***
469      * {@inheritDoc}
470      * @see de.bea.domingo.DView#getAllEntriesByKey(java.util.List, boolean)
471      */
472     public Iterator getAllEntriesByKey(final List keys, final boolean exact) {
473         getFactory().preprocessMethod();
474         final List convertedKeys = convertCalendarsToNotesDateTime(keys);
475         final Vector vector = convertListToVector(convertedKeys);
476         try {
477             final ViewEntryCollection coll = getView().getAllEntriesByKey(vector, exact);
478             return new ViewEntriesIterator(coll);
479         } catch (NotesException e) {
480             throw newRuntimeException("Cannot get all entries by key", e);
481         } finally {
482             recycleDateTimeList(convertedKeys);
483         }
484     }
485 
486     /***
487      * {@inheritDoc}
488      * @see de.bea.domingo.DView#getAllEntriesByKey(java.util.Calendar, java.util.Calendar, boolean)
489      */
490     public Iterator getAllEntriesByKey(final Calendar start, final Calendar end, final boolean exact) {
491         getFactory().preprocessMethod();
492         DateRange dr = createDateRange(start, end);
493         try {
494             final ViewEntryCollection coll = getView().getAllEntriesByKey(dr, exact);
495             return new ViewEntriesIterator(coll);
496         } catch (NotesException e) {
497             throw newRuntimeException("Cannot get all entries by key", e);
498         }
499     }
500 
501 
502     /***
503      * Creates and returns a Proxy for a ViewEntry.
504      * Returns <code>null</code> if the <code>viewEntry</code> parameter is <code>null</code>.
505      *
506      * @param parent the parent object
507      * @param viewEntry to Notes ViewEntry
508      * @return Proxy for a ViewEntry
509      */
510     ViewEntryProxy getDViewEntry(final DBase parent, final ViewEntry viewEntry) {
511         if (viewEntry == null) {
512             return null;
513         }
514         final ViewEntryProxy entry = ViewEntryProxy.getInstance(getFactory(), parent, viewEntry, getMonitor());
515         entry.setMonitor(getMonitor());
516         return entry;
517     }
518 
519     /***
520      * {@inheritDoc}
521      * @see de.bea.domingo.DView#getAllCategories()
522      */
523     public Iterator getAllCategories() {
524         return getAllCategories(0);
525     }
526 
527     /***
528      * {@inheritDoc}
529      * @see de.bea.domingo.DView#getAllCategories(int)
530      */
531     public Iterator getAllCategories(final int level) {
532         final ViewNavigator nav;
533         final ViewEntry entry;
534         try {
535             nav = getView().createViewNavMaxLevel(level);
536             entry = nav.getFirst();
537             return new CategoryIterator(nav, entry);
538         } catch (NotesException e) {
539             throw newRuntimeException("Cannot get next item", e);
540         }
541     }
542 
543     /***
544      * {@inheritDoc}
545      * @see de.bea.domingo.DView#getAllCategoriesByKey(java.lang.String)
546      * @deprecated
547      */
548     public Iterator getAllCategoriesByKey(final String key) {
549         return getAllCategoriesByKey(key, 0, false);
550     }
551 
552     /***
553      * {@inheritDoc}
554      * @see de.bea.domingo.DView#getAllCategoriesByKey(java.lang.String, int)
555      * @deprecated
556      */
557     public Iterator getAllCategoriesByKey(final String key, final int level) {
558         return getAllCategoriesByKey(key, level, false);
559     }
560 
561     /***
562      * {@inheritDoc}
563      * @see de.bea.domingo.DView#getAllCategoriesByKey(java.lang.String, boolean)
564      * @deprecated
565      */
566     public Iterator getAllCategoriesByKey(final String key, final boolean exact) {
567         return getAllCategoriesByKey(key, 0, false);
568     }
569 
570     /***
571      * {@inheritDoc}
572      * @see de.bea.domingo.DView#getAllCategoriesByKey(java.lang.String, int, boolean)
573      * @deprecated
574      */
575     public Iterator getAllCategoriesByKey(final String key, final int level, final boolean exact) {
576 //        final ViewNavigator navigator;
577 //        final ViewEntry entry;
578 //        try {
579 //            navigator = getView().createViewNavMaxLevel(level);
580 //            entry = getView().getEntryByKey(key, exact);
581 //            if (!entry.isCategory()) {
582 //                while (entry != null) {
583 //                    entry = getDViewEntry(ViewProxy.this, getView().getParent());
584 //                }
585 //            }
586 //            return new CategoryIterator(navigator, entry, key, exact);
587 //        } catch (NotesException e) {
588 //            throw newRuntimeException("Cannot get next item", e);
589 //        }
590         return null; // TODO getAllCategoriesByKey()
591     }
592 
593     /***
594      * {@inheritDoc}
595      * @see de.bea.domingo.DView#getAllCategoriesByKey(java.util.List)
596      * @deprecated
597      */
598     public Iterator getAllCategoriesByKey(final List key) {
599         return getAllCategoriesByKey(key, 0, false);
600     }
601 
602     /***
603      * {@inheritDoc}
604      * @see de.bea.domingo.DView#getAllCategoriesByKey(java.util.List, int)
605      * @deprecated
606      */
607     public Iterator getAllCategoriesByKey(final List key, final int level) {
608         return getAllCategoriesByKey(key, level, false);
609     }
610 
611     /***
612      * {@inheritDoc}
613      * @see de.bea.domingo.DView#getAllCategoriesByKey(java.util.List, boolean)
614      * @deprecated
615      */
616     public Iterator getAllCategoriesByKey(final List key, final boolean exact) {
617         return getAllCategoriesByKey(key, 0, exact);
618     }
619 
620     /***
621      * {@inheritDoc}
622      * @see de.bea.domingo.DView#getAllCategoriesByKey(java.util.List, int, boolean)
623      * @deprecated
624      */
625     public Iterator getAllCategoriesByKey(final List key, final int level, final boolean exact) {
626         final ViewNavigator navigator;
627         final ViewEntry entry;
628         try {
629             navigator = getView().createViewNavMaxLevel(level);
630             entry = getView().getEntryByKey(key, exact);
631             return new CategoryIterator(navigator, entry, key, exact);
632         } catch (NotesException e) {
633             throw newRuntimeException("Cannot get next item", e);
634         }
635     }
636 
637     /***
638      * {@inheritDoc}
639      * @see de.bea.domingo.DView#fullTextSearch(java.lang.String)
640      */
641     public int fullTextSearch(final String query) {
642         getFactory().preprocessMethod();
643         try {
644             return getView().FTSearch(query);
645         } catch (NotesException e) {
646             throw newRuntimeException("Cannot search documents in view", e);
647         }
648     }
649 
650     /***
651      * {@inheritDoc}
652      * @see de.bea.domingo.DView#fullTextSearch(java.lang.String, int)
653      */
654     public int fullTextSearch(final String query, final int maxdocs) {
655         getFactory().preprocessMethod();
656         try {
657             return getView().FTSearch(query, maxdocs);
658         } catch (NotesException e) {
659             throw newRuntimeException("Cannot search documents in view", e);
660         }
661     }
662 
663     /***
664      * {@inheritDoc}
665      * @see de.bea.domingo.DView#clear()
666      */
667     public void clear() {
668         getFactory().preprocessMethod();
669         try {
670             getView().clear();
671         } catch (NotesException e) {
672             throw newRuntimeException("Cannot clear search in view", e);
673         }
674     }
675 
676     /***
677      * {@inheritDoc}
678      * @see de.bea.domingo.DView#getSelectionFormula()
679      */
680     public String getSelectionFormula() {
681         getFactory().preprocessMethod();
682         try {
683             return getView().getSelectionFormula();
684         } catch (NotesException e) {
685             throw newRuntimeException("Cannot get selection formula", e);
686         }
687     }
688 
689     /***
690      * {@inheritDoc}
691      * @see de.bea.domingo.DView#setSelectionFormula(java.lang.String)
692      */
693     public void setSelectionFormula(final String formula) {
694         getFactory().preprocessMethod();
695         try {
696             getView().setSelectionFormula(formula);
697         } catch (NotesException e) {
698             throw newRuntimeException("Cannot set selection formula", e);
699         }
700     }
701 
702     /***
703      * {@inheritDoc}
704      * @see de.bea.domingo.DView#getColumnNames()
705      */
706     public List getColumnNames() {
707         getFactory().preprocessMethod();
708         try {
709             return getView().getColumnNames();
710         } catch (NotesException e) {
711             throw newRuntimeException("Cannot get column names", e);
712         }
713     }
714 
715     /***
716      * {@inheritDoc}
717      * @see de.bea.domingo.DView#getColumnNames()
718      */
719     public int getColumnCount() {
720         getFactory().preprocessMethod();
721         try {
722             return getView().getColumnCount();
723         } catch (NotesException e) {
724             throw newRuntimeException("Cannot get column names", e);
725         }
726     }
727 
728     /***
729      * {@inheritDoc}
730      * @see de.bea.domingo.DView#getColumnNames()
731      */
732     public DViewColumn getColumn(final int i) {
733         getFactory().preprocessMethod();
734         try {
735             ViewColumn notesViewColumn = getView().getColumn(i);
736             final ViewColumnProxy viewColumn = ViewColumnProxy.getInstance(getFactory(), this, notesViewColumn, getMonitor());
737             return viewColumn;
738         } catch (NotesException e) {
739             throw newRuntimeException("Cannot get column names", e);
740         }
741     }
742 
743     /***
744      * {@inheritDoc}
745      * @see de.bea.domingo.DView#getColumnNames()
746      */
747     public List getColumns() {
748         getFactory().preprocessMethod();
749         try {
750             return getView().getColumns();
751         } catch (NotesException e) {
752             throw newRuntimeException("Cannot get column names", e);
753         }
754     }
755 
756     ////////////////////////////////////////////////
757     //    Iterator classes
758     ////////////////////////////////////////////////
759 
760     /***
761      * Uses a ViewNavigator to iterate over all entries in a view,
762      * starting with a given entry.
763      *
764      * @author <a href="mailto:kriede@users.sourceforge.net">Kurt Riede</a>
765      */
766     public final class ViewNavigatorIterator implements DNotesIterator {
767 
768         /*** serial version ID for serialization. */
769         private static final long serialVersionUID = -5944222847469877866L;
770 
771         /*** Reference to the internal view navigator. */
772         private final ViewNavigator viewNavigator;
773 
774         /*** Reference to current viewEntry. */
775         private DViewEntry viewEntry = null;
776 
777         /***
778          * Constructs an Iterator using a ViewNavigator and a current entry to start from.
779          *
780          * @param theViewNavigator the ViewNavigator
781          * @param currentEntry the current entry
782          */
783         protected ViewNavigatorIterator(final ViewNavigator theViewNavigator, final DViewEntry currentEntry) {
784             if (theViewNavigator == null) {
785                 throw newRuntimeException("View navigator missing");
786             }
787             viewNavigator = theViewNavigator;
788             viewEntry = currentEntry;
789         }
790 
791         /***
792          * {@inheritDoc}
793          * @see de.bea.domingo.DNotesIterator#getSize()
794          */
795         public int getSize() {
796             return viewNavigator.getCount();
797         }
798 
799         /***
800          * {@inheritDoc}
801          * @see java.util.Iterator#hasNext()
802          */
803         public boolean hasNext() {
804             return viewEntry != null;
805         }
806 
807         /***
808          * {@inheritDoc}
809          * @see java.util.Iterator#next()
810          */
811         public Object next() {
812             if (viewEntry == null) {
813                 throw new NoSuchElementException();
814             }
815             getFactory().preprocessMethod();
816             final DViewEntry result = viewEntry;
817             try {
818                 if (!viewNavigator.gotoNext()) {
819                     viewEntry = null;
820                 } else {
821                     viewEntry = getDViewEntry(ViewProxy.this, viewNavigator.getCurrent());
822                 }
823             } catch (NotesException e) {
824                 throw newRuntimeException("Cannot get next item", e);
825             }
826             return result;
827         }
828 
829         /***
830          * Throws an UnsupportedOperationException: The <tt>remove</tt>
831          * operation is not supported by this Iterator.
832          *
833          * @see java.util.Iterator#remove()
834          */
835         public void remove() {
836             throw new UnsupportedOperationException();
837         }
838 
839         /***
840          * The items iterator doesn't have to recycle anything.
841          * All Items created within this Iterator are recycled by the Notes API.
842          *
843          * @see java.lang.Object#finalize()
844          * @throws Throwable the <code>Exception</code> raised by this method
845          */
846         protected void finalize() throws Throwable {
847             if (viewNavigator != null) {
848                 getFactory().recycleLater(viewNavigator);
849             }
850             super.finalize();
851         }
852     }
853 
854     /***
855      * A <code>ViewEntriesIterator</code> allows iteration over a set of
856      * <code>lotus.domino.ViewEntry</code>s in view order.
857      *
858      * #see getAllEntries
859      *
860      * @author <a href="mailto:kriede@users.sourceforge.net">Kurt Riede</a>
861      */
862     public final class ViewEntriesIterator implements DNotesIterator {
863 
864         /*** serial version ID for serialization. */
865         private static final long serialVersionUID = 2954764194323549206L;
866 
867         /*** Reference to the internal view entry collection. */
868         private final ViewEntryCollection viewEntries;
869 
870         /*** Reference to current viewEntry. */
871         private ViewEntryProxy viewEntry = null;
872 
873         /***
874          * Constructs an Iterator by use of a vector of
875          * <code>lotus.domino.Item</code>s.
876          *
877          * @param theViewEntries the ViewEntryCollection
878          */
879         protected ViewEntriesIterator(final ViewEntryCollection theViewEntries) {
880             this.viewEntries = theViewEntries;
881             initialize();
882         }
883 
884         /***
885          * initialization.
886          */
887         private void initialize() {
888             try {
889                 if (viewEntries != null && viewEntries.getCount() > 0) {
890                     final ViewEntry currentEntry = viewEntries.getFirstEntry();
891                     this.viewEntry = getDViewEntry(ViewProxy.this, currentEntry);
892                 }
893             } catch (NotesException e) {
894                 throw newRuntimeException("Cannot initialize iterator", e);
895             }
896         }
897 
898         /***
899          * {@inheritDoc}
900          * @see de.bea.domingo.DNotesIterator#getSize()
901          */
902         public int getSize() {
903             try {
904                 return viewEntries.getCount();
905             } catch (NotesException e) {
906                 throw newRuntimeException("Cannot get size of iterator", e);
907             }
908         }
909 
910         /***
911          * {@inheritDoc}
912          * @see java.util.Iterator#hasNext()
913          */
914         public boolean hasNext() {
915             return viewEntry != null;
916         }
917 
918         /***
919          * {@inheritDoc}
920          * @see java.util.Iterator#next()
921          */
922         public Object next() {
923             if (viewEntry == null) {
924                 throw new NoSuchElementException();
925             }
926             getFactory().preprocessMethod();
927             final Object result = viewEntry;
928             try {
929                 final ViewEntry nextViewEntry = viewEntries.getNextEntry();
930                 viewEntry = getDViewEntry(ViewProxy.this, nextViewEntry);
931             } catch (NotesException e) {
932                 viewEntry = null;
933                 throw newRuntimeException("Cannot get next item", e);
934             }
935             return result;
936         }
937 
938         /***
939          * Throws an UnsupportedOperationException: The <tt>remove</tt>
940          * operation is not supported by this Iterator.
941          *
942          * @see java.util.Iterator#remove()
943          */
944         public void remove() {
945             throw new UnsupportedOperationException();
946         }
947 
948         /***
949          * The items iterator doesn't have to recycle anything.
950          * All Items created within this Iterator are recycled by the Notes API.
951          *
952          * @see java.lang.Object#finalize()
953          * @throws Throwable the <code>Exception</code> raised by this method
954          */
955         protected void finalize() throws Throwable {
956             if (viewEntries != null) {
957                 getFactory().recycleLater(viewEntries);
958             }
959             super.finalize();
960         }
961     }
962 
963     /***
964      * A <code>ViewEntriesIterator</code> allows iteration over a set of
965      * <code>lotus.domino.ViewEntry</code>s in reverse order.
966      *
967      * #see getAllEntries
968      *
969      * @author <a href="mailto:kriede@users.sourceforge.net">Kurt Riede</a>
970      */
971     public final class ViewEntriesReverseIterator implements DNotesIterator {
972 
973         /*** serial version ID for serialization. */
974         private static final long serialVersionUID = 2954764194323549206L;
975 
976         /*** Reference to the internal view entry collection. */
977         private final ViewEntryCollection viewEntries;
978 
979         /*** Reference to current viewEntry. */
980         private ViewEntryProxy viewEntry = null;
981 
982         /***
983          * Constructs an Iterator by use of a vector of
984          * <code>lotus.domino.Item</code>s.
985          *
986          * @param theViewEntries the ViewEntryCollection
987          */
988         protected ViewEntriesReverseIterator(final ViewEntryCollection theViewEntries) {
989             this.viewEntries = theViewEntries;
990             initialize();
991         }
992 
993         /***
994          * initialization.
995          */
996         private void initialize() {
997             try {
998                 if (viewEntries != null && viewEntries.getCount() > 0) {
999                     final ViewEntry currentEntry = viewEntries.getLastEntry();
1000                     this.viewEntry = getDViewEntry(ViewProxy.this, currentEntry);
1001                 }
1002             } catch (NotesException e) {
1003                 throw newRuntimeException("Cannot initialize iterator", e);
1004             }
1005         }
1006 
1007         /***
1008          * {@inheritDoc}
1009          * @see de.bea.domingo.DNotesIterator#getSize()
1010          */
1011         public int getSize() {
1012             try {
1013                 return viewEntries.getCount();
1014             } catch (NotesException e) {
1015                 throw newRuntimeException("Cannot get size of iterator", e);
1016             }
1017         }
1018 
1019         /***
1020          * {@inheritDoc}
1021          * @see java.util.Iterator#hasNext()
1022          */
1023         public boolean hasNext() {
1024             return viewEntry != null;
1025         }
1026 
1027         /***
1028          * {@inheritDoc}
1029          * @see java.util.Iterator#next()
1030          */
1031         public Object next() {
1032             if (viewEntry == null) {
1033                 throw new NoSuchElementException();
1034             }
1035             getFactory().preprocessMethod();
1036             final Object result = viewEntry;
1037             try {
1038                 final ViewEntry nextViewEntry = viewEntries.getPrevEntry();
1039                 viewEntry = null;
1040                 viewEntry = getDViewEntry(ViewProxy.this, nextViewEntry);
1041             } catch (NotesException e) {
1042                 throw newRuntimeException("Cannot get next item: " + e.getMessage());
1043             }
1044             return result;
1045         }
1046 
1047         /***
1048          * Throws an UnsupportedOperationException: The <tt>remove</tt>
1049          * operation is not supported by this Iterator.
1050          *
1051          * @see java.util.Iterator#remove()
1052          */
1053         public void remove() {
1054             throw new UnsupportedOperationException();
1055         }
1056 
1057         /***
1058          * The items iterator doesn't have to recycle anything.
1059          * All Items created within this Iterator are recycled by the Notes API.
1060          *
1061          * @see java.lang.Object#finalize()
1062          * @throws Throwable the <code>Exception</code> raised by this method
1063          */
1064         protected void finalize() throws Throwable {
1065             if (viewEntries != null) {
1066                 getFactory().recycleLater(viewEntries);
1067             }
1068             super.finalize();
1069         }
1070     }
1071 
1072     /***
1073      * A <code>CategoriesIterator</code> allows iteration over a set of
1074      * <code>lotus.domino.ViewEntry</code>s that are categories.
1075      *
1076      * @see #getAllCategories()
1077      * @see #getAllCategories(int)
1078      * @see #getAllCategoriesByKey(java.lang.String, int, boolean)
1079      * @see #getAllCategoriesByKey(java.util.List, int, boolean)
1080      *
1081      * @author <a href="mailto:kriede@users.sourceforge.net">Kurt Riede</a>
1082      */
1083     public final class CategoryIterator implements Iterator {
1084 
1085         /*** Reference to the internal view navigator. */
1086         private final ViewNavigator fViewNavigator;
1087 
1088         /*** The optional key. */
1089         private final Object fKey;
1090 
1091         /*** If the key should match partial or exact. */
1092         private final boolean fExact;
1093 
1094         /*** Reference to current viewEntry. */
1095         private DViewEntry fNextEntry = null;
1096 
1097         /***
1098          * Constructs an CategoryIterator.
1099          *
1100          * @param theViewNavigator the ViewNavigator
1101          * @param firstEntry the first entry or null of no entry is available
1102          */
1103         protected CategoryIterator(final ViewNavigator theViewNavigator, final ViewEntry firstEntry) {
1104             fViewNavigator = theViewNavigator;
1105             fKey = null;
1106             fExact = false;
1107             initialize(firstEntry);
1108         }
1109 
1110         /***
1111          * Constructor.
1112          *
1113          * @param theViewNavigator the ViewNavigator
1114          * @param firstEntry the first matching entry or null of no entry matching entry is available
1115          * @param theKey the key, either a String a List
1116          * @param isExact use true if you want an exact match or false for a partial
1117          */
1118         public CategoryIterator(final ViewNavigator theViewNavigator, final ViewEntry firstEntry,
1119                                 final Object theKey, final boolean isExact) {
1120             fViewNavigator = theViewNavigator;
1121             fKey = theKey;
1122             fExact = isExact;
1123             initialize(firstEntry);
1124         }
1125 
1126         /***
1127          * initialization.
1128          *
1129          * @param firstEntry the first matching entry or null of no entry matching entry is available
1130          */
1131         private void initialize(final ViewEntry firstEntry) {
1132             getFactory().preprocessMethod();
1133             if (firstEntry != null) {
1134                 fNextEntry = getDViewEntry(ViewProxy.this, firstEntry);
1135                 try {
1136                     if (!fViewNavigator.gotoEntry(firstEntry)) {
1137                         fNextEntry = null;
1138                     }
1139                 } catch (NotesException e) {
1140                     throw new DNotesRuntimeException("Entry not found in view");
1141                 }
1142             }
1143         }
1144 
1145         /***
1146          * Indicates whether this iterator has a next element or not.
1147          *
1148          * @return boolean true if there is a next
1149          * @see java.util.Iterator#hasNext()
1150          */
1151         public boolean hasNext() {
1152             return fNextEntry != null;
1153         }
1154 
1155         /***
1156          * Returns the next element of this iterator
1157          * or <code>null</code> if <code>hasNext()==false</code>.
1158          *
1159          * @return a <code>DBaseItem</code>
1160          * @see java.util.Iterator#next()
1161          */
1162         public Object next() {
1163             if (fNextEntry == null) {
1164                 throw new NoSuchElementException();
1165             }
1166             getFactory().preprocessMethod();
1167             final DViewEntry next = fNextEntry;
1168             fNextEntry = getNextEntry();
1169             return next;
1170         }
1171 
1172         /***
1173          * Throws an UnsupportedOperationException: The <tt>remove</tt>
1174          * operation is not supported by this Iterator.
1175          *
1176          * @see java.util.Iterator#remove()
1177          */
1178         public void remove() {
1179             throw new UnsupportedOperationException();
1180         }
1181 
1182         /***
1183          * Returns the next entry that matches the key
1184          * or <code>null</code> if no more entries available.
1185          *
1186          * @return next item or <code>null</code>
1187          */
1188         private DViewEntry getNextEntry() {
1189             DViewEntry next = fNextEntry;
1190             while (next != null) {
1191                 try {
1192                     next = getDViewEntry(ViewProxy.this, fViewNavigator.getNext());
1193                 } catch (NotesException e) {
1194                     throw newRuntimeException("Cannot get next entry", e);
1195                 }
1196                 if (fKey == null) {
1197                     return next;
1198                 }
1199                 if (match(next)) {
1200                     return next;
1201                 }
1202             }
1203             return null;
1204         }
1205 
1206         /***
1207          * Checks if the column values of a view entry match a given key.
1208          * @param entry the entry to check
1209          * @return if matching or not
1210          */
1211         private boolean match(final DViewEntry entry) {
1212             final List valueList = entry.getColumnValues();
1213             if (valueList.size() == 0) {
1214                 return false;
1215             }
1216             if (fKey instanceof List) {
1217                 final List keyList = (List) fKey;
1218                 if (valueList.size() < keyList.size()) {
1219                     return false;
1220                 }
1221                 for (int i = 0; i < keyList.size() - 1; i++) {
1222                     if (keyList.get(i) != valueList.get(i)) {
1223                         return false;
1224                     }
1225                 }
1226                 final String lastValue = (String) valueList.get(keyList.size());
1227                 final String lastKey = (String) keyList.get(keyList.size());
1228                 if (fExact) {
1229                     return lastValue.startsWith(lastKey);
1230                 } else {
1231                     return lastValue.equals(lastKey);
1232                 }
1233             } else {
1234                 final String value0 = (String) valueList.get(0);
1235                 if (value0 == null) {
1236                     return false;
1237                 }
1238                 return match(value0, fKey);
1239             }
1240         }
1241 
1242         /***
1243          * Compares a single value with a single key.
1244          * @param value the value
1245          * @param key the key
1246          * @return <tt>true</tt> if the value matches
1247          */
1248         private boolean match(final Object value, final Object key) {
1249             if (fExact) {
1250                 return value.equals(key);
1251             }
1252             if (value instanceof String) {
1253                 return partialMatch((String) value, (String) key);
1254             } else if (value instanceof Calendar) {
1255                 return partialMatch((Calendar) value, (Calendar) key);
1256             } else if (value instanceof Double) {
1257                 return partialMatch((Double) value, (Double) key);
1258             }
1259             return false;
1260         }
1261 
1262         /***
1263          * Partially matches a String values.
1264          * @param value the value
1265          * @param theKey the key
1266          * @return <tt>true</tt> if the value partially matches
1267          */
1268         private boolean partialMatch(final String value, final String theKey) {
1269             return value.startsWith(theKey);
1270         }
1271 
1272         /***
1273          * Partially matches a calendar value.
1274          * @param value the value
1275          * @param theKey the key
1276          * @return <tt>true</tt> if the value partially matches
1277          */
1278         private boolean partialMatch(final Calendar value, final Calendar theKey) {
1279             return value.after(theKey);
1280         }
1281 
1282         /***
1283          * Partially matches a double value.
1284          * @param value the value
1285          * @param theKey the key
1286          * @return <tt>true</tt> if the value partially matches
1287          */
1288         private boolean partialMatch(final Double value, final Double theKey) {
1289             return value.doubleValue() > theKey.doubleValue();
1290         }
1291 
1292         /***
1293          * The items iterator doesn't have to recycle anything.
1294          * All Items created within this Iterator are recycled by the Notes API.
1295          *
1296          * @see java.lang.Object#finalize()
1297          * @throws Throwable the <code>Exception</code> raised by this method
1298          */
1299         protected void finalize() throws Throwable {
1300             if (fViewNavigator != null) {
1301                 getFactory().recycleLater(fViewNavigator);
1302             }
1303             super.finalize();
1304         }
1305     }
1306 
1307     /***
1308      * An empty iterator.
1309      */
1310     private static class EmptyIterator implements Iterator {
1311 
1312         /*** @see java.util.Iterator#hasNext() */
1313         public boolean hasNext() {
1314             return false;
1315         }
1316 
1317         /*** @see java.util.Iterator#next() */
1318         public Object next() {
1319             throw new NoSuchElementException("EmtyIterator");
1320         }
1321 
1322         /*** @see java.util.Iterator#remove() */
1323         public void remove() {
1324             throw new IllegalStateException("EmtyIterator");
1325         }
1326     }
1327 }