001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free Software Foundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.amber.collection;
030:
031: import com.caucho.amber.AmberQuery;
032: import com.caucho.amber.AmberRuntimeException;
033: import com.caucho.amber.manager.AmberConnection;
034: import com.caucho.amber.query.UserQuery;
035: import com.caucho.util.Alarm;
036:
037: import java.lang.reflect.Method;
038: import java.sql.SQLException;
039: import java.util.AbstractMap;
040: import java.util.HashMap;
041: import java.util.Map;
042: import java.util.Set;
043:
044: /**
045: * Represents a lazy collection.
046: */
047: public class MapImpl<K, V> extends AbstractMap<K, V> implements
048: AmberCollection {
049: private AmberQuery _query;
050:
051: private AmberConnection _aConn;
052:
053: private HashMap<K, V> _values = new HashMap<K, V>();
054: private long _expireTime;
055:
056: private Method _methodGetMapKey;
057:
058: public MapImpl(AmberConnection aConn, String query,
059: Method methodGetMapKey) {
060: _aConn = aConn;
061: _methodGetMapKey = methodGetMapKey;
062:
063: if (query != null) {
064: try {
065: _query = _aConn.prepareQuery(query);
066: } catch (SQLException e) {
067: throw new AmberRuntimeException(e);
068: }
069: }
070: }
071:
072: public MapImpl(AmberQuery query, Method methodGetMapKey) {
073: _query = query;
074: _methodGetMapKey = methodGetMapKey;
075:
076: // jpa/0v00
077: if (_query != null)
078: setSession(((UserQuery) _query).getConnection());
079: }
080:
081: /**
082: * Sets the session.
083: */
084: public void setSession(AmberConnection aConn) {
085: _aConn = aConn;
086:
087: // jpa/0v00
088: if (aConn != null)
089: _aConn.register(this );
090: }
091:
092: /**
093: * Returns the session.
094: */
095: public AmberConnection getSession() {
096: return _aConn;
097: }
098:
099: /**
100: * Returns the query.
101: */
102: public AmberQuery getQuery() {
103: return _query;
104: }
105:
106: /**
107: * Returns the number of items in the collection.
108: */
109: public int size() {
110: fill();
111:
112: return _values.size();
113: }
114:
115: /**
116: * Returns a set view of the mappings contained in this map.
117: */
118: public Set<Map.Entry<K, V>> entrySet() {
119: fill();
120:
121: return _values.entrySet();
122: }
123:
124: /**
125: * Returns an iterator of the items.
126: */
127: public V get(Object key) {
128: fill();
129:
130: return _values.get(key);
131: }
132:
133: /**
134: * Returns a set view of the keys contained in this map.
135: */
136: public Set<K> keySet() {
137: fill();
138:
139: return _values.keySet();
140: }
141:
142: /**
143: * Clears the collection.
144: */
145: public void clear() {
146: _values.clear();
147: _expireTime = Alarm.getCurrentTime();
148: }
149:
150: /**
151: * Updates the collection.
152: */
153: public void update() {
154: _expireTime = 0;
155: }
156:
157: /**
158: * Adds an item to the collection.
159: */
160: public void putAll(Map<? extends K, ? extends V> map) {
161: // jpa/0v04
162:
163: fill();
164:
165: _values.putAll(map);
166: }
167:
168: protected boolean isValid() {
169: return Alarm.getCurrentTime() <= _expireTime;
170: }
171:
172: private void fill() {
173: // jpa/0v04
174: if (_query == null)
175: return;
176:
177: // If it is detached should not be updated.
178: if (_aConn == null)
179: return;
180:
181: if (Alarm.getCurrentTime() <= _expireTime)
182: return;
183:
184: try {
185: _expireTime = Alarm.getCurrentTime();
186:
187: ((UserQuery) _query).setSession(_aConn);
188: _values.clear();
189: _query.list((HashMap) _values, _methodGetMapKey);
190: } catch (Exception e) {
191: throw new AmberRuntimeException(e);
192: }
193: }
194: }
|