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.cs.messages;
022:
023: import com.db4o.*;
024: import com.db4o.foundation.*;
025: import com.db4o.foundation.network.*;
026: import com.db4o.internal.*;
027: import com.db4o.internal.cs.*;
028:
029: /**
030: * Messages for Client/Server Communication
031: */
032: public abstract class Msg implements Cloneable {
033:
034: static int _messageIdGenerator = 1;
035: private static Msg[] _messages = new Msg[70];
036:
037: int _msgID;
038: String _name;
039: private Transaction _trans;
040: private MessageDispatcher _messageDispatcher;
041:
042: public static final MRuntimeException RUNTIME_EXCEPTION = new MRuntimeException();
043: public static final MClassID CLASS_ID = new MClassID();
044: public static final MClassMetadataIdForName CLASS_METADATA_ID_FOR_NAME = new MClassMetadataIdForName();
045: public static final MClassNameForID CLASS_NAME_FOR_ID = new MClassNameForID();
046: public static final MClose CLOSE = new MClose();
047: public static final MCloseSocket CLOSE_SOCKET = new MCloseSocket();
048: public static final MCommit COMMIT = new MCommit();
049: public static final MCommittedCallBackRegistry COMMITTED_CALLBACK_REGISTER = new MCommittedCallBackRegistry();
050: public static final MCommittedInfo COMMITTED_INFO = new MCommittedInfo();
051: public static final MCommitSystemTransaction COMMIT_SYSTEMTRANS = new MCommitSystemTransaction();
052: public static final MCreateClass CREATE_CLASS = new MCreateClass();
053: public static final MClassMeta CLASS_META = new MClassMeta();
054: public static final MVersion CURRENT_VERSION = new MVersion();
055: public static final MDelete DELETE = new MDelete();
056: public static final MError ERROR = new MError();
057: public static final MFailed FAILED = new MFailed();
058: public static final MGetAll GET_ALL = new MGetAll();
059: public static final MGetClasses GET_CLASSES = new MGetClasses();
060: public static final MGetInternalIDs GET_INTERNAL_IDS = new MGetInternalIDs();
061: public static final MGetThreadID GET_THREAD_ID = new MGetThreadID();
062: public static final MIDList ID_LIST = new MIDList();
063: public static final MIdentity IDENTITY = new MIdentity();
064: public static final MIsAlive IS_ALIVE = new MIsAlive();
065: public static final MLength LENGTH = new MLength();
066: public static final MLogin LOGIN = new MLogin();
067: public static final MLoginOK LOGIN_OK = new MLoginOK();
068: public static final MNull NULL = new MNull();
069: public static final MObjectByUuid OBJECT_BY_UUID = new MObjectByUuid();
070: public static final MsgObject OBJECT_TO_CLIENT = new MsgObject();
071: public static final MObjectSetFetch OBJECTSET_FETCH = new MObjectSetFetch();
072: public static final MObjectSetFinalized OBJECTSET_FINALIZED = new MObjectSetFinalized();
073: public static final MObjectSetGetId OBJECTSET_GET_ID = new MObjectSetGetId();
074: public static final MObjectSetIndexOf OBJECTSET_INDEXOF = new MObjectSetIndexOf();
075: public static final MObjectSetReset OBJECTSET_RESET = new MObjectSetReset();
076: public static final MObjectSetSize OBJECTSET_SIZE = new MObjectSetSize();
077: public static final MOK OK = new MOK();
078: public static final MPing PING = new MPing();
079: public static final MPong PONG = new MPong();
080: public static final MPrefetchIDs PREFETCH_IDS = new MPrefetchIDs();
081: public static final MProcessDeletes PROCESS_DELETES = new MProcessDeletes();
082: public static final MQueryExecute QUERY_EXECUTE = new MQueryExecute();
083: public static final MQueryResult QUERY_RESULT = new MQueryResult();
084: public static final MRaiseVersion RAISE_VERSION = new MRaiseVersion();
085: public static final MReadBlob READ_BLOB = new MReadBlob();
086: public static final MReadBytes READ_BYTES = new MReadBytes();
087: public static final MReadMultipleObjects READ_MULTIPLE_OBJECTS = new MReadMultipleObjects();
088: public static final MReadObject READ_OBJECT = new MReadObject();
089: public static final MReleaseSemaphore RELEASE_SEMAPHORE = new MReleaseSemaphore();
090: public static final MRollback ROLLBACK = new MRollback();
091: public static final MSetSemaphore SET_SEMAPHORE = new MSetSemaphore();
092: public static final MSuccess SUCCESS = new MSuccess();
093: public static final MSwitchToFile SWITCH_TO_FILE = new MSwitchToFile();
094: public static final MSwitchToMainFile SWITCH_TO_MAIN_FILE = new MSwitchToMainFile();
095: public static final MTaDelete TA_DELETE = new MTaDelete();
096: public static final MTaIsDeleted TA_IS_DELETED = new MTaIsDeleted();
097: public static final MUserMessage USER_MESSAGE = new MUserMessage();
098: public static final MUseTransaction USE_TRANSACTION = new MUseTransaction();
099: public static final MWriteBlob WRITE_BLOB = new MWriteBlob();
100: public static final MWriteNew WRITE_NEW = new MWriteNew();
101: public static final MWriteUpdate WRITE_UPDATE = new MWriteUpdate();
102: public static final MWriteUpdateDeleteMembers WRITE_UPDATE_DELETE_MEMBERS = new MWriteUpdateDeleteMembers();
103: public static final MWriteBatchedMessages WRITE_BATCHED_MESSAGES = new MWriteBatchedMessages();
104: public static final MsgBlob DELETE_BLOB_FILE = new MDeleteBlobFile();
105:
106: Msg() {
107: _msgID = _messageIdGenerator++;
108: _messages[_msgID] = this ;
109: }
110:
111: Msg(String aName) {
112: this ();
113: _name = aName;
114: }
115:
116: public static Msg getMessage(int id) {
117: return _messages[id];
118: }
119:
120: public final Msg publicClone() {
121: try {
122: return (Msg) clone();
123: } catch (CloneNotSupportedException e) {
124: Exceptions4.shouldNeverHappen();
125: return null;
126: }
127: }
128:
129: public final boolean equals(Object obj) {
130: if (this == obj) {
131: return true;
132: }
133: if (obj == null || obj.getClass() != this .getClass()) {
134: return false;
135: }
136: return _msgID == ((Msg) obj)._msgID;
137: }
138:
139: public int hashCode() {
140:
141: return _msgID;
142: }
143:
144: /**
145: * dummy method to allow clean override handling
146: * without casting
147: */
148: public Buffer getByteLoad() {
149: return null;
150: }
151:
152: final String getName() {
153: if (_name == null) {
154: return getClass().getName();
155: }
156: return _name;
157: }
158:
159: protected LocalTransaction serverTransaction() {
160: return (LocalTransaction) _trans;
161: }
162:
163: protected Transaction transaction() {
164: return _trans;
165: }
166:
167: protected LocalObjectContainer file() {
168: return (LocalObjectContainer) stream();
169: }
170:
171: protected ObjectContainerBase stream() {
172: return transaction().container();
173: }
174:
175: protected Object streamLock() {
176: return stream().lock();
177: }
178:
179: protected Config4Impl config() {
180: return stream().config();
181: }
182:
183: protected static StatefulBuffer readMessageBuffer(
184: Transaction trans, Socket4 sock) throws Db4oIOException {
185: return readMessageBuffer(trans, sock, Const4.MESSAGE_LENGTH);
186: }
187:
188: protected static StatefulBuffer readMessageBuffer(
189: Transaction trans, Socket4 sock, int length)
190: throws Db4oIOException {
191: StatefulBuffer buffer = new StatefulBuffer(trans, length);
192: int offset = 0;
193: while (length > 0) {
194: int read = sock.read(buffer._buffer, offset, length);
195: if (read < 0) {
196: throw new Db4oIOException();
197: }
198: offset += read;
199: length -= read;
200: }
201: return buffer;
202: }
203:
204: public static final Msg readMessage(
205: MessageDispatcher messageDispatcher, Transaction trans,
206: Socket4 sock) throws Db4oIOException {
207: StatefulBuffer reader = readMessageBuffer(trans, sock);
208: Msg message = _messages[reader.readInt()].readPayLoad(
209: messageDispatcher, trans, sock, reader);
210: if (Debug.messages) {
211: System.out.println(message + " arrived at "
212: + trans.container());
213: }
214: return message;
215: }
216:
217: /** @param sock */
218: Msg readPayLoad(MessageDispatcher messageDispatcher,
219: Transaction a_trans, Socket4 sock, Buffer reader) {
220: Msg msg = publicClone();
221: msg.setMessageDispatcher(messageDispatcher);
222: msg.setTransaction(checkParentTransaction(a_trans, reader));
223: return msg;
224: }
225:
226: protected final Transaction checkParentTransaction(
227: Transaction a_trans, Buffer reader) {
228: if (reader.readByte() == Const4.SYSTEM_TRANS
229: && a_trans.parentTransaction() != null) {
230: return a_trans.parentTransaction();
231: }
232: return a_trans;
233: }
234:
235: public final void setTransaction(Transaction aTrans) {
236: _trans = aTrans;
237: }
238:
239: final public String toString() {
240: return getName();
241: }
242:
243: public void write(Msg msg) {
244: _messageDispatcher.write(msg);
245: }
246:
247: public void writeException(RuntimeException e) {
248: write(RUNTIME_EXCEPTION.getWriterForSingleObject(transaction(),
249: e));
250: }
251:
252: public void respondInt(int response) {
253: write(ID_LIST.getWriterForInt(transaction(), response));
254: }
255:
256: public boolean write(Socket4 sock) {
257: if (null == sock) {
258: throw new ArgumentNullException();
259: }
260: synchronized (sock) {
261: try {
262: if (Debug.messages) {
263: System.out.println(this + " sent by "
264: + Thread.currentThread().getName());
265: }
266: sock.write(payLoad()._buffer);
267: sock.flush();
268: return true;
269: } catch (Exception e) {
270:
271: // TODO: .NET convert SocketException to Db4oIOException
272: // and let Db4oIOException bubble up.
273: //e.printStackTrace();
274:
275: return false;
276: }
277: }
278: }
279:
280: public StatefulBuffer payLoad() {
281: StatefulBuffer writer = new StatefulBuffer(transaction(),
282: Const4.MESSAGE_LENGTH);
283: writer.writeInt(_msgID);
284: return writer;
285: }
286:
287: public MessageDispatcher messageDispatcher() {
288: return _messageDispatcher;
289: }
290:
291: public ServerMessageDispatcher serverMessageDispatcher() {
292: if (_messageDispatcher instanceof ServerMessageDispatcher) {
293: return (ServerMessageDispatcher) _messageDispatcher;
294: }
295: throw new IllegalStateException();
296: }
297:
298: public ClientMessageDispatcher clientMessageDispatcher() {
299: if (_messageDispatcher instanceof ClientMessageDispatcher) {
300: return (ClientMessageDispatcher) _messageDispatcher;
301: }
302: throw new IllegalStateException();
303: }
304:
305: public void setMessageDispatcher(MessageDispatcher messageDispatcher) {
306: _messageDispatcher = messageDispatcher;
307: }
308:
309: public void logMsg(int msgCode, String msg) {
310: stream().logMsg(msgCode, msg);
311: }
312:
313: }
|