001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.net.protocol.transport;
005:
006: import com.tc.bytes.TCByteBuffer;
007: import com.tc.io.TCByteBufferInputStream;
008: import com.tc.net.core.TCConnection;
009: import com.tc.net.protocol.TCNetworkHeader;
010: import com.tc.net.protocol.TCProtocolException;
011: import com.tc.util.Assert;
012:
013: import java.io.IOException;
014:
015: class TransportHandshakeMessageImpl extends WireProtocolMessageImpl
016: implements SynMessage, SynAckMessage, AckMessage {
017: static final byte VERSION_1 = 1;
018:
019: static final byte SYN = 1;
020: static final byte ACK = 2;
021: static final byte SYN_ACK = 3;
022:
023: private final byte version;
024: private final byte type;
025: private final ConnectionID connectionId;
026: private final String errorContext;
027: private final boolean hasErrorContext;
028: private final int maxConnections;
029: private final boolean isMaxConnectionsExceeded;
030:
031: TransportHandshakeMessageImpl(TCConnection source,
032: TCNetworkHeader header, TCByteBuffer[] payload)
033: throws TCProtocolException {
034: super (source, header, payload);
035:
036: try {
037: TCByteBufferInputStream in = new TCByteBufferInputStream(
038: payload);
039: this .version = in.readByte();
040:
041: if (version != VERSION_1) {
042: throw new TCProtocolException("Bad Version: " + version
043: + " != " + VERSION_1);
044: }
045:
046: this .type = in.readByte();
047:
048: try {
049: this .connectionId = ConnectionID.parse(in.readString());
050: } catch (InvalidConnectionIDException e) {
051: throw new TCProtocolException(e);
052: }
053:
054: this .isMaxConnectionsExceeded = in.readBoolean();
055: this .maxConnections = in.readInt();
056: this .hasErrorContext = in.readBoolean();
057:
058: if (this .hasErrorContext) {
059: this .errorContext = in.readString();
060: } else {
061: this .errorContext = null;
062: }
063:
064: } catch (IOException e) {
065: throw new TCProtocolException("IOException reading data: "
066: + e.getMessage());
067: }
068: }
069:
070: public void doRecycleOnWrite() {
071: recycle();
072: }
073:
074: protected String describePayload() {
075: return "type: " + typeToString() + ", connectionId: "
076: + connectionId + ", errorContext " + errorContext
077: + "\n";
078: }
079:
080: private String typeToString() {
081: switch (type) {
082: case SYN:
083: return "SYN";
084: case ACK:
085: return "ACK";
086: case SYN_ACK:
087: return "SYN_ACK";
088: default:
089: return "UNKNOWN";
090: }
091: }
092:
093: public ConnectionID getConnectionId() {
094: return this .connectionId;
095: }
096:
097: public boolean hasErrorContext() {
098: return this .hasErrorContext;
099: }
100:
101: public String getErrorContext() {
102: Assert.eval(hasErrorContext());
103: return this .errorContext;
104: }
105:
106: public boolean isSynAck() {
107: return type == SYN_ACK;
108: }
109:
110: public boolean isSyn() {
111: return type == SYN;
112: }
113:
114: public boolean isAck() {
115: return type == ACK;
116: }
117:
118: public boolean hasDefaultConnectionId() {
119: Assert.assertNotNull(connectionId);
120: return this .connectionId.isNull();
121: }
122:
123: public boolean isMaxConnectionsExceeded() {
124: return this .isMaxConnectionsExceeded;
125: }
126:
127: public int getMaxConnections() {
128: return this.maxConnections;
129: }
130:
131: }
|