Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/vrspace/server/db/DBCache.java


1   package org.vrspace.server.db;
2   
3   import java.lang.reflect.*;
4   import java.util.*;
5   import java.io.*;
6   
7   import org.vrspace.server.*;
8   import org.vrspace.util.*;
9   
10  /**
11   * Database class
12   *
13  */
14  public class DBCache extends DB {
15    private TreeMap tables = new TreeMap();
16    private DB db;
17  
18    public DBCache( DB db ) {
19      db.cache = this;
20      this.db = db;
21    }
22  
23    public String create( String name ) throws Exception {
24      return db.create( name );
25    }
26    /**
27    Returns references to cached tables
28    */
29    TreeMap getTables() {
30      return tables;
31    }
32    /**
33    Connect to database.
34    Calls underlying DB connect().
35    **/
36    public void connect( String name ) throws Exception
37    {
38      db.connect( name );
39    }
40  
41    /** Disconnect **/
42    public void disconnect()
43    {
44      db.disconnect();
45    }
46  
47    /**
48    Commit. Just calls underlying commit
49    */
50    public void commit() {
51      db.commit();
52    }
53  
54    /**
55    Get an object.
56    */
57    public Object get ( Object obj ) throws Exception
58    {
59      return get( getClassName(obj), obj.getClass().getField( "db_id" ).getLong(obj) );
60    }
61  
62    /** From the table <b>obj</b>.getClass().getName() deletes the row having
63     ** db_id == <b>obj</b>.db_id, from both cache and the underlying db.
64     */
65    public void delete( Object obj ) throws Exception
66    {
67      TreeMap table = (TreeMap) tables.get( getClassName(obj) );
68      if ( table != null ) {
69        long id = obj.getClass().getField("db_id").getLong( obj );
70        table.remove( new Long( id ) );
71      }
72      db.delete( obj );
73    }
74    /** 
75    Returns the object having id == <b>obj</b>.db_id
76     */
77    public Object get( String className, long id ) throws Exception
78    {
79      Object ret;
80      if ( className == null ) {
81        throw new DBException( "Null className" );
82      }
83      if ( tables == null ) {
84        throw new DBException( "Null tables" );
85      }
86      TreeMap table = (TreeMap) tables.get( className );
87      if ( table == null ) {
88        ret = db.get( className, id );
89        if ( ret == null  ) {
90          /*
91          // let's just ignore this - it's not important for the cache
92          DBException tabe = new DBException( "Table " + className + " does not exist" );
93          Logger.logError( tabe );
94          throw tabe;
95          */
96        } else {
97          _put( ret );
98        }
99      } else {
100       ret = table.get( new Long(id) );
101       //Logger.logDebug( "DB.get("+className+","+id+")->"+ret );
102       if ( ret == null ) {
103         ret = db.get( className, id );
104       }
105       if ( ret != null ) {
106         _put( ret );
107       }
108     }
109     return ret;
110   }
111 
112   /** Returns the object of <b>className</b> class having <b>field</b> == <b>value</b> */
113   public Object get( String className, String field, Object value ) throws Exception
114   {
115     if ( className == null ) {
116       throw new DBException( "Null className" );
117     }
118     if ( tables == null ) {
119       throw new DBException( "Null tables" );
120     }
121     Object ret = null;
122     TreeMap table = (TreeMap) tables.get( className );
123     if ( table == null ) {
124       throw new DBException( "Table " + className + " does not exist" );
125     } else {
126       Object[] rows = table.values().toArray();
127       try {
128         for ( int i = 0; i < rows.length; i++ ){
129           Field f = rows[i].getClass().getField( field );
130           try {
131             Object val=f.get(rows[i]);
132             //Logger.logDebug( "TextDB.get("+className+","+field+","+value+")="+val );
133             if ( val != null && val.equals( value ) ) {
134               ret = rows[i];
135               //Logger.logDebug( "TextDB.get("+className+","+field+","+value+")="+ret );
136               break;
137             }
138           } catch ( NullPointerException nulle ) {
139             throw new DBException( "Field not found: "+className+"."+field+"=="+value );
140           } catch ( IllegalAccessException acce ) {
141             throw new DBException( "Field not found: "+className+"."+field+"=="+value );
142           }
143         }
144         if ( ret == null ) {
145           ret = db.get( className, field, value );
146           if ( ret != null ) {
147             _put( ret );
148           } else {
149             throw new DBException( "Object not found: "+className+"."+field+"=="+value );
150           }
151         }
152       } catch ( NoSuchFieldException e ) {
153         throw new DBException( e.getMessage() );
154       }
155     }
156     return ret;
157   }
158 
159   /**
160   Returns all members of the class
161   */
162   public Object[] getAll( String className ) throws Exception {
163     Object[] ret = null;
164     TreeMap table = (TreeMap) tables.get( className );
165     if ( table == null ) {
166       throw new DBException( "Table " + className + " does not exist" );
167     } else {
168       ret = table.values().toArray();
169     }
170     return ret;
171   }
172 
173   /** 
174   Returns Object[] of <b>className</b> class having <b>field</b> == <b>value</b> <br>
175   TODO: map calls on underlying DB
176   */
177   public Object[] getRange( String className, String field, Object value )
178                 throws Exception
179   {
180     Object[] ret = new Object[0];
181     TreeMap table = (TreeMap) tables.get( className );
182     if ( table == null ) {
183       throw new DBException( "Table " + className + " does not exist" );
184     } else {
185       Object[] rows = table.values().toArray();
186       try {
187         //Vector v = new Vector();
188         LinkedList v = new LinkedList();
189         for ( int i = 0; i < rows.length; i++ ){
190           if ( rows[i].getClass().getField( field ).get( rows[i] ).equals( value ) ) {
191             v.add( rows[i] );
192           }
193         }
194         ret = v.toArray();
195       } catch ( NoSuchFieldException e ) {
196         throw new DBException( e.getMessage() );
197       } catch ( IllegalAccessException e ) {
198         throw new DBException( e.getMessage() );
199       } catch ( NullPointerException e ) {
200       }
201     }
202     return ret;
203   }
204   /** 
205   Returns Object[] between o1 and o2
206   Class must have comparator() method to be searchable.<br>
207   TODO: map calls to underlying DB!
208   */
209   public Object[] getRange( Object o1, Object o2 )
210                   throws Exception
211   {
212     Object[] ret = null;
213     try {
214       TreeMap table = (TreeMap) tables.get( getClassName(o1) );
215       VRObjectComparator comparator = (VRObjectComparator) o1.getClass().getMethod( "comparator", null ).invoke( o1, null );
216       Iterator it = table.values().iterator();
217       //Vector res = new Vector();
218       LinkedList res = new LinkedList();
219       while ( it.hasNext() ) {
220         Object element = it.next();
221         if ( comparator.compare( o1, element ) < 0 && comparator.compare( element, o2 ) < 0 ) {
222           res.add( element );
223         }
224       }
225       ret = res.toArray();
226     } catch ( NoSuchMethodException e ) {
227       throw new DBException( "Class "+o1.getClass().getName()+" needs a VRObjectComparator to be indexed" );
228     } catch ( IllegalAccessException e ) {
229       throw new DBException( "Could not access comparator()" );
230     } catch ( InvocationTargetException e ) {
231       throw new DBException( "InvocationTargetException while creating comparator()" );
232     }
233     return ret;
234   }
235 
236   public String getClassName( Object obj ) {
237     String name = ((VRObject)obj).getClassName();
238     return name;
239   }
240   
241   /**
242   Stores obj into cache
243    */
244   private synchronized void _put( Object obj ) throws Exception
245   {
246     TreeMap table = (TreeMap) tables.get( getClassName(obj) );
247     if ( table == null ) {
248       table = createTable( obj );
249     }
250     long id = obj.getClass().getField("db_id").getLong( obj );
251     if ( id == 0 ) {
252       // new object
253       if( table.size()>0 ) {
254         id = ((Long) table.lastKey()).longValue()+1;
255       } else {
256         id = 1;
257       }
258       obj.getClass().getField("db_id").setLong( obj, id );
259     }
260     //Logger.logDebug( "TextDB.put( "+getClassName(obj)+", "+obj.getClass().getName()+" "+id+")" );
261     table.put( new Long( id ), obj );
262   }
263   /**
264   Stores obj into database
265    */
266   public void put( Object obj ) throws Exception {
267     db.put( obj );
268     _put( obj );
269   }
270 
271   /**
272   This method only passes request to underlying database.
273   */
274   public void update( Request r ) throws Exception {
275     db.update( r );
276     _put( r.object );
277   }
278 
279   /** Does <b>table</b> exist? **/
280   public boolean tableExists( String table ) {
281     return ( tables.containsKey( table ) );
282   }
283   
284   private TreeMap createTable( Object obj ) throws DBException
285   {
286     String table = getClassName( obj );
287     Logger.logDebug( "Creating table "+table+ " (package "+Util.getPackageName(obj)+")" ); // produces NPE without packages
288     TreeMap ret = new TreeMap();
289     if ( tables.containsKey( table ) ) {
290       throw new DBException ( "Table " + table + " already exists" );
291     } else {
292       tables.put( table, ret );
293     }
294     return ret;
295   }
296 }