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 }