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;
24  
25  import java.applet.Applet;
26  
27  import de.bea.domingo.i18n.ResourceManager;
28  import de.bea.domingo.i18n.Resources;
29  
30  
31  /***
32   * Main entry point for applications to the domingo-API.
33   *
34   * <p>Stand-alond client applications shall call the methos {@link #getInstance()}
35   * method to obtain a singleton instance of the {@link DSession} interface.
36   * Domingo takes care of proper disposual of this singleton session instance.</p>
37   *
38   * <p>Server based applications must call the {@link #newInstance(String)} method
39   * to obtain a new instance of the </p>
40   *
41   * <p>Once an application has obtained a reference to a
42   * <code>DNotesFactory</code> it can use the factory to obtain a Notes
43   * session.</p>
44   *
45   * @author <a href=mailto:kriede@users.sourceforge.net>Kurt Riede</a>
46   */
47  public abstract class DNotesFactory {
48  
49      /*** Singleton instance of this class. */
50      private static DNotesFactory instance = null;
51  
52      /*** Internationalized resources. */
53      private static final Resources RESOURCES = ResourceManager.getPackageResources(DNotesFactory.class);
54  
55      /***
56       * Protected Constructor to restrict creation to sub classes.
57       */
58      protected DNotesFactory() {
59          super();
60      }
61  
62      /***
63       * Returns a singleton instance of class DNotesFactory.
64       *
65       * <p>This method uses the following ordered lookup procedure to determine
66       * the <code>DNotesFactory</code> implementation class to load:
67       * <ul>
68       * <li>Use the <code>de.bea.domingo.factory</code> system property.</li>
69       * <li>Use the resource file <code>de/bea/domingo/domingo.properties</code>
70       * This configuration file must be in standard
71       * <code>java.util.Properties</code> format and contains the fully qualified
72       * name of the implementation class with the key being the system property
73       * defined above.</li>
74       * <li>Defaults to class {@link de.bea.domingo.proxy.NotesProxyFactory}.</li>
75       * </ul></p>
76       *
77       * @return singleton instance of this factory
78       * @throws DNotesRuntimeException if the instance cannot be created
79       */
80      public static synchronized DNotesFactory getInstance() throws DNotesRuntimeException {
81          if (instance == null) {
82              instance = newInstance();
83          }
84          return instance;
85      }
86  
87      /***
88       * Returns a singleton instance of class DNotesFactory.
89       *
90       * @param implementingClassName class name of implementation to use
91       * @return singleton instance of this factory
92       * @throws DNotesRuntimeException if the instance cannot be created
93       */
94      public static synchronized DNotesFactory getInstance(final String implementingClassName) throws DNotesRuntimeException {
95          if (instance == null) {
96              instance = newInstance(implementingClassName);
97          }
98          return instance;
99      }
100 
101     /***
102      * Returns a singleton instance of class DNotesFactory.
103      *
104      * @param implementingClassName class name of implementation to use
105      * @param theMonitor the monitor
106      * @return singleton instance of this factory
107      * @throws DNotesRuntimeException if the instance cannot be created
108      */
109     public static DNotesFactory getInstance(final String implementingClassName, final DNotesMonitor theMonitor)
110             throws DNotesRuntimeException {
111         instance = getInstance(implementingClassName);
112         instance.setMonitor(theMonitor);
113         return instance;
114     }
115 
116     /***
117      * Returns a singleton instance of class DNotesFactory.
118      *
119      * <p>This method uses the following ordered lookup procedure to determine
120      * the <code>DNotesFactory</code> implementation class to load:
121      * <ul>
122      * <li>Use the <code>de.bea.domingo.factory</code> system property.</li>
123      * <li>Use the resource file de/bea/domingo/domingo.properties
124      * This configuration file must be in standard
125      * <code>java.util.Properties</code> format and contains the fully qualified
126      * name of the implementation class with the key being the system property
127      * defined above.</li>
128      * <li>Defaults to class {@link de.bea.domingo.proxy.NotesProxyFactory}.</li>
129      * </ul></p>
130      *
131      * @param theMonitor the monitor
132      * @return singleton instance of this factory
133      * @throws DNotesRuntimeException if the instance cannot be created
134      */
135     public static DNotesFactory getInstance(final DNotesMonitor theMonitor) throws DNotesRuntimeException {
136         instance = getInstance();
137         if (theMonitor != null) {
138             instance.setMonitor(theMonitor);
139         }
140         return instance;
141     }
142 
143     /***
144      * Returns a new instance of class DNotesFactory.
145      *
146      * <p>It is up to the user to remember this instance and to keep it as a singleton if needed.</p>
147      * <p>By default the implementing class is {@link de.bea.domingo.proxy.NotesProxyFactory}.</p>
148      *
149      * @return new instance of this factory
150      * @throws DNotesRuntimeException if the instance cannot be created
151      * @since domingo 1.4
152      */
153     public static DNotesFactory newInstance() throws DNotesRuntimeException {
154         try {
155             return (DNotesFactory) DNotesFactoryFinder.find();
156         } catch (InstantiationException e) {
157             throw new DNotesRuntimeException(e.getMessage());
158         } catch (IllegalAccessException e) {
159             throw new DNotesRuntimeException(e.getMessage());
160         } catch (NoClassDefFoundError e) {
161             if (e.getMessage().indexOf("lotus/domino") >= 0) {
162                 throw new DNotesRuntimeException(RESOURCES.getString("notes.jar.missing"), e);
163             } else {
164                 throw new DNotesRuntimeException(e.getMessage(), e);
165             }
166         }
167     }
168 
169     /***
170      * Returns a new instance of class DNotesFactory.
171      *
172      * <p>It is up to the user to remember this instance and to keep it as a singleton if needed.</p>
173      * <p>By default the implementing class is {@link de.bea.domingo.proxy.NotesProxyFactory}.</p>
174      *
175      * @param theMonitor the monitor
176      * @return new instance of this factory
177      * @throws DNotesRuntimeException if the instance cannot be created
178      * @since domingo 1.4
179      */
180     public static DNotesFactory newInstance(final DNotesMonitor theMonitor) throws DNotesRuntimeException {
181         DNotesFactory newInstance = newInstance();
182         if (theMonitor != null) {
183             newInstance.setMonitor(theMonitor);
184         }
185         return newInstance;
186     }
187 
188     /***
189      * Returns a new instance of class DNotesFactory.
190      *
191      * <p>It is up to the user to remember this instance and to keep it as a singleton if needed.</p>
192      *
193      * @param implementingClassName class name of implementation to use
194      * @param theMonitor the monitor
195      * @return new instance of this factory
196      * @throws DNotesRuntimeException if the instance cannot be created
197      * @since domingo 1.4
198      */
199     public static DNotesFactory newInstance(final String implementingClassName, final DNotesMonitor theMonitor)
200         throws DNotesRuntimeException {
201         DNotesFactory newInstance = newInstance(implementingClassName);
202         newInstance.setMonitor(theMonitor);
203         return newInstance;
204     }
205 
206     /***
207      * Returns a new instance of class DNotesFactory.
208      *
209      * <p>It is up to the user to remember this instance and to keep it as a singleton if needed.</p>
210      *
211      * @param implementingClassName class name of implementation to use
212      * @return new instance of this factory
213      * @throws DNotesRuntimeException if the instance cannot be created
214      * @since domingo 1.4
215      */
216     public static DNotesFactory newInstance(final String implementingClassName) throws DNotesRuntimeException {
217         try {
218             return (DNotesFactory) DNotesFactoryFinder.find(implementingClassName);
219         } catch (InstantiationException e) {
220             throw new DNotesRuntimeException(e.getMessage());
221         } catch (IllegalAccessException e) {
222             throw new DNotesRuntimeException(e.getMessage());
223         } catch (NoClassDefFoundError e) {
224             if (e.getMessage().indexOf("lotus/domino") >= 0) {
225                 throw new DNotesRuntimeException(RESOURCES.getString("notes.jar.missing"), e);
226             } else {
227                 throw new DNotesRuntimeException(e.getMessage(), e);
228             }
229         }
230     }
231 
232     /***
233      * Creates a local session.
234      * <p>(Notes client must be installed)</p>
235      *
236      * @return a local session
237      * @throws DNotesRuntimeException if the session cannot be created
238      */
239     public abstract DSession getSession() throws DNotesRuntimeException;
240 
241     /***
242      * Creates a DIIOP session.
243      *
244      * @param serverUrl URL of server (e.g. <tt>"https://plato.acme:8080"</tt>)
245      * @return a local session
246      * @throws DNotesRuntimeException if the session cannot be created
247      */
248     public abstract DSession getSession(final String serverUrl) throws DNotesRuntimeException;
249 
250     /***
251      * Creates a remote (IIOP or Http) session using host name.
252      *
253      * @param serverUrl URL of server (e.g. <tt>"https://plato.acme:8080"</tt>)
254      * @param user user name for authentication
255      * @param password password for for authentication
256      * @return a remote session
257      * @throws DNotesRuntimeException if the session cannot be created
258      */
259     public abstract DSession getSession(final String serverUrl, final String user, final String password)
260         throws DNotesRuntimeException;
261 
262     /***
263      * Creates a remote (IIOP or Http) session with SSL using host name.
264      *
265      * @param serverUrl URL of server (e.g. <tt>"https://plato.acme:8080"</tt>)
266      * @param user user name for authentication
267      * @param password password for for authentication
268      * @return a remote session
269      * @throws DNotesRuntimeException if the session cannot be created
270      */
271     public abstract DSession getSessionSSL(final String serverUrl, final String user, final String password)
272         throws DNotesRuntimeException;
273 
274     /***
275      * Creates a remote (IIOP or Http) session with arguments using host name.
276      *
277      * @param serverUrl URL of server (e.g. <tt>"https://plato.acme:8080"</tt>)
278      * @param args array of additional arguments
279      * @param user user name for authentication
280      * @param password password for for authentication
281      * @return a remote session
282      * @throws DNotesRuntimeException if the session cannot be created
283      */
284     public abstract DSession getSession(final String serverUrl, final String[] args, final String user, final String password)
285         throws DNotesRuntimeException;
286 
287     /***
288      * Creates a remote (IIOP) session for an applet.
289      *
290      * @param applet applet instance
291      * @param user user name for authentication
292      * @param password password for for authentication
293      * @return a remote session for an applet
294      * @throws DNotesRuntimeException if the session cannot be created
295      */
296     public abstract DSession getSession(final Applet applet, final String user, final String password)
297         throws DNotesRuntimeException;
298 
299     /***
300      * Creates a Domingo session for an existing Notes session.
301      *
302      * <p>This method is used only internally in Notes agents and Notes applets.</p>
303      *
304      * @param notesSession existing Notes session
305      * @return a Domingo session for the given Notes session
306      * @throws DNotesRuntimeException if the session cannot be created
307      */
308     public abstract DSession getSession(final Object notesSession) throws DNotesRuntimeException;
309 
310     /***
311      * Creates a local session.
312      * <p>(Notes client must be installed)</p>
313      * <p>Access restrictions according to readers items are bypassed.</p>
314      *
315      * @return a local session
316      * @throws DNotesRuntimeException if the session cannot be created
317      */
318     public abstract DSession getSessionWithFullAccess() throws DNotesRuntimeException;
319 
320     /***
321      * Creates a local session.
322      * <p>(Notes client must be installed)</p>
323      * <p>Access restrictions according to readers items are bypassed.</p>
324      *
325      * @param password password for for authentication
326      * @return a local session
327      * @throws DNotesRuntimeException if the session cannot be created
328      */
329     public abstract DSession getSessionWithFullAccess(final String password) throws DNotesRuntimeException;
330 
331     /***
332      * Returns the value of a property or returns the given default value if no
333      * configuration found.
334      *
335      * @param key the key of the property
336      * @param defaultValue default value, if no configuration found
337      * @return the value of the property
338      */
339     public static final String getProperty(final String key, final String defaultValue) {
340         return DNotesFactoryFinder.getProperty(key, defaultValue);
341     }
342 
343     /***
344      * Sets a configuration value and overwrites any default or configuration settings.
345      *
346      * @param key the key of the property
347      * @param value the new value
348      */
349     public static void setProperty(final String key, final String value) {
350         DNotesFactoryFinder.setProperty(key, value);
351     }
352 
353     /***
354      * Returns the integer value of a property or returns the given default value if no
355      * configuration found or if the value cannot be converted to an integer value.
356      *
357      * @param key the key of the property
358      * @param defaultValue default value, if no configuration found
359      * @return the value of the property
360      */
361     public static final int getIntProperty(final String key, final int defaultValue) {
362         String value = getProperty(key, Integer.toString(defaultValue));
363         try {
364             return Integer.parseInt(value);
365         } catch (NumberFormatException e) {
366             return defaultValue;
367         }
368     }
369 
370     /***
371      * Returns the integer value of a property or returns the given default value if no
372      * configuration found or if the value cannot be converted to an integer value.
373      *
374      * @param key the key of the property
375      * @param defaultValue default value, if no configuration found
376      * @return the value of the property
377      */
378     public static final boolean getBooleanProperty(final String key, final boolean defaultValue) {
379         String value = getProperty(key, defaultValue ? "true" : "false");
380         try {
381             return Boolean.getBoolean(value);
382         } catch (NumberFormatException e) {
383             return defaultValue;
384         }
385     }
386 
387     /***
388      * Enables Notes access for the current thread.
389      */
390     public abstract void sinitThread();
391 
392     /***
393      * Disables Notes access for the current thread.
394      */
395     public abstract void stermThread();
396 
397     /***
398      * Runs the garbage collector and tries to recycle all internal
399      * notes objects.
400      * <p><b>ATTENTION:</b></p>
401      * <p>This method should not be used in productive code. It only
402      * exists for tests, e.g. to ensure clean memory before analyzing
403      * with JProbe.</p>
404      *
405      * @see java.lang.Runtime#gc()
406      * @deprecated only use this method for testing
407      */
408     protected abstract void gc();
409 
410     /***
411      * Disposes the singleton instance of the factory.
412      *
413      * <p>It is strictly recommended to call this method before exiting
414      * applications in order to not destabilize the Lotus Notes Client.</p>
415      *
416      * <p>If a factory was created with a
417      * {@link #newInstance(String, DNotesMonitor)} method, the factory must be
418      * disposed with the instance method {@link #disposeInstance(boolean)}.
419      *
420      * <p>Equivalent to
421      * <code>{link {@link #dispose(boolean) disposeInstance(true)}</code></p>.
422      *
423      * @throws DNotesRuntimeException if an error occurs during disposal or
424      *              if not all objects can be disposed
425      */
426     public static synchronized void dispose() throws DNotesRuntimeException {
427         if (instance != null) {
428             instance.disposeInstance(true);
429             instance = null;
430         }
431         instance = null;
432     }
433 
434     /***
435      * Disposes the singleton instance of the factory.
436      *
437      * <p>It is strictly recommended to call this method before exiting
438      * applications in order to not destabilize the Lotus Notes Client.</p>
439      *
440      * <p>If a factory was created with a
441      * {@link #newInstance(String, DNotesMonitor)} method, the factory must be
442      * disposed with the instance method {@link #disposeInstance(boolean)}.
443      *
444      * @param force indicates if disposal should happen even if still any
445      *              string or soft reference exists. if <code>false</code>,
446      *              only weak references must remain.
447      * @throws DNotesException if an error occurs during disposal or
448      *              if not all objects can be disposed
449      */
450     public static synchronized void dispose(final boolean force) throws DNotesException {
451         if (instance != null) {
452             instance.disposeInstance(force);
453             instance = null;
454         }
455         instance = null;
456     }
457 
458     /***
459      * Disposes all internal resources of the Notes connection.
460      *
461      * @param force indicates if disposal should happen even if still any
462      *              string or soft reference exists. if <code>false</code>,
463      *              only weak references must remain.
464      * @throws DNotesRuntimeException if an error occurs during disposal or
465      *              if not all objects can be disposed
466      * @deprecated use {@link #disposeInstance(boolean)} instead
467      */
468     public abstract void disposeInternal(final boolean force) throws DNotesRuntimeException;
469 
470     /***
471      * Disposes all internal resources of the Notes connection.
472      *
473      * @param force indicates if disposal should happen even if still any
474      *              string or soft reference exists. if <code>false</code>,
475      *              only weak references must remain.
476      * @throws DNotesRuntimeException if an error occurs during disposal or
477      *              if not all objects can be disposed
478      */
479     public abstract void disposeInstance(final boolean force) throws DNotesRuntimeException;
480 
481     /***
482      * Disposes all internal resources of the Notes connection.
483      *
484      * <p>Equivalent to
485      * <code>{link {@link #disposeInstance(boolean) disposeInstance(false)}</code></p>.
486      *
487      * @throws DNotesRuntimeException if an error occurs during disposal or
488      *              if not all objects can be disposed
489      */
490     public abstract void disposeInstance() throws DNotesRuntimeException;
491 
492     /***
493      * Get the current monitor.
494      * @return current monitor
495      */
496     protected abstract DNotesMonitor getMonitor();
497 
498     /***
499      * Set the monitor.
500      * @param theMonitor the monitor
501      */
502     protected abstract void setMonitor(final DNotesMonitor theMonitor);
503 }