001: /*
002: * SSHTools - Java SSH2 API
003: *
004: * Copyright (C) 2002-2003 Lee David Painter and Contributors.
005: *
006: * Contributions made by:
007: *
008: * Brett Smith
009: * Richard Pernavas
010: * Erwin Bolwidt
011: *
012: * This program is free software; you can redistribute it and/or
013: * modify it under the terms of the GNU General Public License
014: * as published by the Free Software Foundation; either version 2
015: * of the License, or (at your option) any later version.
016: *
017: * This program is distributed in the hope that it will be useful,
018: * but WITHOUT ANY WARRANTY; without even the implied warranty of
019: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
020: * GNU General Public License for more details.
021: *
022: * You should have received a copy of the GNU General Public License
023: * along with this program; if not, write to the Free Software
024: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
025: */
026: package com.sshtools.j2ssh.transport;
027:
028: import com.sshtools.j2ssh.io.ByteArrayReader;
029: import com.sshtools.j2ssh.io.ByteArrayWriter;
030:
031: /**
032: * <p>
033: * This class implements the payload portion each message sent by the transport
034: * protocol. Each message consists of an integer message id followed by a
035: * variable byte array containing message data.
036: * </p>
037: *
038: * @author Lee David Painter
039: * @version $Revision: 1.21 $
040: *
041: * @since 0.2.0
042: */
043: public abstract class SshMessage {
044: // The message Id of the message
045: private int messageId;
046:
047: /**
048: * <p>
049: * Contructs the message.
050: * </p>
051: *
052: * @param messageId the id of the message
053: *
054: * @since 0.2.0
055: */
056: public SshMessage(int messageId) {
057: // Save the message id
058: this .messageId = messageId;
059: }
060:
061: /**
062: * <p>
063: * Returns the id of the message
064: * </p>
065: *
066: * @return an integer message id
067: *
068: * @since 0.2.0
069: */
070: public final int getMessageId() {
071: return messageId;
072: }
073:
074: /**
075: * <p>
076: * Returns the name of the message implementation for debugging purposes.
077: * </p>
078: *
079: * @return the name of the message e.g. "SSH_MSG_DISCONNECT"
080: *
081: * @since 0.2.0
082: */
083: public abstract String getMessageName();
084:
085: /**
086: * <p>
087: * Format the message into the payload array for sending by the transport
088: * protocol. This implementation creates a byte array, writes the message
089: * id and calls the abstract <code>constructByteArray</code>.
090: * </p>
091: *
092: * @return the payload portion of a transport protocol message
093: *
094: * @throws InvalidMessageException if the message is invalid
095: *
096: * @since 0.2.0
097: */
098: public final byte[] toByteArray() throws InvalidMessageException {
099: // Create a writer object to construct the array
100: ByteArrayWriter baw = new ByteArrayWriter();
101:
102: // Write the message id
103: baw.write(messageId);
104:
105: // Call the abstract method so subclasses classes can add their data
106: constructByteArray(baw);
107:
108: // Return the array
109: return baw.toByteArray();
110: }
111:
112: /**
113: * <p>
114: * Initializes the message from a byte array.
115: * </p>
116: *
117: * @param data the byte array being read.
118: *
119: * @throws InvalidMessageException if the message is invalid
120: *
121: * @since 0.2.0
122: */
123: protected final void fromByteArray(ByteArrayReader data)
124: throws InvalidMessageException {
125: // Skip the first 5 bytes as this contains the packet length and payload
126: // length fields
127: data.skip(5);
128:
129: int id = data.read();
130:
131: if (id != messageId) {
132: throw new InvalidMessageException(
133: "The message id "
134: + String.valueOf(id)
135: + " is not the same as the message implementation id "
136: + String.valueOf(messageId));
137: }
138:
139: // Call abstract method for subclasses to extract the message specific data
140: constructMessage(data);
141: }
142:
143: /**
144: * <p>
145: * Helper method to extract the message id from the complete message data
146: * recieved by the transport protocol.
147: * </p>
148: *
149: * @param msgdata the transport protocol message
150: *
151: * @return the id of the message
152: *
153: * @since 0.2.0
154: */
155: public static Integer getMessageId(byte[] msgdata) {
156: return new Integer(msgdata[5]);
157: }
158:
159: /**
160: * <p>
161: * Message implementations should implement this method, writing the data
162: * as exected in the transport protocol message format.
163: * </p>
164: *
165: * @param baw the byte array being written to
166: *
167: * @throws InvalidMessageException if the message is invalid
168: *
169: * @since 0.2.0
170: */
171: protected abstract void constructByteArray(ByteArrayWriter baw)
172: throws InvalidMessageException;
173:
174: /**
175: * <p>
176: * Message implementation should implement this method, reading the data as
177: * expected in the transport protocol message format.
178: * </p>
179: *
180: * @param bar the byte array being read
181: *
182: * @throws InvalidMessageException if the message is invalid
183: *
184: * @since 0.2.0
185: */
186: protected abstract void constructMessage(ByteArrayReader bar)
187: throws InvalidMessageException;
188: }
|