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         }
00225         
00233         public Object readNode(long pos) throws IOException, ClassNotFoundException {
00234                 databaseFile.seek(pos);
00235                 return databaseFile.readObject();
00236         }
00237         
00245         public long writeNode(Object obj) throws IOException, ClassNotFoundException  {
00246                 return databaseFile.writeObject(obj);
00247         }       
00248         
00258         public void rewriteNode(Object obj, long pos) throws IOException, ClassNotFoundException  {
00259                 databaseFile.seek(pos);
00260                 databaseFile.rewriteObject(obj);
00261         }
00262         
00270   public Object readObject(long pos) throws IOException, ClassNotFoundException {
00271     databaseFile.seek(pos);
00272     if (collCypher == null) {
00273       ByteArrayInputStream bstr = new ByteArrayInputStream((byte[])databaseFile.readObject());
00274       ObjectInputStream objstr;
00275       if (header.getDescriptor().isCompressed()) {
00276         GZIPInputStream gzstr = new GZIPInputStream(bstr);
00277         objstr = new ObjectInputStream(gzstr);
00278       } else {
00279         objstr = new ObjectInputStream(bstr);
00280       }
00281       return objstr.readObject();
00282     } else  {
00283       byte[]todecrypt = (byte[])databaseFile.readObject();
00284       byte[] decrypted = collCypher.decryptObject(todecrypt);
00285       ByteArrayInputStream bstr = new ByteArrayInputStream(decrypted);
00286       ObjectInputStream objstr;
00287       if (header.getDescriptor().isCompressed()) {
00288         GZIPInputStream gzstr = new GZIPInputStream(bstr);
00289         objstr = new ObjectInputStream(gzstr);
00290       } else {
00291         objstr = new ObjectInputStream(bstr);
00292       }
00293       return objstr.readObject();
00294     }
00295   }
00296         
00304   public long writeObject(Object obj) throws IOException, ClassNotFoundException  {
00305     if (collCypher == null) {
00306       ByteArrayOutputStream bstr = new ByteArrayOutputStream();
00307       ObjectOutputStream objstr;
00308       if (header.getDescriptor().isCompressed()) {
00309         GZIPOutputStream gzstr = new GZIPOutputStream(bstr);
00310         objstr = new ObjectOutputStream(gzstr);
00311       } else {
00312         objstr = new ObjectOutputStream(bstr);
00313       }
00314       objstr.writeObject(obj);
00315       objstr.flush();
00316       objstr.close();
00317       return databaseFile.writeObject(bstr.toByteArray());
00318     } else  {
00319       ByteArrayOutputStream bstr = new ByteArrayOutputStream();
00320       ObjectOutputStream objstr;
00321       if (header.getDescriptor().isCompressed()) {
00322         GZIPOutputStream gzstr = new GZIPOutputStream(bstr);
00323         objstr = new ObjectOutputStream(gzstr);
00324       } else {
00325         objstr = new ObjectOutputStream(bstr);
00326       }
00327       objstr.writeObject(obj);
00328       objstr.flush();
00329       objstr.close();
00330       byte[] toencrypt = bstr.toByteArray();
00331       byte[] encrypted = collCypher.encryptObject(toencrypt);
00332       return databaseFile.writeObject(encrypted);
00333       
00334     }
00335   }
00336         
00346         public void rewriteObjectt(Object obj, long pos) throws IOException, ClassNotFoundException  {
00347                 databaseFile.seek(pos);
00348                 if (collCypher == null) {
00349                         databaseFile.rewriteObject(obj);
00350                 } else  {
00351                         ByteArrayOutputStream bstr = new ByteArrayOutputStream();
00352                         ObjectOutputStream ostr = new ObjectOutputStream(bstr);
00353                         ostr.writeObject(obj);
00354                         byte[] toencrypt = bstr.toByteArray();
00355                         byte[] encrypted = collCypher.encryptObject(toencrypt);
00356                         databaseFile.rewriteObject(encrypted);
00357                         
00358                 }
00359         }
00360         
00367         public void deleteObject(long pos) throws IOException, ClassNotFoundException  {
00368                                 databaseFile.seek(pos);
00369                                 databaseFile.delete();
00370         }
00371         
00377         public void writeHeader() throws IOException, ClassNotFoundException  {
00378                                 databaseFile.rewind();
00379                                 databaseFile.writeObject(header);
00380         }
00381         
00382         public void rewriteHeader() throws IOException, ClassNotFoundException  {
00383                                 databaseFile.rewind();
00384                                 databaseFile.rewriteObject(header);
00385         }
00386         
00394         public FODBCollectionFileHeader readHeader()  throws IOException, ClassNotFoundException  {
00395                                 databaseFile.rewind();
00396                                 return (FODBCollectionFileHeader)databaseFile.readObject();
00397         }
00398         
00405         private FODBIndexTable readIndexTable() throws IOException, ClassNotFoundException {
00406                 databaseFile.seek(header.getIndexTablePos());
00407                 return (FODBIndexTable)databaseFile.readObject();
00408         }
00409         
00410         public Class getObjectType() {
00411                 return header.getObjectType();
00412         }
00413         
00421         public FODBIndexHeader[] getIndexsHeaders() throws IOException, ClassNotFoundException {
00422                 FODBIndexHeader[] headers;
00423                         int numHeaders = indexTable.size();
00424 
00425                         if (numHeaders <= 0) {
00426                                 return null;
00427                         }
00428                         headers = new FODBIndexHeader[numHeaders];
00429                         
00430                         for (int i = 0; i < numHeaders; i++) {
00431                                 long pos = indexTable.getPosByPlace(i);
00432                                 databaseFile.seek(pos);
00433                                 headers[i] = (FODBIndexHeader)databaseFile.readObject();
00434                         }
00435                 return headers;
00436         }
00437         
00438   public FODBCollectionDescriptor getDescriptor() {
00439     return header.getDescriptor();
00440   }
00441 
00445         public String toString() {
00446                 String result = "     FODBCollectionFile[" + collectionFilePath + ", " + openCounter + "]\n";
00447                 result = result.concat("" + header + "\n");
00448                 result = result.concat("" + indexTable);
00449                 return result;
00450         }
00451 
00452         public String getCollectionFilePath() {
00453                 return collectionFilePath;
00454         }
00455         
00456 }

Generated on Mon Jan 11 21:19:14 2010 for OpenMobileIS by  doxygen 1.5.4