001: /*
002: This file is part of BORG.
003:
004: BORG is free software; you can redistribute it and/or modify
005: it under the terms of the GNU General public final synchronized License as published by
006: the Free Software Foundation; either version 2 of the License, or
007: (at your option) any later version.
008:
009: BORG is distributed in the hope that it will be useful,
010: but WITHOUT ANY WARRANTY; without even the implied warranty of
011: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: GNU General public final synchronized License for more details.
013:
014: You should have received a copy of the GNU General public final synchronized License
015: along with BORG; if not, write to the Free Software
016: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017:
018: Copyright 2003 by Mike Berger
019: */
020:
021: package net.sf.borg.model.db.remote;
022:
023: import java.util.ArrayList;
024: import java.util.Collection;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028:
029: import net.sf.borg.model.BorgOption;
030: import net.sf.borg.model.beans.KeyedBean;
031: import net.sf.borg.model.db.BeanDB;
032:
033: public class CachingBeanDB implements BeanDB {
034: public CachingBeanDB(BeanDB delegate) {
035: this .delegate = delegate;
036: }
037:
038: // BeanDB overrides
039: public final synchronized Collection readAll() throws Exception {
040: return new ArrayList(getObjectMap().values());
041: }
042:
043: public final synchronized KeyedBean readObj(int key)
044: throws Exception {
045: KeyedBean bean = (KeyedBean) getObjectMap().get(
046: new Integer(key));
047: return bean == null ? bean : bean.copy();
048: }
049:
050: public final synchronized KeyedBean newObj() {
051: try {
052: return delegate.newObj();
053: } catch (Exception e) {
054: throw new RuntimeException(e.getClass().getName() + ": "
055: + e.getMessage());
056: }
057: }
058:
059: public synchronized void addObj(KeyedBean bean, boolean crypt)
060: throws Exception {
061: delegate.addObj(bean, crypt);
062: getObjectMap().put(new Integer(bean.getKey()), bean);
063: }
064:
065: public synchronized void updateObj(KeyedBean bean, boolean crypt)
066: throws Exception {
067: delegate.updateObj(bean, crypt);
068: getObjectMap().put(new Integer(bean.getKey()), bean);
069: }
070:
071: public synchronized void delete(int key) throws Exception {
072: getObjectMap().remove(new Integer(key));
073: delegate.delete(key);
074: }
075:
076: public final synchronized Collection getOptions() throws Exception {
077: List lst = new ArrayList();
078: Iterator itr = getOptionsMap().entrySet().iterator();
079: while (itr.hasNext()) {
080: Map.Entry entry = (Map.Entry) itr.next();
081: lst.add(new BorgOption((String) entry.getKey(),
082: (String) entry.getValue()));
083: }
084: return lst;
085: }
086:
087: public final synchronized String getOption(String oname)
088: throws Exception {
089: return (String) getOptionsMap().get(oname);
090: }
091:
092: public final void setOption(BorgOption option) throws Exception {
093: setOption(option.getKey(), option.getValue());
094: }
095:
096: public final synchronized void setOption(String oname, String value)
097: throws Exception {
098: delegate.setOption(new BorgOption(oname, value));
099: getOptionsMap().put(oname, value);
100: }
101:
102: public final synchronized Collection getOptionKeys()
103: throws Exception {
104: return getOptionsMap().keySet();
105: }
106:
107: public final synchronized Collection getKeys() throws Exception {
108: return getObjectMap().keySet();
109: }
110:
111: public final synchronized void close() throws Exception {
112: delegate.close();
113: }
114:
115: public final synchronized int nextkey() throws Exception {
116: return delegate.nextkey();
117: }
118:
119: public final synchronized boolean isDirty() throws Exception {
120: if (data == null)
121: return true;
122: // need to rebuild the world
123:
124: // HACK: We would like to ask our delegate BeanDB if s/he's dirty.
125: // To avoid hammering the server though, we pretend we already know
126: // the answer if we've performed the query less than a second ago
127: // and the response was negative.
128: long lCurTime = System.currentTimeMillis();
129: if (lastNegativeDirtyQueryTimestamp != Long.MIN_VALUE
130: && lCurTime <= (lastNegativeDirtyQueryTimestamp + 1000L))
131: return false;
132:
133: boolean isDelegateDirty = delegate.isDirty();
134: if (!isDelegateDirty)
135: lastNegativeDirtyQueryTimestamp = lCurTime;
136:
137: return isDelegateDirty;
138: }
139:
140: public final synchronized void sync() {
141: delegate.sync();
142: }
143:
144: // protected //
145: protected boolean refresh() throws Exception {
146: if (!isDirty())
147: return false;
148:
149: // System.out.println("Rebuilding the world....");
150:
151: data = new CachingDBCache();
152:
153: // Repopulate our maps.
154: Map map = data.getObjectMap();
155: Collection col = delegate.readAll();
156: for (Iterator itr = col.iterator(); itr.hasNext();) {
157: KeyedBean bean = (KeyedBean) itr.next();
158: map.put(new Integer(bean.getKey()), bean);
159: }
160:
161: map = data.getOptionsMap();
162: col = delegate.getOptions();
163: for (Iterator itr = col.iterator(); itr.hasNext();) {
164: BorgOption option = (BorgOption) itr.next();
165: map.put(option.getKey(), option.getValue());
166: }
167:
168: return true;
169: }
170:
171: protected final Map getObjectMap() throws Exception {
172: refresh();
173: return data.getObjectMap();
174: }
175:
176: protected final Map getOptionsMap() throws Exception {
177: refresh();
178: return data.getOptionsMap();
179: }
180:
181: // private //
182: protected BeanDB delegate;
183: private CachingDBCache data;
184: private long lastNegativeDirtyQueryTimestamp = Long.MIN_VALUE;
185: }
|