View Javadoc

1   /*
2    * Copyright 2007 Hippo
3    *
4    * Licensed under the Apache License, Version 2.0 (the  "License"); 
5    * you may not use this file except in compliance with the License. 
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" 
12   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
15   */
16  package nl.hippo.client.caching;
17  
18  import java.io.Serializable;
19  import java.lang.ref.WeakReference;
20  import java.util.ArrayList;
21  import java.util.Collection;
22  import java.util.Iterator;
23  
24  import nl.hippo.client.api.event.NamedEvent;
25  
26  import org.apache.commons.collections.map.MultiValueMap;
27  
28  public class EventRegistry {
29  
30      private MultiValueMap m_eventMap;
31  
32      public EventRegistry() {
33          m_eventMap = new MultiValueMap();
34      }
35  
36      public void register(NamedEvent e, Object key) {
37          synchronized (this) {
38  
39              if (CacheLogger.log.isDebugEnabled()) {
40                  CacheLogger.log.debug("Register in EventRegistry: " + e.toString() + " -> " + key.toString());
41              }
42  
43              Collection coll = (Collection) m_eventMap.get(e);
44              if (coll == null) {
45                  m_eventMap.put(e, new WeakReference(key));
46                  return;
47              }
48  
49              Iterator it = coll.iterator();
50              Collection removeableWeakRef = new ArrayList();
51  
52              /** below: keep the eventMap clean. Only put when 
53               * (e,key) is not present yet. MultiValueMap puts duplicate 
54               * keys which are the same
55               */
56              while (it.hasNext()) {
57                  Object obj = it.next();
58                  if (obj instanceof WeakReference) {
59                      WeakReference weakKey = (WeakReference) (obj);
60  
61                      // remove the Weak keys that have been set to null to
62                      // avoid memory leaks
63                      if (weakKey != null) {
64                          Object refedObject = weakKey.get();
65  
66                          if (refedObject == null) {
67                              removeableWeakRef.add(weakKey);
68                          }
69                      }
70                  }
71              }
72              m_eventMap.put(e, new WeakReference(key));
73  
74              it = removeableWeakRef.iterator();
75              while (it.hasNext()) {
76                  m_eventMap.remove(e, it.next());
77              }
78          }
79      }
80  
81      /**
82       * Remove all registered data.
83       */
84      public void clear() {
85          synchronized (this) {
86              m_eventMap.clear();
87          }
88      }
89  
90      /**
91       * Retrieve all cache keys mapped to this event.
92       */
93      public Serializable[] keysForEvent(NamedEvent e) {
94  
95          Collection coll;
96          synchronized (this) {
97              Collection collFromMap = (Collection) m_eventMap.get(e);
98  
99              if (collFromMap == null) {
100                 coll = new ArrayList(0);
101             } else {
102                 coll = new ArrayList();
103                 Iterator it = collFromMap.iterator();
104                 while (it.hasNext()) {
105                     Object obj = it.next();
106 
107                     if (obj instanceof WeakReference) {
108                         WeakReference weakKey = (WeakReference) (obj);
109 
110                         Object refedObject = weakKey.get();
111                         // must be seperate test for != null to avoid race conditions
112                         if (refedObject != null) {
113                             coll.add(refedObject);
114                         }
115                     }
116                 }
117             }
118         }
119 
120         Serializable[] result = (Serializable[]) coll.toArray(new Serializable[coll.size()]);
121 
122         if (CacheLogger.log.isDebugEnabled()) {
123             if (result.length > 0) {
124                 StringBuffer buf = new StringBuffer().append("EventRegistry lookup of ").append(e.toString()).append(
125                         " -> ");
126                 for (int i = 0; i < result.length; i++) {
127                     buf.append(System.getProperty("line.separator")).append(result[i].toString());
128                 }
129                 CacheLogger.log.debug(buf.toString());
130             }
131         }
132 
133         return result;
134     }
135 
136     public void dispose() {
137         m_eventMap.clear();
138         m_eventMap = null;
139     }
140 
141 }