FODBCollectionFile.java

00001 /*
00002  * OpenMobileIS - a free Java(TM) Framework for mobile applications Java(TM)
00003  * Copyright (C) 2004-2006 Philippe Delrieu
00004  * All rights reserved.
00005  * Contact: pdelrieu@openmobileis.org
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00020  * USA
00021  *
00022  *  Author : Philippe Delrieu
00023  *  
00024  *  Modifications :
00025  *  2004 Creation P.Delrieu
00026  *  2004 Modified by Romain Beaugrand
00027  * 
00028  */
00029 package org.openmobileis.database.fastobjectdb.db.store;
00030 
00031 import java.io.*;
00032 import java.util.zip.GZIPInputStream;
00033 import java.util.zip.GZIPOutputStream;
00034 
00035 import org.openmobileis.database.fastobjectdb.FODBCollectionDescriptor;
00036 import org.openmobileis.database.fastobjectdb.FastObjectDB;
00037 import org.openmobileis.database.fastobjectdb.db.crypto.FODBCypher;
00038 import org.openmobileis.database.fastobjectdb.db.exception.FODBException;
00039 import org.openmobileis.database.fastobjectdb.db.index.FODBIndexHeader;
00040 import org.openmobileis.database.fastobjectdb.db.index.FODBIndexTable;
00041 import org.openmobileis.database.fastobjectdb.db.index.node.Node;
00042 
00043 
00050 public class FODBCollectionFile {
00051         private final static int ACTION_CREATE = 0;
00052         private final static int ACTION_OPEN = 1;
00053         
00054         private FODBObjectDatabaseFile databaseFile = null;
00055         private FODBCollectionFileHeader header = null;
00056         private FODBIndexTable indexTable = null;
00057         private String collectionFilePath;
00058         private int openCounter = 0;
00059         private FODBCypher collCypher = null;
00060         
00071         private FODBCollectionFile (String filePath, FODBCollectionDescriptor descriptor, int action, FastObjectDB db) throws IOException, ClassNotFoundException {
00072                 if (action == ACTION_CREATE) {
00073                         File f1 = new File(filePath);
00074                         f1.delete();
00075                 }
00076                 
00077                 collectionFilePath = filePath;
00078                 
00079                 // Let's open our file (or create it if it doesn't exist)
00080                 databaseFile = new FODBObjectDatabaseFile(collectionFilePath);
00081                 db.getTransactionManager().registerTransactionFile(databaseFile, descriptor.getCollectionName());
00082                 databaseFile.open();
00083                 try     {
00084                         if (action == ACTION_CREATE) {
00085                                 // create and write header
00086                                 header = new FODBCollectionFileHeader(descriptor);
00087                                 header.setIndexTablePos(Node.NO_NODE);
00088         
00089                                 writeHeader();
00090                                                         
00091                                 // create and write indexTable
00092                                 indexTable = new FODBIndexTable();
00093                                 long tablePos = databaseFile.writeObject(indexTable);
00094         
00095                                 
00096                                 // set indexTable's pos in the header
00097                                 header.setIndexTablePos(tablePos);
00098                                 
00099                                 // rewrite header
00100                                 rewriteHeader();
00101                         }
00102                         else if (action == ACTION_OPEN) {
00103                                 header = readHeader();
00104                                 
00105                                 indexTable = readIndexTable();
00106                         }
00107                 } finally       {
00108         
00109                         // We read or wrote our datas, let's close the file.            
00110                         databaseFile.close();
00111                 }
00112 
00113         }
00114         
00115         public boolean isSynchronized() {
00116                 return header.getDescriptor().isSynchronize();
00117         }
00118 
00119 
00125         public FODBCypher getCollectionCypher() throws FODBException    {
00126                 return collCypher;
00127         }
00128   
00136   public boolean isCompressed() {
00137     return header.getDescriptor().isCompressed();
00138   }
00139  
00147         public void setCollectionCypher(FODBCypher cypher) throws FODBException {
00148                 if (collCypher != null) throw new FODBException("FODBCollection Cypher already initilazed error.");
00149                 collCypher = cypher;
00150                 try     {
00151                         databaseFile.open();
00152                         try     {
00153                                 rewriteHeader();
00154                         } finally       {
00155                                 databaseFile.close();
00156                         }
00157                 } catch (Throwable ex)  {
00158                         throw new FODBException(ex);
00159                 }
00160         }
00161         
00171         public static FODBCollectionFile createCollection (String filePath, FODBCollectionDescriptor descriptor, FastObjectDB db) throws IOException, ClassNotFoundException    {
00172                 return new FODBCollectionFile(filePath, descriptor, ACTION_CREATE, db);
00173         }
00182         public static FODBCollectionFile openCollection (String filePath, String colname, FastObjectDB db) throws IOException, ClassNotFoundException {
00183                 File collectionFile = new File(filePath);
00184                 if (!collectionFile.exists()) {
00185                         return null;
00186                 }
00187                 return new FODBCollectionFile(filePath, new FODBCollectionDescriptor(colname, null), ACTION_OPEN, db);
00188         }
00189         
00197         public synchronized long addIndex(long indexPos)  throws IOException, ClassNotFoundException  {
00198                 boolean modified;
00199                 modified = indexTable.add(indexPos);
00200                 
00201                 rewriteIndexTable(modified);
00202                 return indexPos;
00203         }
00204         
00213         private synchronized void rewriteIndexTable(boolean bigger)  throws IOException, ClassNotFoundException  {
00214                 if (!bigger) {
00215                         databaseFile.seek(header.getIndexTablePos());
00216                         databaseFile.rewriteObject(indexTable);
00217                 }
00218                 else {
00219                                 deleteObject(header.getIndexTablePos());
00220                                 long newPos = databaseFile.writeObject(indexTable);
00221                                 header.setIndexTablePos(newPos);
00222                                 rewriteHeader();
00223                 }
00224         }
00232         public Object readNode(long pos) throws IOException, ClassNotFoundException {
00233                 databaseFile.seek(pos);
00234                 return databaseFile.readObject();
00235         }
00236         
00244         public long writeNode(Object obj) throws IOException, ClassNotFoundException  {
00245                 return databaseFile.writeObject(obj);
00246         }       
00247         
00257         public void rewriteNode(Object obj, long pos) throws IOException, ClassNotFoundException  {
00258                 databaseFile.seek(pos);
00259                 databaseFile.rewriteObject(obj);
00260         }
00261         
00269   public Object readObject(long pos) throws IOException, ClassNotFoundException {
00270     databaseFile.seek(pos);
00271     if (collCypher == null) {
00272       ByteArrayInputStream bstr = new ByteArrayInputStream((byte[])databaseFile.readObject());
00273       ObjectInputStream objstr;
00274       if (header.getDescriptor().isCompressed()) {
00275         GZIPInputStream gzstr = new GZIPInputStream(bstr);
00276         objstr = new ObjectInputStream(gzstr);
00277       } else {
00278         objstr = new ObjectInputStream(bstr);
00279       }
00280       return objstr.readObject();
00281     } else  {
00282       byte[]todecrypt = (byte[])databaseFile.readObject();
00283       byte[] decrypted = collCypher.decryptObject(todecrypt);
00284       ByteArrayInputStream bstr = new ByteArrayInputStream(decrypted);
00285       ObjectInputStream objstr;
00286       if (header.getDescriptor().isCompressed()) {
00287         GZIPInputStream gzstr = new GZIPInputStream(bstr);
00288         objstr = new ObjectInputStream(gzstr);
00289       } else {
00290         objstr = new ObjectInputStream(bstr);
00291       }
00292       return objstr.readObject();
00293     }
00294   }
00295         
00303   public long writeObject(Object obj) throws IOException, ClassNotFoundException  {
00304     if (collCypher == null) {
00305       ByteArrayOutputStream bstr = new ByteArrayOutputStream();
00306       ObjectOutputStream objstr;
00307       if (header.getDescriptor().isCompressed()) {
00308         GZIPOutputStream gzstr = new GZIPOutputStream(bstr);
00309         objstr = new ObjectOutputStream(gzstr);
00310       } else {
00311         objstr = new ObjectOutputStream(bstr);
00312       }
00313       objstr.writeObject(obj);
00314       objstr.flush();
00315       objstr.close();
00316       return databaseFile.writeObject(bstr.toByteArray());
00317     } else  {
00318       ByteArrayOutputStream bstr = new ByteArrayOutputStream();
00319       ObjectOutputStream objstr;
00320       if (header.getDescriptor().isCompressed()) {
00321         GZIPOutputStream gzstr = new GZIPOutputStream(bstr);
00322         objstr = new ObjectOutputStream(gzstr);
00323       } else {
00324         objstr = new ObjectOutputStream(bstr);
00325       }
00326       objstr.writeObject(obj);
00327       objstr.flush();
00328       objstr.close();
00329       byte[] toencrypt = bstr.toByteArray();
00330       byte[] encrypted = collCypher.encryptObject(toencrypt);
00331       return databaseFile.writeObject(encrypted);
00332       
00333     }
00334   }
00335         
00345         public void rewriteObjectt(Object obj, long pos) throws IOException, ClassNotFoundException  {
00346                 databaseFile.seek(pos);
00347                 if (collCypher == null) {
00348                         databaseFile.rewriteObject(obj);
00349                 } else  {
00350                         ByteArrayOutputStream bstr = new ByteArrayOutputStream();
00351                         ObjectOutputStream ostr = new ObjectOutputStream(bstr);
00352                         ostr.writeObject(obj);
00353                         byte[] toencrypt = bstr.toByteArray();
00354                         byte[] encrypted = collCypher.encryptObject(toencrypt);
00355                         databaseFile.rewriteObject(encrypted);
00356                         
00357                 }
00358         }
00359         
00366         public void deleteObject(long pos) throws IOException, ClassNotFoundException  {
00367                                 databaseFile.seek(pos);
00368                                 databaseFile.delete();
00369         }
00370         
00376         public void writeHeader() throws IOException, ClassNotFoundException  {
00377                                 databaseFile.rewind();
00378                                 databaseFile.writeObject(header);
00379         }
00380         
00381         public void rewriteHeader() throws IOException, ClassNotFoundException  {
00382                                 databaseFile.rewind();
00383                                 databaseFile.rewriteObject(header);
00384         }
00385         
00393         public FODBCollectionFileHeader readHeader()  throws IOException, ClassNotFoundException  {
00394                                 databaseFile.rewind();
00395                                 return (FODBCollectionFileHeader)databaseFile.readObject();
00396         }
00397         
00404         private FODBIndexTable readIndexTable() throws IOException, ClassNotFoundException {
00405                 databaseFile.seek(header.getIndexTablePos());
00406                 return (FODBIndexTable)databaseFile.readObject();
00407         }
00408         
00409         public Class getObjectType() {
00410                 return header.getObjectType();
00411         }
00412         
00420         public FODBIndexHeader[] getIndexsHeaders() throws IOException, ClassNotFoundException {
00421                 FODBIndexHeader[] headers;
00422                         int numHeaders = indexTable.size();
00423 
00424                         if (numHeaders <= 0) {
00425                                 return null;
00426                         }
00427                         headers = new FODBIndexHeader[numHeaders];
00428                         
00429                         for (int i = 0; i < numHeaders; i++) {
00430                                 long pos = indexTable.getPosByPlace(i);
00431                                 databaseFile.seek(pos);
00432                                 headers[i] = (FODBIndexHeader)databaseFile.readObject();
00433                         }
00434                 return headers;
00435         }
00436         
00437   public FODBCollectionDescriptor getDescriptor() {
00438     return header.getDescriptor();
00439   }
00440 
00444         public String toString() {
00445                 String result = "     FODBCollectionFile[" + collectionFilePath + ", " + openCounter + "]\n";
00446                 result = result.concat("" + header + "\n");
00447                 result = result.concat("" + indexTable);
00448                 return result;
00449         }
00450         
00451 }

Generated on Mon Dec 4 11:03:26 2006 for OpenMobileIS by  doxygen 1.5.1-p1