1   package org.apache.commons.jcs.admin;
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  import org.apache.commons.jcs.access.exception.CacheException;
23  import org.apache.commons.jcs.auxiliary.remote.server.RemoteCacheServer;
24  import org.apache.commons.jcs.auxiliary.remote.server.RemoteCacheServerFactory;
25  import org.apache.commons.jcs.engine.CacheElementSerialized;
26  import org.apache.commons.jcs.engine.behavior.ICacheElement;
27  import org.apache.commons.jcs.engine.behavior.IElementAttributes;
28  import org.apache.commons.jcs.engine.control.CompositeCache;
29  import org.apache.commons.jcs.engine.control.CompositeCacheManager;
30  import org.apache.commons.jcs.engine.memory.behavior.IMemoryCache;
31  
32  import java.io.IOException;
33  import java.io.ObjectOutputStream;
34  import java.io.Serializable;
35  import java.text.DateFormat;
36  import java.util.Arrays;
37  import java.util.Date;
38  import java.util.LinkedList;
39  import java.util.Set;
40  
41  
42  
43  
44  
45  
46  
47  public class JCSAdminBean implements JCSJMXBean
48  {
49      
50      private final CompositeCacheManager cacheHub;
51  
52      
53  
54  
55      public JCSAdminBean()
56      {
57          super();
58          try
59          {
60              this.cacheHub = CompositeCacheManager.getInstance();
61          }
62          catch (CacheException e)
63          {
64              throw new RuntimeException("Could not retrieve cache manager instance", e);
65          }
66      }
67  
68      
69  
70  
71  
72  
73  	public JCSAdminBean(CompositeCacheManager cacheHub)
74  	{
75  		super();
76  		this.cacheHub = cacheHub;
77  	}
78  
79  	
80  
81  
82  
83  
84  
85  
86      @Override
87      public CacheElementInfo[] buildElementInfo( String cacheName )
88          throws Exception
89      {
90          CompositeCache<Serializable, Serializable> cache = cacheHub.getCache( cacheName );
91  
92          Serializable[] keys = cache.getMemoryCache().getKeySet().toArray(new Serializable[0]);
93  
94          
95          
96          try
97          {
98              Arrays.sort( keys );
99          }
100         catch ( Exception e )
101         {
102             keys = cache.getMemoryCache().getKeySet().toArray(new Serializable[0]);
103         }
104 
105         LinkedList<CacheElementInfo> records = new LinkedList<CacheElementInfo>();
106 
107         ICacheElement<Serializable, Serializable> element;
108         IElementAttributes attributes;
109         CacheElementInfo elementInfo;
110 
111         DateFormat format = DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT );
112 
113         long now = System.currentTimeMillis();
114 
115         for (Serializable key : keys)
116         {
117             element = cache.getMemoryCache().getQuiet( key );
118 
119             attributes = element.getElementAttributes();
120 
121             elementInfo = new CacheElementInfo(
122             		String.valueOf( key ),
123             		attributes.getIsEternal(),
124             		format.format(new Date(attributes.getCreateTime())),
125             		attributes.getMaxLife(),
126             		(now - attributes.getCreateTime() - attributes.getMaxLife() * 1000 ) / -1000);
127 
128             records.add( elementInfo );
129         }
130 
131         return records.toArray(new CacheElementInfo[0]);
132     }
133 
134     
135 
136 
137 
138 
139 
140 
141 
142     @Override
143     public CacheRegionInfo[] buildCacheInfo()
144         throws Exception
145     {
146         String[] cacheNames = cacheHub.getCacheNames();
147 
148         Arrays.sort( cacheNames );
149 
150         LinkedList<CacheRegionInfo> cacheInfo = new LinkedList<CacheRegionInfo>();
151 
152         CacheRegionInfo regionInfo;
153         CompositeCache<?, ?> cache;
154 
155         for ( int i = 0; i < cacheNames.length; i++ )
156         {
157             cache = cacheHub.getCache( cacheNames[i] );
158 
159             regionInfo = new CacheRegionInfo(
160                     cache.getCacheName(),
161                     cache.getSize(),
162                     cache.getStatus().toString(),
163                     cache.getStats(),
164                     cache.getHitCountRam(),
165                     cache.getHitCountAux(),
166                     cache.getMissCountNotFound(),
167                     cache.getMissCountExpired(),
168                     getByteCount( cache ));
169 
170             cacheInfo.add( regionInfo );
171         }
172 
173         return cacheInfo.toArray(new CacheRegionInfo[0]);
174     }
175 
176 
177 	
178 
179 
180 
181 
182 
183 
184 	@Override
185     public int getByteCount(String cacheName)
186 	{
187 		return getByteCount(cacheHub.getCache(cacheName));
188 	}
189 
190 	
191 
192 
193 
194 
195 
196 
197     public <K, V> int getByteCount(CompositeCache<K, V> cache)
198     {
199         if (cache == null)
200         {
201             throw new IllegalArgumentException("The cache object specified was null.");
202         }
203 
204         long size = 0;
205         IMemoryCache<K, V> memCache = cache.getMemoryCache();
206 
207         for (K key : memCache.getKeySet())
208         {
209             ICacheElement<K, V> ice = null;
210 			try
211 			{
212 				ice = memCache.get(key);
213 			}
214 			catch (IOException e)
215 			{
216                 throw new RuntimeException("IOException while trying to get a cached element", e);
217 			}
218 
219 			if (ice == null)
220 			{
221 				continue;
222 			}
223 
224 			if (ice instanceof CacheElementSerialized)
225             {
226                 size = size + ((CacheElementSerialized<K, V>) ice).getSerializedValue().length;
227             }
228             else
229             {
230                 Object element = ice.getVal();
231 
232                 
233                 CountingOnlyOutputStream counter = new CountingOnlyOutputStream();
234                 ObjectOutputStream out = null;
235                 try
236                 {
237                     out = new ObjectOutputStream(counter);
238                     out.writeObject(element);
239                 }
240                 catch (IOException e)
241                 {
242                     throw new RuntimeException("IOException while trying to measure the size of the cached element", e);
243                 }
244                 finally
245                 {
246                 	try
247                 	{
248                 		if (out != null)
249                 		{
250                 			out.close();
251                 		}
252 					}
253                 	catch (IOException e)
254                 	{
255                 		
256 					}
257                 	try
258                 	{
259 						counter.close();
260 					}
261                 	catch (IOException e)
262                 	{
263                 		
264 					}
265                 }
266 
267                 
268                 size = size + counter.getCount() - 4;
269             }
270         }
271 
272         if (size > Integer.MAX_VALUE)
273         {
274             throw new IllegalStateException("The size of cache " + cache.getCacheName() + " (" + size + " bytes) is too large to be represented as an integer.");
275         }
276 
277         return (int) size;
278     }
279 
280     
281 
282 
283 
284 
285 
286 
287     @Override
288     public void clearAllRegions() throws IOException
289     {
290         if (RemoteCacheServerFactory.getRemoteCacheServer() == null)
291         {
292             
293             
294 
295             String[] names = cacheHub.getCacheNames();
296 
297             for (int i = 0; i < names.length; i++)
298             {
299                 cacheHub.getCache(names[i]).removeAll();
300             }
301         }
302         else
303         {
304             
305             
306             try
307             {
308                 String[] cacheNames = cacheHub.getCacheNames();
309 
310                 
311                 RemoteCacheServer<?, ?> remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
312                 for (int i = 0; i < cacheNames.length; i++)
313                 {
314                     String cacheName = cacheNames[i];
315                     remoteCacheServer.removeAll(cacheName);
316                 }
317             }
318             catch (IOException e)
319             {
320                 throw new IllegalStateException("Failed to remove all elements from all cache regions: " + e, e);
321             }
322         }
323     }
324 
325     
326 
327 
328 
329 
330 
331 
332     @Override
333     public void clearRegion(String cacheName) throws IOException
334     {
335         if (cacheName == null)
336         {
337             throw new IllegalArgumentException("The cache name specified was null.");
338         }
339         if (RemoteCacheServerFactory.getRemoteCacheServer() == null)
340         {
341             
342             
343             cacheHub.getCache(cacheName).removeAll();
344         }
345         else
346         {
347             
348             
349             try
350             {
351                 
352                 RemoteCacheServer<?, ?> remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
353                 remoteCacheServer.removeAll(cacheName);
354             }
355             catch (IOException e)
356             {
357                 throw new IllegalStateException("Failed to remove all elements from cache region [" + cacheName + "]: " + e, e);
358             }
359         }
360     }
361 
362     
363 
364 
365 
366 
367 
368 
369 
370 
371 
372 
373 
374     @Override
375     public void removeItem(String cacheName, String key) throws IOException
376     {
377         if (cacheName == null)
378         {
379             throw new IllegalArgumentException("The cache name specified was null.");
380         }
381         if (key == null)
382         {
383             throw new IllegalArgumentException("The key specified was null.");
384         }
385         if (RemoteCacheServerFactory.getRemoteCacheServer() == null)
386         {
387             
388             
389             cacheHub.getCache(cacheName).remove(key);
390         }
391         else
392         {
393             
394             
395             try
396             {
397                 Object keyToRemove = null;
398                 CompositeCache<?, ?> cache = CompositeCacheManager.getInstance().getCache(cacheName);
399 
400                 
401                 
402                 
403                 
404                 Set<?> allKeysInCache = cache.getMemoryCache().getKeySet();
405                 for (Object keyInCache : allKeysInCache)
406                 {
407                     if (keyInCache.toString().equals(key))
408                     {
409                         if (keyToRemove == null)
410                         {
411                             keyToRemove = keyInCache;
412                         }
413                         else
414                         {
415                             
416                             throw new IllegalStateException("Unexpectedly found duplicate keys in the cache region matching the key specified.");
417                         }
418                     }
419                 }
420                 if (keyToRemove == null)
421                 {
422                     throw new IllegalStateException("No match for this key could be found in the set of keys retrieved from the memory cache.");
423                 }
424                 
425 
426                 
427                 RemoteCacheServer<Serializable, Serializable> remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
428                 remoteCacheServer.remove(cacheName, key);
429             }
430             catch (Exception e)
431             {
432                 throw new IllegalStateException("Failed to remove element with key [" + key + ", " + key.getClass() + "] from cache region [" + cacheName + "]: " + e, e);
433             }
434         }
435     }
436 }