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 }
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 }