001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.internal.fileheader;
022:
023: import com.db4o.*;
024: import com.db4o.ext.OldFormatException;
025: import com.db4o.internal.*;
026:
027: /**
028: * @exclude
029: */
030: public abstract class FileHeader {
031:
032: private static final FileHeader[] AVAILABLE_FILE_HEADERS = new FileHeader[] {
033: new FileHeader0(), new FileHeader1() };
034:
035: private static int readerLength() {
036: int length = AVAILABLE_FILE_HEADERS[0].length();
037: for (int i = 1; i < AVAILABLE_FILE_HEADERS.length; i++) {
038: length = Math.max(length, AVAILABLE_FILE_HEADERS[i]
039: .length());
040: }
041: return length;
042: }
043:
044: public static FileHeader readFixedPart(LocalObjectContainer file)
045: throws OldFormatException {
046: Buffer reader = prepareFileHeaderReader(file);
047: FileHeader header = detectFileHeader(file, reader);
048: if (header == null) {
049: Exceptions4
050: .throwRuntimeException(Messages.INCOMPATIBLE_FORMAT);
051: } else {
052: header.readFixedPart(file, reader);
053: }
054: return header;
055: }
056:
057: private static Buffer prepareFileHeaderReader(
058: LocalObjectContainer file) {
059: Buffer reader = new Buffer(readerLength());
060: reader.read(file, 0, 0);
061: return reader;
062: }
063:
064: private static FileHeader detectFileHeader(
065: LocalObjectContainer file, Buffer reader) {
066: for (int i = 0; i < AVAILABLE_FILE_HEADERS.length; i++) {
067: reader.seek(0);
068: FileHeader result = AVAILABLE_FILE_HEADERS[i]
069: .newOnSignatureMatch(file, reader);
070: if (result != null) {
071: return result;
072: }
073: }
074: return null;
075: }
076:
077: public abstract void close() throws Db4oIOException;
078:
079: public abstract void initNew(LocalObjectContainer file)
080: throws Db4oIOException;
081:
082: public abstract Transaction interruptedTransaction();
083:
084: public abstract int length();
085:
086: protected abstract FileHeader newOnSignatureMatch(
087: LocalObjectContainer file, Buffer reader);
088:
089: protected long timeToWrite(long time, boolean shuttingDown) {
090: return shuttingDown ? 0 : time;
091: }
092:
093: protected abstract void readFixedPart(LocalObjectContainer file,
094: Buffer reader);
095:
096: public abstract void readVariablePart(LocalObjectContainer file);
097:
098: protected boolean signatureMatches(Buffer reader, byte[] signature,
099: byte version) {
100: for (int i = 0; i < signature.length; i++) {
101: if (reader.readByte() != signature[i]) {
102: return false;
103: }
104: }
105: return reader.readByte() == version;
106: }
107:
108: // TODO: freespaceID should not be passed here, it should be taken from SystemData
109: public abstract void writeFixedPart(LocalObjectContainer file,
110: boolean startFileLockingThread, boolean shuttingDown,
111: StatefulBuffer writer, int blockSize, int freespaceID);
112:
113: public abstract void writeTransactionPointer(
114: Transaction systemTransaction, int transactionAddress);
115:
116: protected void writeTransactionPointer(
117: Transaction systemTransaction, int transactionAddress,
118: final int address, final int offset) {
119: StatefulBuffer bytes = new StatefulBuffer(systemTransaction,
120: address, Const4.INT_LENGTH * 2);
121: bytes.moveForward(offset);
122: bytes.writeInt(transactionAddress);
123: bytes.writeInt(transactionAddress);
124: if (Debug.xbytes && Deploy.overwrite) {
125: bytes.setID(Const4.IGNORE_ID);
126: }
127: bytes.write();
128: }
129:
130: public abstract void writeVariablePart(LocalObjectContainer file,
131: int part);
132:
133: protected void readClassCollectionAndFreeSpace(
134: LocalObjectContainer file, Buffer reader) {
135: SystemData systemData = file.systemData();
136: systemData.classCollectionID(reader.readInt());
137: systemData.freespaceID(reader.readInt());
138: }
139:
140: public static boolean lockedByOtherSession(
141: LocalObjectContainer container, long lastAccessTime) {
142: return container.needsLockFileThread() && (lastAccessTime != 0);
143: }
144:
145: }
|