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 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
00080 databaseFile = new FODBObjectDatabaseFile(collectionFilePath);
00081 db.getTransactionManager().registerTransactionFile(databaseFile, descriptor.getCollectionName());
00082 databaseFile.open();
00083 try {
00084 if (action == ACTION_CREATE) {
00085
00086 header = new FODBCollectionFileHeader(descriptor);
00087 header.setIndexTablePos(Node.NO_NODE);
00088
00089 writeHeader();
00090
00091
00092 indexTable = new FODBIndexTable();
00093 long tablePos = databaseFile.writeObject(indexTable);
00094
00095
00096
00097 header.setIndexTablePos(tablePos);
00098
00099
00100 rewriteHeader();
00101 }
00102 else if (action == ACTION_OPEN) {
00103 header = readHeader();
00104
00105 indexTable = readIndexTable();
00106 }
00107 } finally {
00108
00109
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 }