Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

CacheDatabaseTable.java

00001 /**
00002  * C-JDBC: Clustered JDBC.
00003  * Copyright (C) 2002-2004 French National Institute For Research In Computer
00004  * Science And Control (INRIA).
00005  * Contact: c-jdbc@objectweb.org
00006  * 
00007  * This library is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation; either version 2.1 of the License, or any later
00010  * version.
00011  * 
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00015  * for more details.
00016  * 
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00020  *
00021  * Initial developer(s): Emmanuel Cecchet.
00022  * Contributor(s): Sara Bouchenak.
00023  */
00024 
00025 package org.objectweb.cjdbc.controller.cache.result.schema;
00026 
00027 import java.io.Serializable;
00028 import java.sql.SQLException;
00029 import java.util.ArrayList;
00030 import java.util.HashMap;
00031 import java.util.Iterator;
00032 
00033 import org.objectweb.cjdbc.common.sql.RequestType;
00034 import org.objectweb.cjdbc.common.sql.schema.DatabaseColumn;
00035 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable;
00036 import org.objectweb.cjdbc.controller.cache.result.entries.CacheEntry;
00037 import org.objectweb.cjdbc.controller.cache.result.entries.ResultCacheEntry;
00038 
00039 /**
00040  * A <code>CacheDatabaseTable</code> represents a database table and its
00041  * associated cache entries. It has an array of <code>CacheDatabaseColumn</code>
00042  * objects.
00043  * <p>
00044  * Keep it mind that <code>ArrayList</code> and <code>HashMap</code> are not
00045  * synchronized...
00046  * 
00047  * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
00048  * @author <a href="mailto:Sara.Bouchenak@epfl.ch">Sara Bouchenak </a>
00049  * @version 1.0
00050  */
00051 public class CacheDatabaseTable implements Serializable
00052 {
00053   private String    name;
00054   private ArrayList columns;
00055   private ArrayList cacheEntries;  // Cache entries depending on this table
00056   private HashMap   pkCacheEntries; // Cache entries corresponding to a pk value
00057 
00058   /**
00059    * Creates a new <code>CacheDatabaseTable</code> instance.
00060    * 
00061    * @param databaseTable the database table to cache
00062    */
00063   public CacheDatabaseTable(DatabaseTable databaseTable)
00064   {
00065     // Clone the name and the columns
00066     name = databaseTable.getName();
00067     ArrayList origColumns = databaseTable.getColumns();
00068     int size = origColumns.size();
00069     columns = new ArrayList(size);
00070     for (int i = 0; i < size; i++)
00071       columns.add(new CacheDatabaseColumn(((DatabaseColumn) origColumns.get(i))
00072           .getName()));
00073 
00074     // Create an empty cache
00075     cacheEntries = new ArrayList();
00076     pkCacheEntries = new HashMap();
00077   }
00078 
00079   /**
00080    * Gets the name of the table.
00081    * 
00082    * @return the table name
00083    */
00084   public String getName()
00085   {
00086     return name;
00087   }
00088 
00089   /**
00090    * Adds a <code>CacheDatabaseColumn</code> object to this table.
00091    * <p>
00092    * Warning! The underlying <code>ArrayList</code> is not synchronized.
00093    * 
00094    * @param column a <code>CacheDatabaseColumn</code> value
00095    */
00096   public void addColumn(CacheDatabaseColumn column)
00097   {
00098     columns.add(column);
00099   }
00100 
00101   /**
00102    * Merge the given table's columns with the current table. All missing columns
00103    * are added if no conflict is detected. An exception is thrown if the given
00104    * table columns conflicts with the current one.
00105    * 
00106    * @param t the table to merge
00107    * @throws SQLException if the schemas conflict
00108    */
00109   public void mergeColumns(CacheDatabaseTable t) throws SQLException
00110   {
00111     if (t == null)
00112       return;
00113 
00114     ArrayList otherColumns = t.getColumns();
00115     if (otherColumns == null)
00116       return;
00117 
00118     int size = otherColumns.size();
00119     for (int i = 0; i < size; i++)
00120     {
00121       CacheDatabaseColumn c = (CacheDatabaseColumn) otherColumns.get(i);
00122       CacheDatabaseColumn original = getColumn(c.getName());
00123       if (original == null)
00124         addColumn(c);
00125       else
00126       {
00127         if (!original.equals(c))
00128           throw new SQLException("Column " + c.getName()
00129               + " definition mismatch.");
00130       }
00131     }
00132   }
00133 
00134   /**
00135    * Returns a list of <code>CacheDatabaseColumn</code> objects describing the
00136    * columns of this table.
00137    * <p>
00138    * Warning! The underlying <code>ArrayList</code> is not synchronized.
00139    * 
00140    * @return an <code>ArrayList</code> of <code>CacheDatabaseColumn</code>
00141    */
00142   public ArrayList getColumns()
00143   {
00144     return columns;
00145   }
00146 
00147   /**
00148    * Returns the <code>CacheDatabaseColumn</code> object matching the given
00149    * column name or <code>null</code> if not found.
00150    * 
00151    * @param columnName column name to look for
00152    * @return a <code>CacheDatabaseColumn</code> value or <code>null</code>
00153    */
00154   public CacheDatabaseColumn getColumn(String columnName)
00155   {
00156     for (Iterator i = columns.iterator(); i.hasNext();)
00157     {
00158       CacheDatabaseColumn c = (CacheDatabaseColumn) i.next();
00159       if (columnName.compareToIgnoreCase(c.getName()) == 0)
00160         return c;
00161     }
00162     return null;
00163   }
00164 
00165   /**
00166    * Two <code>CacheDatabaseColumn</code> are equals if they have the same
00167    * name and the same columns.
00168    * 
00169    * @param other the object to compare with
00170    * @return true if the objects are the same
00171    */
00172   public boolean equals(Object other)
00173   {
00174     if (!(other instanceof CacheDatabaseTable))
00175       return false;
00176 
00177     CacheDatabaseTable t = (CacheDatabaseTable) other;
00178     return t.getName().equals(name) && t.getColumns().equals(columns);
00179   }
00180 
00181   /**
00182    * Adds a <code>CacheEntry</code> object whose consistency depends on this
00183    * table.
00184    * 
00185    * @param ce a <code>CacheEntry</code> value
00186    */
00187   public synchronized void addCacheEntry(CacheEntry ce)
00188   {
00189     cacheEntries.add(ce);
00190   }
00191 
00192   /**
00193    * Adds a <code>CacheEntry</code> object associated to a pk entry.
00194    * 
00195    * @param pk the pk entry
00196    * @param ce a <code>CacheEntry</code> value
00197    */
00198   public void addPkCacheEntry(String pk, CacheEntry ce)
00199   {
00200     synchronized (pkCacheEntries)
00201     {
00202       pkCacheEntries.put(pk, ce);
00203     }
00204   }
00205 
00206   /**
00207    * Gets a <code>CacheEntry</code> object associated to a pk entry.
00208    * 
00209    * @param pk the pk entry
00210    * @return the corresponding cache entry if any or null if nothing is found
00211    */
00212   public ResultCacheEntry getPkResultCacheEntry(String pk)
00213   {
00214     if (pk == null)
00215       return null;
00216     synchronized (pkCacheEntries)
00217     {
00218       return (ResultCacheEntry) pkCacheEntries.get(pk);
00219     }
00220   }
00221 
00222   /**
00223    * Remove a <code>CacheEntry</code> object associated to a pk entry.
00224    * 
00225    * @param pk the pk entry
00226    */
00227   public void removePkResultCacheEntry(Object pk)
00228   {
00229     synchronized (pkCacheEntries)
00230     {
00231       ResultCacheEntry rce = (ResultCacheEntry) pkCacheEntries.remove(pk);
00232       rce.invalidate();
00233     }
00234   }
00235 
00236   /**
00237    * Invalidates all cache entries of every column of this table. This does also
00238    * affect the entries based on pk values.
00239    */
00240   public void invalidateAll()
00241   {
00242     synchronized (this)
00243     {
00244       for (Iterator i = cacheEntries.iterator(); i.hasNext();)
00245         ((ResultCacheEntry) i.next()).invalidate();
00246       cacheEntries.clear();
00247 
00248       for (int i = 0; i < columns.size(); i++)
00249         ((CacheDatabaseColumn) columns.get(i)).invalidateAll();
00250     }
00251     synchronized (pkCacheEntries)
00252     { // All pk cache entries have been invalidated as a side effect by the
00253       // above loop.
00254       pkCacheEntries.clear();
00255     }
00256   }
00257 
00258   /**
00259    * Invalidates all cache entries of every column of this table. This does not
00260    * affect the entries based on pk values.
00261    */
00262   public synchronized void invalidateAllExceptPk()
00263   {
00264     for (Iterator i = cacheEntries.iterator(); i.hasNext();)
00265     {
00266       ResultCacheEntry qce = (ResultCacheEntry) i.next();
00267       if (qce.getRequest().getCacheAbility() != RequestType.UNIQUE_CACHEABLE)
00268         qce.invalidate();
00269     }
00270     cacheEntries.clear();
00271   }
00272 
00273   /**
00274    * Returns information about the database table and its columns.
00275    * 
00276    * @param longFormat true for a long format, false for a short summary
00277    * @return String
00278    */
00279   public String getInformation(boolean longFormat)
00280   {
00281     String result = "Table " + name + ": ";
00282     int size = columns.size();
00283     for (int i = 0; i < size; i++)
00284     {
00285       CacheDatabaseColumn c = (CacheDatabaseColumn) columns.get(i);
00286       if (longFormat)
00287         result += "\n";
00288       result += c.getInformation();
00289       if (!longFormat && (i < size - 1))
00290         result += ",";
00291     }
00292     return result;
00293   }
00294 }

Generated on Mon Apr 11 22:01:29 2005 for C-JDBC by  doxygen 1.3.9.1