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 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 License for more details.
013:
014: You should have received a copy of the GNU General Public 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: package net.sf.borg.model.db.file;
021:
022: import java.util.ArrayList;
023: import java.util.Collection;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.List;
027:
028: import net.sf.borg.model.BorgOption;
029: import net.sf.borg.model.beans.KeyedBean;
030: import net.sf.borg.model.db.BeanDB;
031: import net.sf.borg.model.db.file.mdb.Row;
032: import net.sf.borg.model.db.file.mdb.SMDB;
033:
034: // FileBeanDB is a layer on top of SMDB. It reads Row records
035: // from the underlying SMDB database. The user passes in a FileBeanAdapter which will
036: // be used to convert between the Rows and the corresponding KeyedBean object.
037: //
038: // An XML schema for the DB is used when creating the DB. The Row objects
039: // use this schema to translate to and from a String. A code generator
040: // also uses this schema to generate the FileBeanAdapter and KeyedBean classes.
041: //
042: // A FileBeanDB will use a KeyedBean subclass to communicate data to callers.
043:
044: class FileBeanDB extends SMDB implements BeanDB {
045: private FileBeanAdapter adapter_; // adapter for converting Rows to DataBeans
046: private boolean objectCacheOn_; // is caching on?
047: private HashMap objectCache_; // the cache
048:
049: FileBeanDB(String file, int locktype, FileBeanAdapter a,
050: boolean shared) throws Exception {
051: super (file, locktype, shared);
052: objectCacheOn_ = true;
053: objectCache_ = new HashMap();
054:
055: adapter_ = a;
056: }
057:
058: // turn on caching
059: public void cacheOn(boolean b) {
060: objectCacheOn_ = b;
061: }
062:
063: // read all beans from the DB
064: public Collection readAll() throws Exception {
065: List lst = new ArrayList();
066: Iterator itr = getKeys().iterator();
067: while (itr.hasNext()) {
068: Integer ki = (Integer) itr.next();
069: lst.add(readObj(ki.intValue()));
070: }
071: return lst;
072: }
073:
074: // read a bean from the DB given the key
075: public KeyedBean readObj(int key) throws Exception {
076:
077: // if the bean is in the cache - return it
078: if (objectCacheOn_) {
079: Object o = objectCache_.get(new Integer(key));
080:
081: if (o != null) {
082: KeyedBean r = (KeyedBean) o;
083: return r.copy();
084: }
085: }
086:
087: Row sr = readRow(key);
088: if (sr == null)
089: return null;
090: KeyedBean bean = adapter_.fromRow(sr);
091: // put the bean in the cache
092: if (objectCacheOn_) {
093: objectCache_.put(new Integer(key), bean);
094: }
095:
096: // return a copy of the bean - so that changes to the bean
097: // do not update the cached bean
098: return bean.copy();
099:
100: }
101:
102: public KeyedBean newObj() {
103: return (adapter_.newBean());
104: }
105:
106: // add a bean unencrypted
107: public void addObj(KeyedBean bean) throws Exception {
108: addObj(bean, false);
109: }
110:
111: // add a bean that has been filled in by the caller
112: public void addObj(KeyedBean bean, boolean crypt) throws Exception {
113:
114: Row sr = adapter_.toRow(schema_, bean, normalize_);
115:
116: addRow(sr.getKey(), sr, crypt);
117:
118: // put a copy of the bean in the cache
119: if (objectCacheOn_) {
120: objectCache_.put(new Integer(bean.getKey()), bean.copy());
121: }
122: }
123:
124: // update unencrypted
125: public void updateObj(KeyedBean bean) throws Exception {
126: updateObj(bean, false);
127: }
128:
129: // update a bean
130: public void updateObj(KeyedBean bean, boolean crypt)
131: throws Exception {
132:
133: // delete the record first
134: delete(bean.getKey());
135:
136: // call addObj
137: addObj(bean, crypt);
138: }
139:
140: public void delete(int key) throws Exception {
141:
142: // remove the bean from the cache
143: if (objectCacheOn_) {
144: objectCache_.remove(new Integer(key));
145: }
146:
147: // call MDB.delete()
148: super .delete(key);
149: }
150:
151: public final synchronized boolean isDirty() throws Exception {
152: return isMDBDirty();
153: }
154:
155: public void sync() {
156: syncMDB();
157: objectCache_ = new HashMap();
158: }
159:
160: public Collection getOptions() throws Exception {
161: List lst = new ArrayList();
162: Iterator itr = optionKeys().iterator();
163: while (itr.hasNext()) {
164: String oname = (String) itr.next();
165: lst.add(new BorgOption(oname, getOption(oname)));
166: }
167: return lst;
168: }
169:
170: public void setOption(BorgOption option) throws Exception {
171: setOption(option.getKey(), option.getValue());
172: }
173: }
|