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.ArrayList;
26  import java.util.Calendar;
27  import java.util.Collections;
28  import java.util.List;
29  import java.util.TimeZone;
30  import java.util.Vector;
31  
32  import lotus.domino.ACL;
33  import lotus.domino.Agent;
34  import lotus.domino.AgentContext;
35  import lotus.domino.Base;
36  import lotus.domino.Database;
37  import lotus.domino.DateTime;
38  import lotus.domino.DbDirectory;
39  import lotus.domino.Document;
40  import lotus.domino.DxlExporter;
41  import lotus.domino.Form;
42  import lotus.domino.Log;
43  import lotus.domino.Name;
44  import lotus.domino.NotesError;
45  import lotus.domino.NotesException;
46  import lotus.domino.Registration;
47  import lotus.domino.Session;
48  import lotus.domino.View;
49  import de.bea.domingo.DAgentContext;
50  import de.bea.domingo.DBase;
51  import de.bea.domingo.DBaseDocument;
52  import de.bea.domingo.DDatabase;
53  import de.bea.domingo.DDocument;
54  import de.bea.domingo.DDxlExporter;
55  import de.bea.domingo.DLog;
56  import de.bea.domingo.DNotesException;
57  import de.bea.domingo.DNotesMonitor;
58  import de.bea.domingo.DSession;
59  import de.bea.domingo.cache.Cache;
60  import de.bea.domingo.cache.SimpleCache;
61  import de.bea.domingo.exception.DominoException;
62  
63  /***
64   * Notes session.
65   *
66   * @author <a href=mailto:kriede@users.sourceforge.net>Kurt Riede</a>
67   */
68  public final class SessionProxy extends BaseProxy implements DSession {
69  
70      /*** serial version ID for serialization. */
71      private static final long serialVersionUID = 3617290125554628918L;
72  
73      /*** Cache of all databases within a session.
74       * <p>Maps database file names to database proxies.</p>*/
75      private final Cache databaseCache = new SimpleCache();
76  
77      /*** Reference to the international settings of a session. */
78      private final InternationalProxy international;
79  
80      /*** Cached canonical form of name of current user. */
81      private String canonicalUserName = null;
82  
83      /*** mail server of current user. */
84      private String mailServer;
85  
86      /*** name of mail database of current user. */
87      private String mailDatabaseName;
88  
89      /*** mutex to synchronize fetching mail info. */
90      private Object fMailInfoMutex = new Object();
91  
92      /*** name of mail domain of current user. */
93      private String mailDomain;
94  
95      /*** Time zone to use when creating calendar instances. */
96      private TimeZone fZone;
97  
98      /***
99       * Constructor.
100      *
101      * @param theFactory the controlling factory
102      * @param session the encapsulated Notes-Session.
103      * @param monitor the monitor
104      */
105     private SessionProxy(final NotesProxyFactory theFactory, final Session session, final DNotesMonitor monitor) {
106         super(theFactory, null, session, monitor);
107         international = new InternationalProxy(session, monitor);
108     }
109 
110     /***
111      * Creates an encapsulated notes session object.
112      *
113      * @param theFactory the controlling factory
114      * @param theSession the Notes Session
115      * @param monitor the monitor
116      * @return a session object
117      */
118     public static DSession getInstance(final NotesProxyFactory theFactory, final Session theSession,
119                                 final DNotesMonitor monitor) {
120         if (theSession == null) {
121             return null;
122         }
123         SessionProxy sessionProxy = (SessionProxy) theFactory.getBaseCache().get(theSession);
124         if (sessionProxy == null) {
125             sessionProxy = new SessionProxy(theFactory, theSession, monitor);
126             theFactory.getBaseCache().put(theSession, sessionProxy);
127         }
128         return sessionProxy;
129     }
130 
131     /***
132      * Returns the associated Notes session.
133      *
134      * @return associated Notes session
135      */
136     private Session getSession() {
137         getFactory().preprocessMethod();
138         return (Session) this.getNotesObject();
139     }
140 
141     /***
142      * @return Returns the international.
143      */
144     public InternationalProxy getInternational() {
145         return international;
146     }
147 
148     /***
149      * {@inheritDoc}
150      * @see de.bea.domingo.DSession#isOnServer()
151      */
152     public boolean isOnServer() {
153         getFactory().preprocessMethod();
154         try {
155             return getSession().isOnServer();
156         } catch (NotesException e) {
157             throw newRuntimeException(RESOURCES.getString("session.cannot.check.isonserver"), e);
158         }
159     }
160 
161     /***
162      * {@inheritDoc}
163      * @see de.bea.domingo.DSession#getDatabase(java.lang.String, java.lang.String)
164      */
165     public DDatabase getDatabase(final String serverName, final String databaseName) throws DNotesException {
166         getFactory().preprocessMethod();
167         final String dbKey = DatabaseProxy.getDatabaseKey(serverName, databaseName);
168         DDatabase database = (DDatabase) databaseCache.get(dbKey);
169         String userName;
170         try {
171             userName = getCanonicalUserName();
172         } catch (RuntimeException re) {
173             userName = null;
174         }
175         if (database == null) {
176             try {
177                 database = getDatabaseIntern(serverName, databaseName, dbKey, userName);
178                 databaseCache.put(dbKey, database);
179             } catch (NotesException e) {
180                 if (userName == null || "".equals(userName)) {
181                     throw newException(RESOURCES.getString("session.cannot.currentuser.unknown"), e);
182                 } else if (e.id == NotesError.NOTES_ERR_DBSECURITY) {
183                     throw newException("Current user is unknown. Maybe the notes.ini is corrupt.", e);
184                 } else if (e.id == NotesError.NOTES_ERR_DBNOACCESS) {
185                     final DominoException d = new DominoException(e);
186                     final String msg = RESOURCES.getString("session.database.no.access.2", userName, dbKey);
187                     throw new NotesProxyException(msg, d);
188                 } else {
189                     final DominoException d = new DominoException(e);
190                     String msg = RESOURCES.getString("session.cannot.find.database.2", userName, dbKey);
191                     throw new NotesProxyException(msg, d);
192                 }
193             }
194         }
195         return database;
196     }
197 
198     /***
199      * For a given Notes database instance, returns the corresponding existing
200      * domingo database instance if it already exists in the cache, or creates
201      * and returns a new domingo database instance.
202      *
203      * @param database a Notes database instance
204      * @return the corresponding domingo database instance
205      * @throws DNotesException if accessing the database causes an error
206      */
207     private DatabaseProxy getDatabaseProxy(final Database database) throws DNotesException {
208         try {
209             return (DatabaseProxy) getDatabase(database.getServer(), database.getFilePath());
210         } catch (NotesException e) {
211             final DominoException d = new DominoException(e);
212             throw new NotesProxyException(RESOURCES.getString("session.cannot.get.databasekey"), d);
213         }
214     }
215 
216     /***
217      * Internal implementation of getting a database.
218      *
219      * @param serverName server name
220      * @param databaseName database name
221      * @param dbKey database key
222      * @param userName name of current user
223      * @return the database
224      * @throws NotesException if the database cannot be opened due to a notes exception
225      * @throws NotesProxyException if the database cannot be opened even if no notes exception occurred
226      */
227     private DDatabase getDatabaseIntern(final String serverName, final String databaseName, final String dbKey,
228             final String userName) throws NotesException, DNotesException {
229         DDatabase database;
230         Database notesDatabase = getSession().getDatabase(serverName, databaseName);
231         if (notesDatabase == null) {
232             getMonitor().error(RESOURCES.getString("session.cannot.get.database.2", userName, dbKey));
233             throw new NotesProxyException(RESOURCES.getString("session.database.not.found.1", dbKey));
234         }
235         if (notesDatabase.getCurrentAccessLevel() == ACL.LEVEL_NOACCESS) {
236             getMonitor().warn(RESOURCES.getString("session.cannot.access.database.2", userName, dbKey));
237         }
238         if (!notesDatabase.isOpen()) {
239             try {
240                 notesDatabase.open();
241             } catch (NotesException e) {
242                 getMonitor().debug(RESOURCES.getString("session.cannot.open.database.2", userName, dbKey), e);
243             }
244         }
245         if (!notesDatabase.isOpen()) {
246             notesDatabase.recycle();
247             notesDatabase = getSession().getDatabase(serverName, databaseName);
248         }
249         if (!notesDatabase.isOpen()) {
250             try {
251                 notesDatabase.open();
252             } catch (NotesException e) {
253                 getMonitor().debug(RESOURCES.getString("session.failed.open.database.2", userName, dbKey), e);
254             }
255         }
256         if (!notesDatabase.isOpen()) {
257             getMonitor().error(RESOURCES.getString("session.cannot.open.database.2" + userName, dbKey));
258             throw new NotesProxyException(RESOURCES.getString("session.cannot.find.database.2", userName, dbKey));
259         }
260         database = DatabaseProxy.getInstance(getFactory(), this, notesDatabase, getMonitor(), true);
261         return database;
262     }
263 
264     /***
265      * @see de.bea.domingo.proxy.BaseProxy#toString()
266      * @return  a string representation of the object.
267      */
268     public String toString() {
269         return BaseProxy.toStringIntern(this);
270     }
271 
272     /***
273      * {@inheritDoc}
274      * @see de.bea.domingo.DSession#getUserName()
275      */
276     public String getUserName() {
277         getFactory().preprocessMethod();
278         try {
279             return getSession().getUserName();
280         } catch (NotesException e) {
281             throw newRuntimeException(RESOURCES.getString("session.cannot.get.username"), e);
282         }
283     }
284 
285     /***
286      * {@inheritDoc}
287      * @see de.bea.domingo.DSession#createDatabase(java.lang.String, java.lang.String)
288      */
289     public DDatabase createDatabase(final String serverName, final String databaseName) {
290         getFactory().preprocessMethod();
291         try {
292             final DbDirectory directory = getSession().getDbDirectory(serverName);
293             final Database newDatabase = directory.createDatabase(databaseName, true);
294             databaseCache.put(DatabaseProxy.getDatabaseKey(serverName, databaseName), newDatabase);
295             return DatabaseProxy.getInstance(getFactory(), this, newDatabase, getMonitor(), true);
296         } catch (NotesException e) {
297             throw newRuntimeException(RESOURCES.getString("session.cannot.create.database"), e);
298         }
299     }
300 
301     /***
302      * {@inheritDoc}
303      * @see de.bea.domingo.DSession#getCommonUserName()
304      */
305     public String getCommonUserName() {
306         getFactory().preprocessMethod();
307         try {
308             return getSession().getCommonUserName();
309         } catch (NotesException e) {
310             throw newRuntimeException(RESOURCES.getString("session.cannot.get.commonusername"), e);
311         }
312     }
313 
314     /***
315      * {@inheritDoc}
316      * @see de.bea.domingo.DSession#getCanonicalUserName()
317      */
318     public String getCanonicalUserName() {
319         if (canonicalUserName != null) {
320             return canonicalUserName;
321         }
322         getFactory().preprocessMethod();
323         Name name = null;
324         try {
325             name = getSession().getUserNameObject();
326             canonicalUserName = name.getCanonical();
327         } catch (NotesException e) {
328             throw newRuntimeException(RESOURCES.getString("session.cannot.get.canonicalusername"), e);
329         } finally {
330             if (name != null) {
331                 try {
332                     name.recycle();
333                     name = null;
334                 } catch (NotesException e) {
335                     getMonitor().error("Cannot recycle name object", new DominoException(e));
336                 }
337             }
338         }
339         return canonicalUserName;
340     }
341 
342     /***
343      * {@inheritDoc}
344      * @see de.bea.domingo.DSession#evaluate(java.lang.String)
345      */
346     public List evaluate(final String formula) throws DNotesException {
347         getFactory().preprocessMethod();
348         try {
349             return getSession().evaluate(formula);
350         } catch (NotesException e) {
351             throw newException(RESOURCES.getString("session.cannot.evaluate.formula.1", formula), e);
352         }
353     }
354 
355     /***
356      * {@inheritDoc}
357      * @see de.bea.domingo.DSession#evaluate(java.lang.String, de.bea.domingo.DBaseDocument)
358      */
359     public List evaluate(final String formula, final DBaseDocument doc) throws DNotesException {
360         if (!(doc instanceof BaseDocumentProxy)) {
361             throw newRuntimeException("parameter doc is not a valid document");
362         }
363         getFactory().preprocessMethod();
364         try {
365              final Vector vector = getSession().evaluate(formula, ((BaseDocumentProxy) doc).getDocument());
366              final List convertedValues = convertNotesDateTimesToCalendar(vector);
367              recycleDateTimeList(vector);
368              return Collections.unmodifiableList(convertedValues);
369         } catch (NotesException e) {
370             throw newException(RESOURCES.getString("session.cannot.evaluate.formula.1", formula), e);
371         }
372     }
373 
374     /***
375      * {@inheritDoc}
376      * @see de.bea.domingo.DSession#getEnvironmentString(java.lang.String)
377      */
378     public String getEnvironmentString(final String name) {
379         return getEnvironmentString(name, false);
380     }
381 
382     /***
383      * {@inheritDoc}
384      * @see de.bea.domingo.DSession#getEnvironmentValue(java.lang.String)
385      */
386     public Object getEnvironmentValue(final String name) {
387         return getEnvironmentValue(name, false);
388     }
389 
390     /***
391      * {@inheritDoc}
392      * @see de.bea.domingo.DSession#getEnvironmentString(java.lang.String, boolean)
393      */
394     public String getEnvironmentString(final String name, final boolean isSystem) {
395         getFactory().preprocessMethod();
396         try {
397             return getSession().getEnvironmentString(name, isSystem);
398         } catch (NotesException e) {
399             String env = isSystem ? "" : "$" + name;
400             String msg = RESOURCES.getString("session.cannot.get.environmentstring.1", env);
401             throw newRuntimeException(msg, e);
402         }
403     }
404 
405     /***
406      * {@inheritDoc}
407      * @see de.bea.domingo.DSession#getEnvironmentValue(java.lang.String, boolean)
408      */
409     public Object getEnvironmentValue(final String name, final boolean isSystem) {
410         getFactory().preprocessMethod();
411         try {
412             return getSession().getEnvironmentString(name, isSystem);
413         } catch (NotesException e) {
414             String env = isSystem ? "" : "$" + name;
415             String msg = RESOURCES.getString("session.cannot.get.environmentvalue.1", env);
416             throw newRuntimeException(msg, e);
417         }
418     }
419 
420     /***
421      * {@inheritDoc}
422      * @see de.bea.domingo.DSession#setEnvironmentString(java.lang.String, java.lang.String)
423      */
424     public void setEnvironmentString(final String name, final String value) {
425         getFactory().preprocessMethod();
426         try {
427             getSession().setEnvironmentVar(name, value);
428         } catch (NotesException e) {
429             String env = "$" + name;
430             throw newRuntimeException(RESOURCES.getString("session.cannot.set.environmentstring.1", env), e);
431         }
432     }
433 
434     /***
435      * {@inheritDoc}
436      * @see de.bea.domingo.DSession#setEnvironmentString(java.lang.String, java.lang.String, boolean)
437      */
438     public void setEnvironmentString(final String name, final String value, final boolean isSystem) {
439         getFactory().preprocessMethod();
440         try {
441             getSession().setEnvironmentVar(name, value, isSystem);
442         } catch (NotesException e) {
443             String env = isSystem ? "" : "$" + name;
444             throw newRuntimeException(RESOURCES.getString("session.cannot.set.environmentstring.1", env), e);
445         }
446     }
447 
448     /***
449      * {@inheritDoc}
450      * @see de.bea.domingo.DSession#createLog(java.lang.String)
451      */
452     public DLog createLog(final String name) {
453         getFactory().preprocessMethod();
454         try {
455             final Log log = getSession().createLog(name);
456             return LogProxy.getInstance(getFactory(), this, log, getMonitor());
457         } catch (NotesException e) {
458             throw newRuntimeException(RESOURCES.getString("session.cannot.create.log"), e);
459         }
460     }
461 
462     /***
463      * {@inheritDoc}
464      * @see de.bea.domingo.DSession#getAddressBooks()
465      */
466     public List getAddressBooks() {
467         getFactory().preprocessMethod();
468         try {
469             final Vector vector = getSession().getAddressBooks();
470             final List list = new ArrayList();
471             for (int i = 0; i < vector.size(); i++) {
472                 final Database notesDatabase = (Database) vector.get(i);
473                 String key = notesDatabase.toString();
474                 try {
475                     key = DatabaseProxy.getDatabaseKey(notesDatabase.getServer(), notesDatabase.getFilePath());
476                     notesDatabase.open();
477                     final DDatabase proxy = DatabaseProxy.getInstance(getFactory(), this, notesDatabase, getMonitor(), false);
478                     databaseCache.put(key, proxy);
479                     list.add(proxy);
480                 } catch (NotesException ne) {
481                     getMonitor().warn(RESOURCES.getString("session.cannot.open.addressbook.1", key));
482                 }
483             }
484             return list;
485         } catch (NotesException e) {
486             throw newRuntimeException(RESOURCES.getString("session.cannot.create.log"), e);
487         }
488     }
489 
490 
491     /***
492      * {@inheritDoc}
493      * @see de.bea.domingo.DSession#getAbbreviatedName(java.lang.String)
494      */
495     public String getAbbreviatedName(final String canonicalName) {
496         getFactory().preprocessMethod();
497         final Name name;
498         final String abbreviatedName;
499         try {
500             name = this.getSession().createName(canonicalName);
501         } catch (NotesException e) {
502             getMonitor().debug(RESOURCES.getString("session.cannot.create.name.1", canonicalName), e);
503             return null;
504         }
505         try {
506             abbreviatedName = name.getAbbreviated();
507         } catch (NotesException e) {
508             getMonitor().debug(RESOURCES.getString("session.cannot.abbreviate.name.1", canonicalName), e);
509             return null;
510         }
511         try {
512             name.recycle();
513         } catch (NotesException e) {
514             getMonitor().debug(RESOURCES.getString("session.cannot.recycle.name.1", canonicalName), e);
515         }
516         return abbreviatedName;
517     }
518 
519     /***
520      * {@inheritDoc}
521      * @see de.bea.domingo.DSession#getCanonicalName(java.lang.String)
522      */
523     public String getCanonicalName(final String abreviatedName) {
524         getFactory().preprocessMethod();
525         final Name name;
526         final String canonicalName;
527         try {
528             name = this.getSession().createName(abreviatedName);
529         } catch (NotesException e) {
530             getMonitor().debug(RESOURCES.getString("session.cannot.create.name.1", abreviatedName), e);
531             return null;
532         }
533         try {
534             canonicalName = name.getCanonical();
535         } catch (NotesException e) {
536             getMonitor().debug(RESOURCES.getString("session.cannot.abbreviate.name.1", abreviatedName), e);
537             return null;
538         }
539         try {
540             name.recycle();
541         } catch (NotesException e) {
542             getMonitor().debug(RESOURCES.getString("session.cannot.recycle.name.1", abreviatedName), e);
543         }
544         return canonicalName;
545     }
546 
547     /***
548      * {@inheritDoc}
549      * @see de.bea.domingo.DSession#getAgentContext()
550      */
551     public DAgentContext getAgentContext() {
552         getFactory().preprocessMethod();
553         try {
554             final AgentContext agentContext = getSession().getAgentContext();
555             return AgentContextProxy.getInstance(getFactory(), this, agentContext, getMonitor());
556         } catch (NotesException e) {
557             throw newRuntimeException(RESOURCES.getString("session.cannot.get.agentcontext"), e);
558         }
559     }
560 
561     /***
562      * {@inheritDoc}
563      * @see de.bea.domingo.DSession#getCurrentTime()
564      */
565     public Calendar getCurrentTime() {
566         getFactory().preprocessMethod();
567         try {
568             final DateTime dateTime = getSession().createDateTime("Today");
569             dateTime.setNow();
570             final Calendar calendar = this.createCalendar(dateTime);
571             getFactory().recycle(dateTime);
572             return calendar;
573         } catch (NotesException e) {
574             throw newRuntimeException(RESOURCES.getString("session.cannot.get.currenttime"), e);
575         }
576     }
577 
578     /***
579      * {@inheritDoc}
580      * @see de.bea.domingo.DSession#isValid()
581      */
582     public boolean isValid() {
583         getFactory().preprocessMethod();
584         return getSession().isValid();
585     }
586 
587     /***
588      * {@inheritDoc}
589      * @see de.bea.domingo.DSession#getNotesVersion()
590      */
591     public String getNotesVersion() {
592         try {
593             return this.getSession().getNotesVersion();
594         } catch (NotesException e) {
595             throw newRuntimeException(RESOURCES.getString("session.cannot.get.notesversion"), e);
596         }
597     }
598 
599     /***
600      * {@inheritDoc}
601      * @see de.bea.domingo.DSession#getPlatform()
602      */
603     public String getPlatform() {
604         try {
605             return this.getSession().getPlatform();
606         } catch (NotesException e) {
607             throw newRuntimeException(RESOURCES.getString("session.cannot.get.notesplatform"), e);
608         }
609     }
610 
611     /***
612      * {@inheritDoc}
613      * @see de.bea.domingo.DSession#createDxlExporter()
614      */
615     public DDxlExporter createDxlExporter() throws DNotesException {
616         try {
617             final DxlExporter dxlExporter = this.getSession().createDxlExporter();
618             return DxlExporterProxy.getInstance(getFactory(), this, dxlExporter, getMonitor());
619         } catch (NotesException e) {
620             throw newRuntimeException(RESOURCES.getString("session.cannot.create.dxlexporter"), e);
621         }
622     }
623 
624     /***
625      * {@inheritDoc}
626      *
627      * <p>The two methods {@link #getMailServer()()} and {@link #getMailDatabaseName()()}
628      * are synchronized to prevent double-reading of mail information. The field
629      * <code>fMailInfoMutex</code> is used as the locking mutex.</p>
630      *
631      * @see de.bea.domingo.DSession#getMailServer()
632      */
633     public String getMailServer() {
634         synchronized (fMailInfoMutex) {
635             if (mailServer == null) {
636                 readMailInfo();
637             }
638             return mailServer;
639 
640         }
641     }
642 
643     /***
644      * {@inheritDoc}
645      *
646      * <p>The two methods {@link #getMailServer()()} and {@link #getMailDatabaseName()()}
647      * are synchronized to prevent double-reading of mail information. The field
648      * <code>mailServer</code> is used as the locking mutex.</p>
649      *
650      * @see de.bea.domingo.DSession#getMailDatabaseName()
651      */
652     public String getMailDatabaseName() {
653         synchronized (fMailInfoMutex) {
654             if (mailDatabaseName == null) {
655                 readMailInfo();
656             }
657             return mailDatabaseName;
658         }
659     }
660 
661     /***
662      * {@inheritDoc}
663      *
664      * @see de.bea.domingo.DSession#getMailDatabase()
665      */
666     public DDatabase getMailDatabase() throws DNotesException {
667         return getDSession().getDatabase(getMailServer(), getMailDatabaseName());
668     }
669 
670     /***
671      * {@inheritDoc}
672      *
673      * <p>The mail server of the current user is used as registration server.</p>
674      *
675      * @see de.bea.domingo.DSession#getMailDatabase()
676      * @see de.bea.domingo.DSession#getMailDatabase(String)
677      */
678     public DDatabase getMailDatabase(final String username) throws DNotesException {
679         return getMailDatabase(getMailServer(), username);
680     }
681 
682     /***
683      * <p>The two methods {@link #getMailServer()()} and {@link #getMailDatabaseName()()}
684      * are synchronized to prevent double-reading of mail information. The field
685      * <code>fMailInfoMutex</code> is used as the locking mutex.</p>
686      *
687      * @see de.bea.domingo.DSession#getMailDatabase()
688      */
689     private DDatabase getMailDatabase(final String registrationServer, final String username) throws DNotesException {
690         Registration registration = null;
691         StringBuffer server = new StringBuffer();
692         StringBuffer file = new StringBuffer();
693         StringBuffer domain = new StringBuffer();
694         StringBuffer system = new StringBuffer();
695         Vector profile = new Vector();
696         try {
697             registration = getSession().createRegistration();
698             registration.setRegistrationServer(registrationServer);
699             registration.getUserInfo(username, server, file, domain, system, profile);
700         } catch (NotesException e) {
701             getMonitor().warn("Cannot access registration", e);
702         } finally {
703             if (registration != null) {
704                 try {
705                     registration.recycle();
706                 } catch (NotesException e) {
707                     getMonitor().warn("Cannot recycle registration", e);
708                 }
709             }
710         }
711         return getDSession().getDatabase(server.toString(), file.toString());
712     }
713 
714     /***
715      * {@inheritDoc}
716      * @see de.bea.domingo.DSession#getMailDomain()
717      */
718     public String getMailDomain() {
719         if (mailDomain == null) {
720             readMailDomain();
721         }
722         return mailDomain;
723     }
724 
725     /***
726      * {@inheritDoc}
727      * @see de.bea.domingo.DSession#resolve(String)
728      */
729     public DBase resolve(final String url) {
730         getFactory().preprocessMethod();
731         try {
732             Base base = getSession().resolve(url);
733             if (base instanceof Database) {
734                 return DatabaseProxy.getInstance(getFactory(), this, (Database) base, getMonitor(), false);
735             } else if (base instanceof View) {
736                 Database notesDatabase = ((View) base).getParent();
737                 DatabaseProxy database = (DatabaseProxy) getDatabaseProxy(notesDatabase);
738                 return ViewProxy.getInstance(getFactory(), database, (View) base, getMonitor());
739             } else if (base instanceof Form) {
740                 getMonitor().warn("resolving URLs to forms is not yet supported");
741                 // TODO support class DForm
742                 return null;
743             } else if (base instanceof Agent) {
744                 Database notesDatabase = ((Agent) base).getParent();
745                 DatabaseProxy database = (DatabaseProxy) getDatabaseProxy(notesDatabase);
746                 return AgentProxy.getInstance(getFactory(), database, (Agent) base, getMonitor());
747             } else if (base instanceof Document) {
748                 return DatabaseProxy.getInstance(getFactory(), this, (Database) base, getMonitor(), false);
749             } else {
750                 return null;
751             }
752         } catch (NotesException e) {
753             throw newRuntimeException(RESOURCES.getString("session.cannot.resolve.url.1", url), e);
754         } catch (DNotesException e) {
755             throw newRuntimeException(RESOURCES.getString("session.cannot.resolve.url.1", url), e);
756         }
757     }
758 
759     /***
760      * Reads and caches both, the mail server and the mail database name
761      * of the current user.
762      */
763     private void readMailInfo() {
764         String server = getServerName();
765         // TODO check if this test is ok... shouldn't we check if session.isOnServer?
766         if (server == null || server.length() == 0) {
767             readLocalMailInfo();
768         } else {
769             readServerMailInfo();
770         }
771     }
772 
773     /***
774      * Reads the location of the current mail file from the location
775      * that is currently selected in the Notes client.
776      */
777     private void readLocalMailInfo() {
778         String locationValue = getEnvironmentString("Location", true);
779         if (locationValue == null || locationValue.length() == 0) {
780             readServerMailInfo();
781             return;
782         }
783         String locationNoteId = parseLocationNoteId(locationValue);
784         try {
785             DDatabase database = getDatabase("", "names.nsf");
786             DDocument location = database.getDocumentByID(locationNoteId);
787             String mailType = location.getItemValueString("MailType");
788             mailDatabaseName = location.getItemValueString("MailFile");
789             if ("1".equals(mailType)) { // local mail file
790                 mailServer = "";
791             } else {
792                 mailServer = location.getItemValueString("MailServer");
793             }
794         } catch (DNotesException e) {
795             throw new NotesProxyRuntimeException("Cannot use local names.nsf", e);
796         }
797     }
798 
799     /***
800      * Extracts the note-id of the current location from a location value as
801      * used in the file <code>notes.ini</code>.
802      * <p>The note-id is between the last two commas in the string.</p>
803      * <p>Example from notes.ini: <code>Location=Office (Network),9EA,CN=Kurt Riede/O=acme</code></p>
804      *
805      * @param locationValue
806      * @return note-Id of location value
807      */
808     static String parseLocationNoteId(final String locationValue) {
809         int pos2 = locationValue.lastIndexOf(',');
810         if (pos2 < 0) {
811             throw new IllegalArgumentException("invalid location value: " + locationValue);
812         }
813         int pos1 = locationValue.lastIndexOf(',', pos2 - 1);
814         if (pos2 < 0) {
815             throw new IllegalArgumentException("invalid location value: " + locationValue);
816         }
817         return locationValue.substring(pos1 + 1, pos2);
818     }
819 
820     private void readServerMailInfo() {
821         // TODO get mail info Registration from Session
822         Vector vector;
823         try {
824             vector = this.getSession().evaluate("@MailDbName");
825         } catch (NotesException e) {
826             throw newRuntimeException(RESOURCES.getString("session.cannot.read.mailinfo"));
827         }
828         if (vector.size() == 0) {
829             throw newRuntimeException("Cannot get mail server");
830         }
831         mailServer = (String) vector.get(0);
832         if (vector.size() < 2) {
833             throw newRuntimeException(RESOURCES.getString("session.cannot.get.maildatabase"));
834         }
835         mailDatabaseName = (String) vector.get(1);
836     }
837 
838     private void readMailDomain() {
839         Vector vector;
840         try {
841             vector = this.getSession().evaluate("@Domain");
842         } catch (NotesException e) {
843             throw newRuntimeException("Cannot get mail domain", e);
844         }
845         if (vector.size() < 2) {
846             throw newRuntimeException(RESOURCES.getString("session.cannot.get.maildomain"));
847         }
848         mailDomain = (String) vector.get(1);
849     }
850 
851     /***
852      * {@inheritDoc}
853      * @see de.bea.domingo.DSession#getServerName()
854      */
855     public String getServerName() {
856         try {
857             return getSession().getServerName();
858         } catch (NotesException e) {
859             throw newRuntimeException(RESOURCES.getString("session.cannot.get.servername"), e);
860         }
861     }
862 
863     /***
864      * {@inheritDoc}
865      * @see de.bea.domingo.DSession#setTimeZone(java.util.TimeZone)
866      */
867     public void setTimeZone(final TimeZone zone) {
868         fZone = zone;
869     }
870 
871     /***
872      * {@inheritDoc}
873      * @see de.bea.domingo.DSession#getTimeZone()
874      */
875     public TimeZone getTimeZone() {
876         return fZone;
877     }
878 }