00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 package org.openmobileis.database.fastobjectdb.db.store;
00030
00031 import java.io.*;
00032
00033 import org.openmobileis.database.fastobjectdb.FastObjectDB;
00034 import org.openmobileis.database.fastobjectdb.db.crypto.FODBCypher;
00035 import org.openmobileis.database.fastobjectdb.db.exception.FODBException;
00036 import org.openmobileis.database.fastobjectdb.db.index.FODBIndexHeader;
00037 import org.openmobileis.database.fastobjectdb.db.index.FODBIndexTable;
00038 import org.openmobileis.database.fastobjectdb.db.index.node.Node;
00039
00040
00047 public class FODBCollectionFile {
00048 private final static int ACTION_CREATE = 0;
00049 private final static int ACTION_OPEN = 1;
00050
00051 private FODBObjectDatabaseFile databaseFile = null;
00052 private FODBCollectionFileHeader header = null;
00053 private FODBIndexTable indexTable = null;
00054 private String collectionFilePath;
00055 private int openCounter = 0;
00056 private FODBCypher collCypher = null;
00057
00068 private FODBCollectionFile (String filePath, Class objType, int action, String colName, FastObjectDB db) throws IOException, ClassNotFoundException {
00069 if (action == ACTION_CREATE) {
00070 File f1 = new File(filePath);
00071 f1.delete();
00072 }
00073
00074 collectionFilePath = filePath;
00075
00076
00077 databaseFile = new FODBObjectDatabaseFile(collectionFilePath);
00078 db.getTransactionManager().registerTransactionFile(databaseFile, colName);
00079 databaseFile.open();
00080 try {
00081 if (action == ACTION_CREATE) {
00082
00083 header = new FODBCollectionFileHeader(objType);
00084 header.setIndexTablePos(Node.NO_NODE);
00085
00086 writeHeader();
00087
00088
00089 indexTable = new FODBIndexTable();
00090 long tablePos = databaseFile.writeObject(indexTable);
00091
00092
00093
00094 header.setIndexTablePos(tablePos);
00095
00096
00097 rewriteHeader();
00098 }
00099 else if (action == ACTION_OPEN) {
00100 header = readHeader();
00101
00102 indexTable = readIndexTable();
00103 }
00104 } finally {
00105
00106
00107 databaseFile.close();
00108 }
00109
00110 }
00111
00112 public boolean isSynchronized() {
00113 return header.isSynchronized();
00114 }
00115
00116
00122 public FODBCypher getCollectionCypher() throws FODBException {
00123 return collCypher;
00124 }
00125
00133 public void setCollectionCypher(FODBCypher cypher) throws FODBException {
00134 if (collCypher != null) throw new FODBException("FODBCollection Cypher already initilazed error.");
00135 collCypher = cypher;
00136 try {
00137 databaseFile.open();
00138 try {
00139 rewriteHeader();
00140 } finally {
00141 databaseFile.close();
00142 }
00143 } catch (Throwable ex) {
00144 throw new FODBException(ex);
00145 }
00146 }
00147
00148 public void setSynchronized(boolean sync) throws IOException, ClassNotFoundException {
00149 header.setSynchronized(sync);
00150 rewriteHeader();
00151 }
00152
00162 public static FODBCollectionFile createCollection (String filePath, Class objType, String colname, FastObjectDB db) throws IOException, ClassNotFoundException {
00163 return new FODBCollectionFile(filePath, objType, ACTION_CREATE, colname, db);
00164 }
00173 public static FODBCollectionFile openCollection (String filePath, String colname, FastObjectDB db) throws IOException, ClassNotFoundException {
00174 File collectionFile = new File(filePath);
00175 if (!collectionFile.exists()) {
00176 return null;
00177 }
00178 return new FODBCollectionFile(filePath, null, ACTION_OPEN, colname, db);
00179 }
00180
00188 public synchronized long addIndex(long indexPos) throws IOException, ClassNotFoundException {
00189 boolean modified;
00190 modified = indexTable.add(indexPos);
00191
00192 rewriteIndexTable(modified);
00193 return indexPos;
00194 }
00195
00204 private synchronized void rewriteIndexTable(boolean bigger) throws IOException, ClassNotFoundException {
00205 if (!bigger) {
00206 databaseFile.seek(header.getIndexTablePos());
00207 databaseFile.rewriteObject(indexTable);
00208 }
00209 else {
00210 deleteObject(header.getIndexTablePos());
00211 long newPos = databaseFile.writeObject(indexTable);
00212 header.setIndexTablePos(newPos);
00213 rewriteHeader();
00214 }
00215 }
00223 public Object readNode(long pos) throws IOException, ClassNotFoundException {
00224 databaseFile.seek(pos);
00225 return databaseFile.readObject();
00226 }
00227
00235 public long writeNode(Object obj) throws IOException, ClassNotFoundException {
00236 return databaseFile.writeObject(obj);
00237 }
00238
00248 public void rewriteNode(Object obj, long pos) throws IOException, ClassNotFoundException {
00249 databaseFile.seek(pos);
00250 databaseFile.rewriteObject(obj);
00251 }
00252
00260 public Object readObject(long pos) throws IOException, ClassNotFoundException {
00261 databaseFile.seek(pos);
00262 if (collCypher == null) {
00263 return databaseFile.readObject();
00264 } else {
00265 byte[]todecrypt = (byte[])databaseFile.readObject();
00266 byte[] decrypted = collCypher.decryptObject(todecrypt);
00267 ByteArrayInputStream bstr = new ByteArrayInputStream(decrypted);
00268 ObjectInputStream ostr = new ObjectInputStream(bstr);
00269 return ostr.readObject();
00270 }
00271 }
00272
00280 public long writeObject(Object obj) throws IOException, ClassNotFoundException {
00281 if (collCypher == null) {
00282 return databaseFile.writeObject(obj);
00283 } else {
00284 ByteArrayOutputStream bstr = new ByteArrayOutputStream();
00285 ObjectOutputStream ostr = new ObjectOutputStream(bstr);
00286 ostr.writeObject(obj);
00287 byte[] toencrypt = bstr.toByteArray();
00288 byte[] encrypted = collCypher.encryptObject(toencrypt);
00289 return databaseFile.writeObject(encrypted);
00290
00291 }
00292 }
00293
00303 public void rewriteObjectt(Object obj, long pos) throws IOException, ClassNotFoundException {
00304 databaseFile.seek(pos);
00305 if (collCypher == null) {
00306 databaseFile.rewriteObject(obj);
00307 } else {
00308 ByteArrayOutputStream bstr = new ByteArrayOutputStream();
00309 ObjectOutputStream ostr = new ObjectOutputStream(bstr);
00310 ostr.writeObject(obj);
00311 byte[] toencrypt = bstr.toByteArray();
00312 byte[] encrypted = collCypher.encryptObject(toencrypt);
00313 databaseFile.rewriteObject(encrypted);
00314
00315 }
00316 }
00317
00324 public void deleteObject(long pos) throws IOException, ClassNotFoundException {
00325 databaseFile.seek(pos);
00326 databaseFile.delete();
00327 }
00328
00334 public void writeHeader() throws IOException, ClassNotFoundException {
00335 databaseFile.rewind();
00336 databaseFile.writeObject(header);
00337 }
00338
00339 public void rewriteHeader() throws IOException, ClassNotFoundException {
00340 databaseFile.rewind();
00341 databaseFile.rewriteObject(header);
00342 }
00343
00351 public FODBCollectionFileHeader readHeader() throws IOException, ClassNotFoundException {
00352 databaseFile.rewind();
00353 return (FODBCollectionFileHeader)databaseFile.readObject();
00354 }
00355
00362 private FODBIndexTable readIndexTable() throws IOException, ClassNotFoundException {
00363 databaseFile.seek(header.getIndexTablePos());
00364 return (FODBIndexTable)databaseFile.readObject();
00365 }
00366
00367 public Class getObjectType() {
00368 return header.getObjectType();
00369 }
00370
00378 public FODBIndexHeader[] getIndexsHeaders() throws IOException, ClassNotFoundException {
00379 FODBIndexHeader[] headers;
00380 int numHeaders = indexTable.size();
00381
00382 if (numHeaders <= 0) {
00383 return null;
00384 }
00385 headers = new FODBIndexHeader[numHeaders];
00386
00387 for (int i = 0; i < numHeaders; i++) {
00388 long pos = indexTable.getPosByPlace(i);
00389 databaseFile.seek(pos);
00390 headers[i] = (FODBIndexHeader)databaseFile.readObject();
00391 }
00392 return headers;
00393 }
00394
00398 public String toString() {
00399 String result = " FODBCollectionFile[" + collectionFilePath + ", " + openCounter + "]\n";
00400 result = result.concat("" + header + "\n");
00401 result = result.concat("" + indexTable);
00402 return result;
00403 }
00404
00405 }