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.lang.ref.WeakReference;
26  import java.util.ArrayList;
27  import java.util.Calendar;
28  import java.util.Collections;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Vector;
32  
33  import lotus.domino.Agent;
34  import lotus.domino.Database;
35  import lotus.domino.DateTime;
36  import lotus.domino.Document;
37  import lotus.domino.DocumentCollection;
38  import lotus.domino.Form;
39  import lotus.domino.NotesException;
40  import lotus.domino.View;
41  import de.bea.domingo.DAgent;
42  import de.bea.domingo.DDatabase;
43  import de.bea.domingo.DDocument;
44  import de.bea.domingo.DForm;
45  import de.bea.domingo.DNotesException;
46  import de.bea.domingo.DNotesMonitor;
47  import de.bea.domingo.DProfileDocument;
48  import de.bea.domingo.DSession;
49  import de.bea.domingo.DView;
50  import de.bea.domingo.cache.Cache;
51  import de.bea.domingo.cache.SimpleCache;
52  
53  /***
54   * Represents a Notes database.
55   *
56   * @author <a href=mailto:kriede@users.sourceforge.net>Kurt Riede</a>
57   */
58  public final class DatabaseProxy extends BaseProxy implements DDatabase {
59  
60      /*** serial version ID for serialization. */
61      private static final long serialVersionUID = 3834028048088380976L;
62  
63      /***
64       * Cache of all views of a database.
65       *
66       * <p>viewName -> WeakReference(View)</p>
67       */
68      private final Cache viewCache;
69  
70      /*** Flag, if the Notes database was found and is open. */
71      private boolean databaseNotFound;
72  
73      /*** The file/path of the database for fast access. */
74      private String filePath;
75  
76      /*** The server of the database for fast access. */
77      private String server;
78  
79      /***
80       * Private Constructor for this class.
81       *
82       * @param theFactory the controlling factory
83       * @param session the session that produced the database
84       * @param database Notes database object
85       * @param monitor the monitor that handles logging
86       * @param forceOpen whether the database should be forced to be open or not
87       * @see lotus.domino.Database
88       */
89      private DatabaseProxy(final NotesProxyFactory theFactory, final DSession session,
90                            final Database database, final DNotesMonitor monitor, final boolean forceOpen) {
91          super(theFactory, session, database, monitor);
92          this.viewCache = new SimpleCache();
93          getFactory().preprocessMethod();
94          server = getServerIntern();
95          filePath = getFilePathIntern();
96          try {
97              if (forceOpen) {
98                  if (!database.isOpen()) {
99                      try {
100                         database.open();
101                     } catch (NotesException e) {
102                         monitor.warn(RESOURCES.getString("database.tried.open.database"), e);
103                     }
104                 }
105                 if (!database.isOpen()) {
106                     getMonitor().error(RESOURCES.getString("database.database.not.open.1", toString()));
107                     databaseNotFound = true;
108                 }
109             }
110         } catch (NotesException e) {
111             databaseNotFound = true;
112             monitor.error(RESOURCES.getString("database.cannot.get.database.1", toString()), e);
113         }
114     }
115 
116     /***
117      * Factory method for instances of this class.
118      *
119      * @param theFactory the controlling factory
120      * @param session the session that produced the database
121      * @param theDatabase Notes database object
122      * @param monitor the monitor that handles logging
123      * @param forceOpen whether the database should be forced to be open or not
124      *
125      * @return Returns a DDatabase instance of type DatabaseProxy
126      */
127     static DDatabase getInstance(final NotesProxyFactory theFactory, final DSession session,
128                                  final Database theDatabase, final DNotesMonitor monitor, final boolean forceOpen) {
129         if (theDatabase == null) {
130             return null;
131         }
132         DatabaseProxy databaseProxy = (DatabaseProxy) theFactory.getBaseCache().get(theDatabase);
133         if (databaseProxy == null) {
134             databaseProxy = new DatabaseProxy(theFactory, session, theDatabase, monitor, forceOpen);
135             if (databaseProxy.databaseNotFound) {
136                 return null;
137             }
138             theFactory.getBaseCache().put(theDatabase, databaseProxy);
139         }
140         try {
141             final String key1 = getDatabaseKey(databaseProxy.getServer(), databaseProxy.getFilePath());
142             final String key2 = getDatabaseKey(theDatabase.getServer(), theDatabase.getFilePath());
143             if (!key1.equals(key2)) {
144                 monitor.warn(RESOURCES.getString("database.invalid.database.proxy.2", key2, key1));
145                 return new DatabaseProxy(theFactory, session, theDatabase, monitor, forceOpen);
146             }
147         } catch (NotesException e) {
148             monitor.fatalError(RESOURCES.getString("database.cannot.get.database.proxy.instance"), e);
149         }
150         return databaseProxy;
151     }
152 
153     /***
154      * Returns the database key for a given server and filename.
155      * To ensure platform independence, path separators get unified to <tt>'/'</tt>.
156      *
157      * @param serverName name of a notes server
158      * @param databaseName file path of database
159      * @return database key that can be used for caching database objects in a map.
160      */
161     static String getDatabaseKey(final String serverName, final String databaseName) {
162         if (databaseName == null) {
163             return serverName;
164         }
165         String server = ("".equals(serverName) ? "local" : serverName);
166         return server + "!!" + databaseName.replace('//', '/');
167     }
168 
169     /***
170      * {@inheritDoc}
171      * @see de.bea.domingo.DDatabase#getSession()
172      */
173     public DSession getSession() {
174         return (DSession) getParent();
175     }
176 
177     /***
178      * Returns the associated notes database object.
179      *
180      * @return notes database object
181      */
182     private Database getDatabase() {
183         return (Database) getNotesObject();
184     }
185 
186     /***
187      * {@inheritDoc}
188      * @see de.bea.domingo.DDatabase#replicate(java.lang.String)
189      */
190     public boolean replicate(final String targetServer) {
191         getFactory().preprocessMethod();
192         try {
193             return getDatabase().replicate(targetServer);
194         } catch (NotesException e) {
195             throw newRuntimeException(RESOURCES.getString("database.cannot.replicate.database"), e);
196         }
197     }
198 
199     /***
200      * {@inheritDoc}
201      * @see de.bea.domingo.DDatabase#remove()
202      */
203     public boolean remove() {
204         getFactory().preprocessMethod();
205         // todo shrink thread pool size to one before removing database, then resize pool again
206         // (Otherwise the database might be locked by another thread and thus removal fails)
207         try {
208             getDatabase().remove();
209             return true;
210         } catch (NotesException e) {
211             throw newRuntimeException(RESOURCES.getString("database.cannot.remove.database.1", getFileName()), e);
212         }
213     }
214 
215     /***
216      * {@inheritDoc}
217      * @see de.bea.domingo.DDatabase#getDocumentByUNID(String)
218      * todo check if it is possible and helpfull to reuse existing instances of a document
219      */
220     public DDocument getDocumentByUNID(final String docId) {
221         getFactory().preprocessMethod();
222         try {
223             final Document doc = getDatabase().getDocumentByUNID(docId);
224             if (doc.isProfile()) {
225                 final String message = RESOURCES.getString("database.cannot.query.profile");
226                 getMonitor().error(message);
227                 return null;
228             }
229             return (DDocument) BaseDocumentProxy.getInstance(getFactory(), this, doc, getMonitor());
230         } catch (NotesException e) {
231             throw newRuntimeException(RESOURCES.getString("database.cannot.get.unid.1", docId), e);
232         }
233     }
234 
235     /***
236      * {@inheritDoc}
237      * @see de.bea.domingo.DDatabase#getProfileDocument(String, String)
238      */
239     public DProfileDocument getProfileDocument(final String profileName, final String profileKey) {
240         getFactory().preprocessMethod();
241         try {
242             final Document document = getDatabase().getProfileDocument(profileName, profileKey);
243             return (DProfileDocument) BaseDocumentProxy.getInstance(getFactory(), this, document, getMonitor());
244         } catch (NotesException e) {
245             String key = profileName + "_" + profileKey;
246             throw newRuntimeException(RESOURCES.getString("database.cannot.get.profile.1", key), e);
247         }
248     }
249 
250     /***
251      * {@inheritDoc}
252      * @see de.bea.domingo.DDatabase#getView(String)
253      */
254     public DView getView(final String viewName) {
255         getFactory().preprocessMethod();
256         final WeakReference weakReference = (WeakReference) viewCache.get(viewName);
257         final DView cachedView = (weakReference == null) ? null : (DView) weakReference.get();
258         if (cachedView != null) {
259             return cachedView;
260         }
261         try {
262             final View notesView = getDatabase().getView(viewName);
263             final DView view = ViewProxy.getInstance(getFactory(), this, notesView, getMonitor());
264             viewCache.put(viewName, new WeakReference(view));
265             return view;
266         } catch (NotesException e) {
267             throw newRuntimeException(RESOURCES.getString("database.cannot.get.view.1", viewName), e);
268         }
269     }
270 
271     /***
272      * {@inheritDoc}
273      * @see de.bea.domingo.DDatabase#createDocument()
274      */
275     public DDocument createDocument() {
276         getFactory().preprocessMethod();
277         try {
278             final Document doc = getDatabase().createDocument();
279             return (DDocument) BaseDocumentProxy.getInstance(getFactory(), this, doc, getMonitor());
280         } catch (NotesException e) {
281             throw newRuntimeException(RESOURCES.getString("database.cannot.create.document"), e);
282         }
283     }
284 
285     /***
286      * {@inheritDoc}
287      * @see de.bea.domingo.DDatabase#getDocumentByID(java.lang.String)
288      * todo check if it is possible and helpfull to reuse existing instances of a document
289      */
290     public DDocument getDocumentByID(final String noteId) {
291         getFactory().preprocessMethod();
292         try {
293             final Document doc = getDatabase().getDocumentByID(noteId);
294             return (DDocument) BaseDocumentProxy.getInstance(getFactory(), this, doc, getMonitor());
295         } catch (NotesException e) {
296             throw newRuntimeException(RESOURCES.getString("database.cannot.get.documentbyid.1", noteId), e);
297         }
298     }
299 
300     /***
301      * {@inheritDoc}
302      * @see de.bea.domingo.DDatabase#getFilePath()
303      */
304     public String getFilePath() {
305         return filePath;
306     }
307 
308     /***
309      * @see de.bea.domingo.DDatabase#getFilePath()
310      */
311     private String getFilePathIntern() {
312         getFactory().preprocessMethod();
313         try {
314             return getDatabase().getFilePath();
315         } catch (NotesException e) {
316             throw newRuntimeException(RESOURCES.getString("database.cannot.get.filepath"), e);
317         }
318     }
319 
320     /***
321      * {@inheritDoc}
322      * @see de.bea.domingo.DDatabase#getFileName()
323      */
324     public String getFileName() {
325         getFactory().preprocessMethod();
326         try {
327             return getDatabase().getFileName();
328         } catch (NotesException e) {
329             throw newRuntimeException(RESOURCES.getString("database.cannot.get.filename"), e);
330         }
331     }
332 
333     /***
334      * {@inheritDoc}
335      * @see java.lang.Object#toString()
336      */
337     public String toString() {
338         return server + "!!" + filePath;
339     }
340 
341     /***
342      * {@inheritDoc}
343      * @see de.bea.domingo.DDatabase#getAllDocuments()
344      */
345     public Iterator getAllDocuments() {
346         getFactory().preprocessMethod();
347         try {
348             return new DocumentCollectionIterator(getFactory(), this, getDatabase().getAllDocuments(), getMonitor());
349         } catch (NotesException e) {
350             throw newRuntimeException(RESOURCES.getString("database.cannot.get.alldocuments"), e);
351         }
352     }
353 
354     /***
355      * {@inheritDoc}
356      * @see de.bea.domingo.DDatabase#createDatabaseFromTemplate(java.lang.String, java.lang.String, boolean)
357      */
358     public DDatabase createDatabaseFromTemplate(final String serverName, final String dbName, final boolean inherit)
359         throws DNotesException {
360         getFactory().preprocessMethod();
361         try {
362             final Database newDatabase = getDatabase().createFromTemplate(serverName, dbName, inherit);
363             final DSession session = (DSession) getParent();
364             return getInstance(getFactory(), session, newDatabase, getMonitor(), true);
365         } catch (NotesException e) {
366             String templ = getServer() + "!!" + getFileName();
367             String db = serverName + "!!" + dbName;
368             String msg = RESOURCES.getString("database.cannot.create.database.from.template.2", db, templ);
369             throw newException(msg, e);
370         }
371     }
372 
373     /***
374      * {@inheritDoc}
375      * @see de.bea.domingo.DDatabase#createReplica(java.lang.String, java.lang.String)
376      */
377     public DDatabase createReplica(final String serverName, final String dbName) throws DNotesException {
378         getFactory().preprocessMethod();
379         try {
380             final Database newReplica = getDatabase().createReplica(serverName, dbName);
381             final DSession session = (DSession) getParent();
382             return getInstance(getFactory(), session, newReplica, getMonitor(), true);
383         } catch (NotesException e) {
384             throw newRuntimeException(e.text, e);
385         }
386     }
387 
388     /***
389      * {@inheritDoc}
390      * @see de.bea.domingo.DDatabase#getCurrentAccessLevel()
391      */
392     public int getCurrentAccessLevel() {
393         getFactory().preprocessMethod();
394         try {
395             return getDatabase().getCurrentAccessLevel();
396         } catch (NotesException e) {
397             throw newRuntimeException(RESOURCES.getString("database.cannot.get.accesslevel"), e);
398         }
399     }
400 
401     /***
402      * {@inheritDoc}
403      * @see de.bea.domingo.DDatabase#getServer()
404      */
405     public String getServer() {
406         return server;
407     }
408 
409     /***
410      * @see de.bea.domingo.DDatabase#getServer()
411      */
412     private String getServerIntern() {
413         getFactory().preprocessMethod();
414         try {
415             String s = getDatabase().getServer();
416             if (s == null || "".equals(s)) {
417                 s = "local";
418             }
419             return s;
420         } catch (NotesException e) {
421             throw newRuntimeException(RESOURCES.getString("database.cannot.get.server"), e);
422         }
423     }
424 
425     /***
426      * {@inheritDoc}
427      * @see de.bea.domingo.DDatabase#getAgent(java.lang.String)
428      */
429     public DAgent getAgent(final String name) {
430         getFactory().preprocessMethod();
431         try {
432             final Agent agent = getDatabase().getAgent(name);
433             return AgentProxy.getInstance(getFactory(), this, agent, getMonitor());
434 
435         } catch (NotesException e) {
436             throw newRuntimeException(RESOURCES.getString("database.cannot.get.agent.1", name), e);
437         }
438     }
439 
440     /***
441      * {@inheritDoc}
442      * @see de.bea.domingo.DDatabase#isPublicAddressBook()
443      */
444     public boolean isPublicAddressBook() {
445         getFactory().preprocessMethod();
446         try {
447             return getDatabase().isPublicAddressBook();
448         } catch (NotesException e) {
449             throw newRuntimeException(e);
450         }
451     }
452 
453     /***
454      * {@inheritDoc}
455      * @see de.bea.domingo.DDatabase#isPrivateAddressBook()
456      */
457     public boolean isPrivateAddressBook() {
458         getFactory().preprocessMethod();
459         try {
460             return getDatabase().isPrivateAddressBook();
461         } catch (NotesException e) {
462             throw newRuntimeException(e);
463         }
464     }
465 
466     /***
467      * {@inheritDoc}
468      * @see de.bea.domingo.DDatabase#isOpen()
469      */
470     public boolean isOpen() {
471         getFactory().preprocessMethod();
472         try {
473             return getDatabase().isOpen();
474         } catch (NotesException e) {
475             throw newRuntimeException(e);
476         }
477     }
478 
479     /***
480      * {@inheritDoc}
481      * @see de.bea.domingo.DDatabase#open()
482      */
483     public boolean open() {
484         getFactory().preprocessMethod();
485         try {
486             return getDatabase().open();
487         } catch (NotesException e) {
488             throw newRuntimeException(e);
489         }
490     }
491 
492     /***
493      * {@inheritDoc}
494      * @see de.bea.domingo.DDatabase#getCategories()
495      */
496     public String getCategories() {
497         getFactory().preprocessMethod();
498         try {
499             return getDatabase().getCategories();
500         } catch (NotesException e) {
501             throw newRuntimeException(e);
502         }
503     }
504 
505     /***
506      * {@inheritDoc}
507      * @see de.bea.domingo.DDatabase#isDelayUpdates()
508      */
509     public boolean isDelayUpdates() {
510         getFactory().preprocessMethod();
511         try {
512             return getDatabase().isDelayUpdates();
513         } catch (NotesException e) {
514             throw newRuntimeException(e);
515         }
516     }
517 
518     /***
519      * {@inheritDoc}
520      * @see de.bea.domingo.DDatabase#getReplicaID()
521      */
522     public String getReplicaID() {
523         getFactory().preprocessMethod();
524         try {
525             return getDatabase().getReplicaID();
526         } catch (NotesException e) {
527             throw newRuntimeException(e);
528         }
529     }
530 
531     /***
532      * {@inheritDoc}
533      * @see de.bea.domingo.DDatabase#getSizeQuota()
534      */
535     public int getSizeQuota() {
536         getFactory().preprocessMethod();
537         try {
538             return getDatabase().getSizeQuota();
539         } catch (NotesException e) {
540             throw newRuntimeException(e);
541         }
542     }
543 
544     /***
545      * {@inheritDoc}
546      * @see de.bea.domingo.DDatabase#getTemplateName()
547      */
548     public String getTemplateName() {
549         getFactory().preprocessMethod();
550         try {
551             return getDatabase().getTemplateName();
552         } catch (NotesException e) {
553             throw newRuntimeException(e);
554         }
555     }
556 
557     /***
558      * {@inheritDoc}
559      * @see de.bea.domingo.DDatabase#getTitle()
560      */
561     public String getTitle() {
562         getFactory().preprocessMethod();
563         try {
564             return getDatabase().getTitle();
565         } catch (NotesException e) {
566             throw newRuntimeException(e);
567         }
568     }
569 
570     /***
571      * {@inheritDoc}
572      * @see de.bea.domingo.DDatabase#setTitle(java.lang.String)
573      */
574     public void setTitle(final String title) {
575         getFactory().preprocessMethod();
576         try {
577             getDatabase().setTitle(title);
578         } catch (NotesException e) {
579             throw newRuntimeException("Cannot invoke setTitle", e);
580         }
581     }
582 
583     /***
584      * {@inheritDoc}
585      *
586      * @see de.bea.domingo.DDatabase#getDesignTemplateName()
587      */
588     public String getDesignTemplateName() {
589         getFactory().preprocessMethod();
590         try {
591             return getDatabase().getDesignTemplateName();
592         } catch (NotesException e) {
593             throw newRuntimeException(e);
594         }
595     }
596 
597     /***
598      * {@inheritDoc}
599      * @see de.bea.domingo.DDatabase#search(String, Calendar, int)
600      */
601     public Iterator search(final String formula) {
602         getFactory().preprocessMethod();
603         try {
604             return new DocumentCollectionIterator(getFactory(), this, getDatabase().search(formula), getMonitor());
605         } catch (NotesException e) {
606             throw newRuntimeException(RESOURCES.getString("database.cannot.search.documents.1", formula), e);
607         }
608     }
609 
610     /***
611      * {@inheritDoc}
612      * @see de.bea.domingo.DDatabase#search(java.lang.String, java.util.Calendar, int)
613      */
614     public Iterator search(final String formula, final Calendar dt, final int max) {
615         getFactory().preprocessMethod();
616         try {
617             final DateTime dateTime = (dt == null) ? null : createDateTime(dt);
618             final DocumentCollection collection = getDatabase().search(formula, dateTime, max);
619             final Iterator iterator = new DocumentCollectionIterator(getFactory(), this, collection, getMonitor());
620             getFactory().recycle(dateTime);
621             return iterator;
622         } catch (NotesException e) {
623             throw newRuntimeException(RESOURCES.getString("database.cannot.search.documents.1", formula), e);
624         }
625     }
626 
627     /***
628      * {@inheritDoc}
629      * @see de.bea.domingo.DDatabase#search(java.lang.String, java.util.Calendar)
630      */
631     public Iterator search(final String formula, final Calendar dt) {
632         getFactory().preprocessMethod();
633         try {
634             final DateTime dateTime = createDateTime(dt);
635             final DocumentCollection collection = getDatabase().search(formula, dateTime);
636             final Iterator iterator = new DocumentCollectionIterator(getFactory(), this, collection, getMonitor());
637             getFactory().recycle(dateTime);
638             return iterator;
639         } catch (NotesException e) {
640             throw newRuntimeException(RESOURCES.getString("database.cannot.search.documents.1", formula), e);
641         }
642     }
643 
644     /***
645      * {@inheritDoc}
646      * @see de.bea.domingo.DDatabase#isFTIndexed()
647      */
648     public boolean isFTIndexed() {
649         getFactory().preprocessMethod();
650         try {
651             return getDatabase().isFTIndexed();
652         } catch (NotesException e) {
653             throw newRuntimeException(e);
654         }
655     }
656 
657     /***
658      * {@inheritDoc}
659      * @see de.bea.domingo.DDatabase#updateFTIndex(boolean)
660      */
661     public void updateFTIndex(final boolean create) {
662         getFactory().preprocessMethod();
663         try {
664             getDatabase().updateFTIndex(create);
665         } catch (NotesException e) {
666             throw newRuntimeException(e);
667         }
668     }
669 
670     /***
671      * {@inheritDoc}
672      * @see de.bea.domingo.DDatabase#fullTextSearchRange(java.lang.String, int, int, int, int)
673      */
674     public Iterator fullTextSearchRange(final String query, final int max, final int sortopt, final int otheropt,
675             final int start) {
676         getFactory().preprocessMethod();
677         try {
678             DocumentCollection collection = getDatabase().FTSearchRange(query, max, sortopt, otheropt, start);
679             return new DocumentCollectionIterator(getFactory(), this, collection, getMonitor());
680         } catch (NotesException e) {
681             throw newRuntimeException(RESOURCES.getString("database.cannot.ftsearch.documents.1", query), e);
682         }
683     }
684 
685     /***
686      * {@inheritDoc}
687      * @see de.bea.domingo.DDatabase#fullTextSearch(java.lang.String)
688      */
689     public Iterator fullTextSearch(final String query) {
690         getFactory().preprocessMethod();
691         try {
692             DocumentCollection collection = getDatabase().FTSearch(query);
693             return new DocumentCollectionIterator(getFactory(), this, collection, getMonitor());
694         } catch (NotesException e) {
695             throw newRuntimeException(RESOURCES.getString("database.cannot.ftsearch.documents.1", query), e);
696         }
697     }
698 
699     /***
700      * {@inheritDoc}
701      * @see de.bea.domingo.DDatabase#fullTextSearch(java.lang.String, int)
702      */
703     public Iterator fullTextSearch(final String query, final int max) {
704         getFactory().preprocessMethod();
705         try {
706             DocumentCollection collection = getDatabase().FTSearch(query, max);
707             return new DocumentCollectionIterator(getFactory(), this, collection, getMonitor());
708         } catch (NotesException e) {
709             throw newRuntimeException(RESOURCES.getString("database.cannot.ftsearch.documents.1", query), e);
710         }
711     }
712 
713     /***
714      * {@inheritDoc}
715      * @see de.bea.domingo.DDatabase#fullTextSearch(java.lang.String, int, int, int)
716      */
717     public Iterator fullTextSearch(final String query, final int max, final int sortopt, final int otheropt) {
718         getFactory().preprocessMethod();
719         try {
720             DocumentCollection collection = getDatabase().FTSearch(query, max, sortopt, otheropt);
721             return new DocumentCollectionIterator(getFactory(), this, collection, getMonitor());
722         } catch (NotesException e) {
723             throw newRuntimeException(RESOURCES.getString("database.cannot.ftsearch.documents.1", query), e);
724         }
725     }
726 
727     /***
728      * {@inheritDoc}
729      * @see de.bea.domingo.DDatabase#isDocumentLockingEnabled()
730      */
731     public boolean isDocumentLockingEnabled() {
732         getFactory().preprocessMethod();
733         try {
734             return getDatabase().isDocumentLockingEnabled();
735         } catch (NotesException e) {
736             throw newRuntimeException(e);
737         }
738     }
739 
740     /***
741      * {@inheritDoc}
742      * @see de.bea.domingo.DDatabase#setDocumentLockingEnabled(boolean)
743      */
744     public void setDocumentLockingEnabled(final boolean flag) {
745         getFactory().preprocessMethod();
746         try {
747             getDatabase().setDocumentLockingEnabled(flag);
748         } catch (NotesException e) {
749             throw newRuntimeException(e);
750         }
751     }
752 
753     /***
754      * {@inheritDoc}
755      * @see de.bea.domingo.DDatabase#getFolderReferencesEnabled()
756      */
757     public boolean getFolderReferencesEnabled() {
758         getFactory().preprocessMethod();
759         try {
760             return getDatabase().getFolderReferencesEnabled();
761         } catch (NotesException e) {
762             throw newRuntimeException(e);
763         }
764     }
765 
766     /***
767      * {@inheritDoc}
768      * @see de.bea.domingo.DDatabase#setFolderReferencesEnabled(boolean)
769      */
770     public void setFolderReferencesEnabled(final boolean flag) {
771         getFactory().preprocessMethod();
772         try {
773             getDatabase().setFolderReferencesEnabled(flag);
774         } catch (NotesException e) {
775             throw newRuntimeException(e);
776         }
777     }
778 
779     /***
780      * {@inheritDoc}
781      * @see de.bea.domingo.DDatabase#getViews()
782      */
783     public List getViews() {
784         getFactory().preprocessMethod();
785         try {
786             Vector views = getDatabase().getViews();
787             return convertNotesList(views);
788         } catch (NotesException e) {
789             throw newRuntimeException("Cannot invoke getViews", e);
790         }
791     }
792 
793     /***
794      * {@inheritDoc}
795      * @see de.bea.domingo.DDatabase#getForm(java.lang.String)
796      */
797     public DForm getForm(final String formName) {
798         getFactory().preprocessMethod();
799         try {
800             final Form notesForm = getDatabase().getForm(formName);
801             return FormProxy.getInstance(getFactory(), this, notesForm, getMonitor());
802         } catch (NotesException e) {
803             throw newRuntimeException(RESOURCES.getString("database.cannot.get.from.1", formName), e);
804         }
805     }
806 
807     /***
808      * {@inheritDoc}
809      * @see de.bea.domingo.DDatabase#getForms()
810      */
811     public List getForms() {
812         getFactory().preprocessMethod();
813         try {
814             Vector forms = getDatabase().getForms();
815             return convertNotesList(forms);
816         } catch (NotesException e) {
817             throw newRuntimeException("Cannot invoke getForms", e);
818         }
819     }
820 
821     /***
822      * Converts a list of notes views into a list of corresponding domingo views.
823      *
824      * @param list list of notes views
825      * @return list of corresponding domingo views
826      */
827     private List convertNotesList(final List list) {
828         if (list == null) {
829             return null;
830         }
831         final List result = new ArrayList();
832         for (int i = 0; i < list.size(); i++) {
833             final Object object = list.get(i);
834             if (object instanceof View) {
835                 result.add(ViewProxy.getInstance(getFactory(), this, (View) object, getMonitor()));
836             } else if (object instanceof Form) {
837                 result.add(FormProxy.getInstance(getFactory(), this, (Form) object, getMonitor()));
838             } else {
839                 result.add(object);
840             }
841         }
842         return Collections.unmodifiableList(result);
843     }
844 }