KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > nextapp > echo2 > webcontainer > util > IdTable


1 /*
2  * This file is part of the Echo Web Application Framework (hereinafter "Echo").
3  * Copyright (C) 2002-2005 NextApp, Inc.
4  *
5  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * Alternatively, the contents of this file may be used under the terms of
18  * either the GNU General Public License Version 2 or later (the "GPL"), or
19  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
20  * in which case the provisions of the GPL or the LGPL are applicable instead
21  * of those above. If you wish to allow use of your version of this file only
22  * under the terms of either the GPL or the LGPL, and not to allow others to
23  * use your version of this file under the terms of the MPL, indicate your
24  * decision by deleting the provisions above and replace them with the notice
25  * and other provisions required by the GPL or the LGPL. If you do not delete
26  * the provisions above, a recipient may use your version of this file under
27  * the terms of any one of the MPL, the GPL or the LGPL.
28  */

29
30 package nextapp.echo2.webcontainer.util;
31
32 import java.io.IOException JavaDoc;
33 import java.io.ObjectInputStream JavaDoc;
34 import java.io.ObjectOutputStream JavaDoc;
35 import java.io.Serializable JavaDoc;
36 import java.lang.ref.Reference JavaDoc;
37 import java.lang.ref.ReferenceQueue JavaDoc;
38 import java.lang.ref.WeakReference JavaDoc;
39 import java.util.HashMap JavaDoc;
40 import java.util.HashSet JavaDoc;
41 import java.util.Iterator JavaDoc;
42 import java.util.Map JavaDoc;
43 import java.util.Set JavaDoc;
44
45 import nextapp.echo2.app.RenderIdSupport;
46
47 /**
48  * A table which provides an identifier-to-object mapping, with the objects
49  * being weakly referenced (i.e., the fact that they are held within this table
50  * will not prevent them from being garbage collected).
51  */

52 public class IdTable
53 implements Serializable JavaDoc {
54     
55     private boolean hasHardReferences = false;
56     private transient Map JavaDoc idToReferenceMap = new HashMap JavaDoc();
57     private transient ReferenceQueue JavaDoc referenceQueue = new ReferenceQueue JavaDoc();
58     
59     /**
60      * Registers an object with the <code>IdTable</code>
61      *
62      * @param object the object to identify
63      */

64     public void register(RenderIdSupport object) {
65         purge();
66         String JavaDoc id = object.getRenderId();
67         WeakReference JavaDoc weakReference;
68         synchronized(idToReferenceMap) {
69             if (!idToReferenceMap.containsKey(id)) {
70                 weakReference = new WeakReference JavaDoc(object, referenceQueue);
71                 idToReferenceMap.put(id, weakReference);
72             }
73         }
74     }
75     
76     /**
77      * Retrieves the object associated with the specified identifier.
78      *
79      * @param id the identifier
80      * @return the object (or null, if the object is not in the queue, perhaps
81      * due to having been dereferenced and garbage collected)
82      */

83     public Object JavaDoc getObject(String JavaDoc id) {
84         purge();
85         WeakReference JavaDoc weakReference;
86         synchronized(idToReferenceMap) {
87             weakReference = (WeakReference JavaDoc) idToReferenceMap.get(id);
88         }
89         if (weakReference == null) {
90             return null;
91         }
92         Object JavaDoc object = weakReference.get();
93         return object;
94     }
95     
96     /**
97      * Purges dereferenced/garbage collected entries from the
98      * <code>IdTable</code>.
99      */

100     private void purge() {
101         // Convert any hard references to weak references.
102
if (hasHardReferences) {
103             synchronized (idToReferenceMap) {
104                 Iterator JavaDoc idIt = idToReferenceMap.keySet().iterator();
105                 while (idIt.hasNext()) {
106                     String JavaDoc id = (String JavaDoc) idIt.next();
107                     Object JavaDoc object = idToReferenceMap.get(id);
108                     if (!(object instanceof WeakReference JavaDoc)) {
109                         WeakReference JavaDoc weakReference = new WeakReference JavaDoc(object, referenceQueue);
110                         idToReferenceMap.put(id, weakReference);
111                     }
112                 }
113                 hasHardReferences = false;
114             }
115         }
116         
117         // Purge weak references that are no longer hard referenced elsewhere.
118
Reference JavaDoc reference = referenceQueue.poll();
119         if (reference == null) {
120             // No such references exist.
121
return;
122         }
123         Set JavaDoc referenceSet = new HashSet JavaDoc();
124         while (reference != null) {
125             referenceSet.add(reference);
126             reference = referenceQueue.poll();
127         }
128         
129         synchronized (idToReferenceMap) {
130             Iterator JavaDoc idIt = idToReferenceMap.keySet().iterator();
131             while (idIt.hasNext()) {
132                 String JavaDoc id = (String JavaDoc) idIt.next();
133                 if (referenceSet.contains(idToReferenceMap.get(id))) {
134                     idIt.remove();
135                 }
136             }
137         }
138     }
139
140     /**
141      * @see java.io.Serializable
142      *
143      * Writes objects directly into values of Map as straight references.
144      * The values will be changed to <code>WeakReference</code>s when
145      * purge() is called.
146      */

147     private void readObject(ObjectInputStream JavaDoc in)
148     throws IOException JavaDoc, ClassNotFoundException JavaDoc {
149         in.defaultReadObject();
150         
151         idToReferenceMap = new HashMap JavaDoc();
152         referenceQueue = new ReferenceQueue JavaDoc();
153        
154         String JavaDoc id = (String JavaDoc) in.readObject();
155         if (id != null) {
156             // Hard references will be written.
157
hasHardReferences = true;
158
159             // Load map and store objects as hard references.
160
while (id != null) {
161                 RenderIdSupport object = (RenderIdSupport) in.readObject();
162                 idToReferenceMap.put(id, object);
163                 id = (String JavaDoc) in.readObject();
164             }
165         }
166     }
167
168     /**
169      * @see java.io.Serializable
170      */

171     private void writeObject(ObjectOutputStream JavaDoc out)
172     throws IOException JavaDoc {
173         out.defaultWriteObject();
174         Iterator JavaDoc it = idToReferenceMap.keySet().iterator();
175         while (it.hasNext()) {
176             String JavaDoc id = (String JavaDoc) it.next();
177             out.writeObject(id);
178             Object JavaDoc object = idToReferenceMap.get(id);
179             if (object instanceof WeakReference JavaDoc) {
180                 object = ((WeakReference JavaDoc) object).get();
181             }
182             out.writeObject(object);
183         }
184         // Write null to specify end of object.
185
out.writeObject(null);
186     }
187 }
188
Popular Tags