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.proxy;
24
25 import lotus.domino.Agent;
26 import lotus.domino.AgentContext;
27 import lotus.domino.Base;
28 import lotus.domino.Database;
29 import lotus.domino.DateRange;
30 import lotus.domino.DateTime;
31 import lotus.domino.DbDirectory;
32 import lotus.domino.Document;
33 import lotus.domino.DocumentCollection;
34 import lotus.domino.EmbeddedObject;
35 import lotus.domino.Form;
36 import lotus.domino.Item;
37 import lotus.domino.Log;
38 import lotus.domino.NotesException;
39 import lotus.domino.RichTextItem;
40 import lotus.domino.Session;
41 import lotus.domino.View;
42 import lotus.domino.ViewEntry;
43 import lotus.domino.ViewEntryCollection;
44 import lotus.domino.ViewNavigator;
45 import de.bea.domingo.DNotesMonitor;
46 import de.bea.domingo.exception.DominoException;
47 import de.bea.domingo.monitor.AbstractMonitorEnabled;
48 import de.bea.domingo.queue.Queue;
49
50 /***
51 * Implementation of interface <code>NotesRecycler</code> that explicitly
52 * recycles almost all Notes objects.
53 *
54 * <p>This strategy should be used with Lotus Notes R5 while missing explicit
55 * recycle results in memory leaks.</p>
56 *
57 * @author <a href=mailto:kriede@users.sourceforge.net>Kurt Riede</a>
58 */
59 public final class RecycleStrategy extends AbstractMonitorEnabled implements NotesRecycler {
60
61 /*** Reference to a recycle queue. */
62 private Queue recycleQueue = new NotesRecycleQueue();
63
64 /*** Indicates whether the DateTime recycle problem is already reported.*/
65 private boolean dateTimeHitfixProblemReported = false;
66
67 /***
68 * Constructor.
69 *
70 * @param monitor the monitor
71 */
72 public RecycleStrategy(final DNotesMonitor monitor) {
73 super(monitor);
74 }
75
76 /***
77 * {@inheritDoc}
78 * @see de.bea.domingo.proxy.NotesRecycler#recycleLater(java.lang.Object)
79 */
80 public synchronized void recycleLater(final Object object) {
81 final Base notesBase = getNotesObject(object);
82 if (notesBase != null) {
83 recycleQueue.enqueue(notesBase);
84 }
85 }
86
87 /***
88 * @see de.bea.domingo.proxy.NotesRecycler#recycleQueue()
89 */
90 public synchronized void recycleQueue() {
91 if (!recycleQueue.isEmpty()) {
92 while (!recycleQueue.isEmpty()) {
93 final Object obj = recycleQueue.dequeue();
94 if (obj != null) {
95 recycle(obj);
96 }
97 }
98 }
99 }
100
101 /***
102 * {@inheritDoc}
103 * @see de.bea.domingo.proxy.NotesRecycler#recycle(java.lang.Object)
104 */
105 public synchronized void recycle(final Object object) {
106 final Base notesBase = getNotesObject(object);
107 try {
108 if (notesBase == null) {
109 return;
110 } else if (notesBase instanceof Session) {
111 notesBase.recycle();
112 } else if (notesBase instanceof DbDirectory) {
113 notesBase.recycle();
114 } else if (notesBase instanceof Database) {
115 notesBase.recycle();
116 } else if (notesBase instanceof Log) {
117 return;
118 } else if (notesBase instanceof View) {
119 notesBase.recycle();
120 } else if (notesBase instanceof ViewNavigator) {
121 notesBase.recycle();
122 } else if (notesBase instanceof ViewEntryCollection) {
123 return;
124 } else if (notesBase instanceof ViewEntry) {
125 notesBase.recycle();
126 } else if (notesBase instanceof DocumentCollection) {
127 notesBase.recycle();
128 } else if (notesBase instanceof Document) {
129 notesBase.recycle();
130 } else if (notesBase instanceof Item) {
131 return;
132 } else if (notesBase instanceof RichTextItem) {
133 return;
134 } else if (notesBase instanceof EmbeddedObject) {
135 return;
136 } else if (notesBase instanceof Form) {
137 notesBase.recycle();
138 } else if (notesBase instanceof Agent) {
139 notesBase.recycle();
140 } else if (notesBase instanceof AgentContext) {
141 notesBase.recycle();
142 } else if (notesBase instanceof DateTime) {
143 recycleDateTime((DateTime) notesBase);
144 } else if (notesBase instanceof DateRange) {
145 notesBase.recycle();
146 } else {
147 getMonitor().debug("No explicit recycle strategy found for class " + notesBase.getClass().getName());
148 notesBase.recycle();
149 }
150 } catch (NotesException e) {
151 getMonitor().warn("Cannot recycle " + notesBase.getClass().getName(), new DominoException(e));
152 }
153 }
154
155 /***
156 * Recycles a Notes date/time object.
157 *
158 * @param dateTime the date/time object
159 */
160 private void recycleDateTime(final DateTime dateTime) {
161 try {
162 if (dateTime.getParent() == null) {
163
164
165
166
167
168
169
170
171
172
173
174 if (!dateTimeHitfixProblemReported) {
175 dateTimeHitfixProblemReported = true;
176 getMonitor().fatalError("recycle a DateTime object without parent session.");
177 }
178 } else {
179 dateTime.recycle();
180 }
181 } catch (NotesException e) {
182 getMonitor().warn("recycle DateTime with parent session not available.", new DominoException(e));
183 }
184 }
185
186 /***
187 * Given any object (might be a Domingo object or a Notes object) returns
188 * the base notes object if available.
189 *
190 * @return notes object
191 */
192 private Base getNotesObject(final Object object) {
193 final Base notesBase;
194 if (object instanceof BaseProxy) {
195 notesBase = ((BaseProxy) object).getNotesObject();
196 } else if (object instanceof Base) {
197 notesBase = (Base) object;
198 } else {
199 notesBase = null;
200 }
201 return notesBase;
202 }
203 }