1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 }