001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry.services.impl;
016
017 import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock;
018 import org.apache.tapestry.event.ReportStatusEvent;
019 import org.apache.tapestry.event.ReportStatusListener;
020 import org.apache.tapestry.event.ResetEventListener;
021 import org.apache.tapestry.services.ObjectPool;
022
023 import java.util.*;
024
025 /**
026 * Implementation of the {@link org.apache.tapestry.services.ObjectPool} interface.
027 * <p>
028 * This ia a minimal implementation, one that has no concept of automatically removing unused pooled
029 * objects. Eventually, it will also register for notifications about general cache cleaning.
030 *
031 * @author Howard Lewis Ship
032 * @since 4.0
033 */
034 public class ObjectPoolImpl implements ObjectPool, ResetEventListener, ReportStatusListener
035 {
036 private String _serviceId;
037
038 private int _count = 0;
039
040 private final ReentrantLock _lock = new ReentrantLock();
041
042 /**
043 * Pool of Lists (of pooled objects), keyed on arbitrary key.
044 */
045 private Map _pool = new HashMap();
046
047 public Object get(Object key)
048 {
049 List pooled = (List) _pool.get(key);
050
051 try
052 {
053 _lock.lock();
054
055 if (pooled == null || pooled.isEmpty())
056 return null;
057
058 _count--;
059
060 return pooled.remove(0);
061
062 } finally
063 {
064 _lock.unlock();
065 }
066 }
067
068 public void store(Object key, Object value)
069 {
070 List pooled = (List) _pool.get(key);
071
072 try
073 {
074 _lock.lock();
075
076 if (pooled == null)
077 {
078 pooled = new LinkedList();
079 _pool.put(key, pooled);
080 }
081
082 pooled.add(value);
083
084 _count++;
085 } finally
086 {
087 _lock.unlock();
088 }
089 }
090
091 public void resetEventDidOccur()
092 {
093 _pool.clear();
094
095 _count = 0;
096 }
097
098 public void reportStatus(ReportStatusEvent event)
099 {
100 event.title(_serviceId);
101
102 event.property("total count", _count);
103
104 event.section("Count by Key");
105
106 Iterator i = _pool.entrySet().iterator();
107
108 while (i.hasNext())
109 {
110 Map.Entry entry = (Map.Entry) i.next();
111
112 String key = entry.getKey().toString();
113
114 List pooled = (List) entry.getValue();
115
116 event.property(key, pooled.size());
117 }
118 }
119
120 public void setServiceId(String serviceId)
121 {
122 _serviceId = serviceId;
123 }
124 }