0001: package dalma.endpoints.jms.impl;
0002:
0003: import javax.jms.JMSException;
0004: import javax.jms.MessageEOFException;
0005: import javax.jms.MessageFormatException;
0006: import javax.jms.MessageNotReadableException;
0007: import javax.jms.MessageNotWriteableException;
0008: import javax.jms.StreamMessage;
0009: import javax.jms.Message;
0010: import java.io.DataInputStream;
0011: import java.io.DataOutputStream;
0012: import java.io.EOFException;
0013: import java.io.IOException;
0014:
0015: /**
0016: * @ThirdParty this class contains code released under ASL.
0017: * @author Kohsuke Kawaguchi
0018: */
0019: public class StreamMessageImpl extends MessageImpl<StreamMessage>
0020: implements StreamMessage {
0021: /**
0022: * A {@link StreamMessage} can be in two modes.
0023: * read-only/write-only
0024: */
0025: boolean readOnlyMode = false;
0026:
0027: private DataInputStream dataIn;
0028: private DataOutputStream dataOut;
0029: private Buffer bytesOut = new Buffer();
0030: private int bytesToRead = -1;
0031:
0032: public StreamMessageImpl() {
0033: }
0034:
0035: public StreamMessageImpl wrap(StreamMessage s) throws JMSException {
0036: super .wrap(s);
0037: try {
0038: while (true) {
0039: writeObject(s.readObject());
0040: }
0041: } catch (MessageEOFException e) {
0042: // reached EOF
0043: reset();
0044: }
0045: return this ;
0046: }
0047:
0048: public void writeTo(StreamMessage d) throws JMSException {
0049: super .writeTo(d);
0050: try {
0051: while (true) {
0052: d.writeObject(readObject());
0053: }
0054: } catch (MessageEOFException e) {
0055: // EOF
0056: }
0057: }
0058:
0059: public void clearBody() throws JMSException {
0060: dataOut = null;
0061: dataIn = null;
0062: bytesOut = new Buffer();
0063: readOnlyMode = false;
0064: }
0065:
0066: /**
0067: * Reads a <code>boolean</code> from the stream message.
0068: *
0069: * @return the <code>boolean</code> value read
0070: * @throws JMSException if the JMS provider fails to read the message
0071: * due to some internal error.
0072: * @throws MessageEOFException if unexpected end of message stream has
0073: * been reached.
0074: * @throws MessageFormatException if this type conversion is invalid.
0075: * @throws MessageNotReadableException if the message is in write-only
0076: * mode.
0077: */
0078:
0079: public boolean readBoolean() throws JMSException {
0080: initializeReading();
0081: try {
0082: if (this .dataIn.available() == 0) {
0083: throw new MessageEOFException("reached end of data");
0084: }
0085:
0086: this .dataIn.mark(10);
0087: int type = this .dataIn.read();
0088: if (type == BOOLEAN) {
0089: return this .dataIn.readBoolean();
0090: }
0091: if (type == STRING) {
0092: return Boolean.valueOf(this .dataIn.readUTF());
0093: }
0094: if (type == NULL) {
0095: this .dataIn.reset();
0096: throw new NullPointerException(
0097: "Cannot convert NULL value to boolean.");
0098: } else {
0099: this .dataIn.reset();
0100: throw new MessageFormatException(" not a boolean type");
0101: }
0102: } catch (EOFException e) {
0103: JMSException jmsEx = new MessageEOFException(e.getMessage());
0104: jmsEx.setLinkedException(e);
0105: throw jmsEx;
0106: } catch (IOException e) {
0107: JMSException jmsEx = new MessageFormatException(e
0108: .getMessage());
0109: jmsEx.setLinkedException(e);
0110: throw jmsEx;
0111: }
0112: }
0113:
0114: /**
0115: * Reads a <code>byte</code> value from the stream message.
0116: *
0117: * @return the next byte from the stream message as a 8-bit
0118: * <code>byte</code>
0119: * @throws JMSException if the JMS provider fails to read the message
0120: * due to some internal error.
0121: * @throws MessageEOFException if unexpected end of message stream has
0122: * been reached.
0123: * @throws MessageFormatException if this type conversion is invalid.
0124: * @throws MessageNotReadableException if the message is in write-only
0125: * mode.
0126: */
0127:
0128: public byte readByte() throws JMSException {
0129: initializeReading();
0130: try {
0131: if (this .dataIn.available() == 0) {
0132: throw new MessageEOFException("reached end of data");
0133: }
0134:
0135: this .dataIn.mark(10);
0136: int type = this .dataIn.read();
0137: if (type == BYTE) {
0138: return this .dataIn.readByte();
0139: }
0140: if (type == STRING) {
0141: return Byte.valueOf(this .dataIn.readUTF());
0142: }
0143: if (type == NULL) {
0144: this .dataIn.reset();
0145: throw new NullPointerException(
0146: "Cannot convert NULL value to byte.");
0147: } else {
0148: this .dataIn.reset();
0149: throw new MessageFormatException(" not a byte type");
0150: }
0151: } catch (NumberFormatException mfe) {
0152: try {
0153: this .dataIn.reset();
0154: } catch (IOException ioe) {
0155: JMSException jmsEx = new JMSException("reset failed");
0156: jmsEx.setLinkedException(ioe);
0157: }
0158: throw mfe;
0159:
0160: } catch (EOFException e) {
0161: JMSException jmsEx = new MessageEOFException(e.getMessage());
0162: jmsEx.setLinkedException(e);
0163: throw jmsEx;
0164: } catch (IOException e) {
0165: JMSException jmsEx = new MessageFormatException(e
0166: .getMessage());
0167: jmsEx.setLinkedException(e);
0168: throw jmsEx;
0169: }
0170: }
0171:
0172: /**
0173: * Reads a 16-bit integer from the stream message.
0174: *
0175: * @return a 16-bit integer from the stream message
0176: * @throws JMSException if the JMS provider fails to read the message
0177: * due to some internal error.
0178: * @throws MessageEOFException if unexpected end of message stream has
0179: * been reached.
0180: * @throws MessageFormatException if this type conversion is invalid.
0181: * @throws MessageNotReadableException if the message is in write-only
0182: * mode.
0183: */
0184:
0185: public short readShort() throws JMSException {
0186: initializeReading();
0187: try {
0188: if (this .dataIn.available() == 0) {
0189: throw new MessageEOFException("reached end of data");
0190: }
0191:
0192: this .dataIn.mark(17);
0193: int type = this .dataIn.read();
0194: if (type == SHORT) {
0195: return this .dataIn.readShort();
0196: }
0197: if (type == BYTE) {
0198: return this .dataIn.readByte();
0199: }
0200: if (type == STRING) {
0201: return Short.valueOf(this .dataIn.readUTF());
0202: }
0203: if (type == NULL) {
0204: this .dataIn.reset();
0205: throw new NullPointerException(
0206: "Cannot convert NULL value to short.");
0207: } else {
0208: this .dataIn.reset();
0209: throw new MessageFormatException(" not a short type");
0210: }
0211: } catch (NumberFormatException mfe) {
0212: try {
0213: this .dataIn.reset();
0214: } catch (IOException ioe) {
0215: JMSException jmsEx = new JMSException("reset failed");
0216: jmsEx.setLinkedException(ioe);
0217: }
0218: throw mfe;
0219:
0220: } catch (EOFException e) {
0221: JMSException jmsEx = new MessageEOFException(e.getMessage());
0222: jmsEx.setLinkedException(e);
0223: throw jmsEx;
0224: } catch (IOException e) {
0225: JMSException jmsEx = new MessageFormatException(e
0226: .getMessage());
0227: jmsEx.setLinkedException(e);
0228: throw jmsEx;
0229: }
0230:
0231: }
0232:
0233: /**
0234: * Reads a Unicode character value from the stream message.
0235: *
0236: * @return a Unicode character from the stream message
0237: * @throws JMSException if the JMS provider fails to read the message
0238: * due to some internal error.
0239: * @throws MessageEOFException if unexpected end of message stream has
0240: * been reached.
0241: * @throws MessageFormatException if this type conversion is invalid
0242: * @throws MessageNotReadableException if the message is in write-only
0243: * mode.
0244: */
0245:
0246: public char readChar() throws JMSException {
0247: initializeReading();
0248: try {
0249: if (this .dataIn.available() == 0) {
0250: throw new MessageEOFException("reached end of data");
0251: }
0252:
0253: this .dataIn.mark(17);
0254: int type = this .dataIn.read();
0255: if (type == CHAR) {
0256: return this .dataIn.readChar();
0257: }
0258: if (type == NULL) {
0259: this .dataIn.reset();
0260: throw new NullPointerException(
0261: "Cannot convert NULL value to char.");
0262: } else {
0263: this .dataIn.reset();
0264: throw new MessageFormatException(" not a char type");
0265: }
0266: } catch (NumberFormatException mfe) {
0267: try {
0268: this .dataIn.reset();
0269: } catch (IOException ioe) {
0270: JMSException jmsEx = new JMSException("reset failed");
0271: jmsEx.setLinkedException(ioe);
0272: }
0273: throw mfe;
0274:
0275: } catch (EOFException e) {
0276: JMSException jmsEx = new MessageEOFException(e.getMessage());
0277: jmsEx.setLinkedException(e);
0278: throw jmsEx;
0279: } catch (IOException e) {
0280: JMSException jmsEx = new MessageFormatException(e
0281: .getMessage());
0282: jmsEx.setLinkedException(e);
0283: throw jmsEx;
0284: }
0285: }
0286:
0287: /**
0288: * Reads a 32-bit integer from the stream message.
0289: *
0290: * @return a 32-bit integer value from the stream message, interpreted
0291: * as an <code>int</code>
0292: * @throws JMSException if the JMS provider fails to read the message
0293: * due to some internal error.
0294: * @throws MessageEOFException if unexpected end of message stream has
0295: * been reached.
0296: * @throws MessageFormatException if this type conversion is invalid.
0297: * @throws MessageNotReadableException if the message is in write-only
0298: * mode.
0299: */
0300:
0301: public int readInt() throws JMSException {
0302: initializeReading();
0303: try {
0304: if (this .dataIn.available() == 0) {
0305: throw new MessageEOFException("reached end of data");
0306: }
0307:
0308: this .dataIn.mark(33);
0309: int type = this .dataIn.read();
0310: if (type == INT) {
0311: return this .dataIn.readInt();
0312: }
0313: if (type == SHORT) {
0314: return this .dataIn.readShort();
0315: }
0316: if (type == BYTE) {
0317: return this .dataIn.readByte();
0318: }
0319: if (type == STRING) {
0320: return Integer.valueOf(this .dataIn.readUTF());
0321: }
0322: if (type == NULL) {
0323: this .dataIn.reset();
0324: throw new NullPointerException(
0325: "Cannot convert NULL value to int.");
0326: } else {
0327: this .dataIn.reset();
0328: throw new MessageFormatException(" not an int type");
0329: }
0330: } catch (NumberFormatException mfe) {
0331: try {
0332: this .dataIn.reset();
0333: } catch (IOException ioe) {
0334: JMSException jmsEx = new JMSException("reset failed");
0335: jmsEx.setLinkedException(ioe);
0336: }
0337: throw mfe;
0338:
0339: } catch (EOFException e) {
0340: JMSException jmsEx = new MessageEOFException(e.getMessage());
0341: jmsEx.setLinkedException(e);
0342: throw jmsEx;
0343: } catch (IOException e) {
0344: JMSException jmsEx = new MessageFormatException(e
0345: .getMessage());
0346: jmsEx.setLinkedException(e);
0347: throw jmsEx;
0348: }
0349: }
0350:
0351: /**
0352: * Reads a 64-bit integer from the stream message.
0353: *
0354: * @return a 64-bit integer value from the stream message, interpreted as
0355: * a <code>long</code>
0356: * @throws JMSException if the JMS provider fails to read the message
0357: * due to some internal error.
0358: * @throws MessageEOFException if unexpected end of message stream has
0359: * been reached.
0360: * @throws MessageFormatException if this type conversion is invalid.
0361: * @throws MessageNotReadableException if the message is in write-only
0362: * mode.
0363: */
0364:
0365: public long readLong() throws JMSException {
0366: initializeReading();
0367: try {
0368: if (this .dataIn.available() == 0) {
0369: throw new MessageEOFException("reached end of data");
0370: }
0371:
0372: this .dataIn.mark(65);
0373: int type = this .dataIn.read();
0374: if (type == LONG) {
0375: return this .dataIn.readLong();
0376: }
0377: if (type == INT) {
0378: return this .dataIn.readInt();
0379: }
0380: if (type == SHORT) {
0381: return this .dataIn.readShort();
0382: }
0383: if (type == BYTE) {
0384: return this .dataIn.readByte();
0385: }
0386: if (type == STRING) {
0387: return Long.valueOf(this .dataIn.readUTF());
0388: }
0389: if (type == NULL) {
0390: this .dataIn.reset();
0391: throw new NullPointerException(
0392: "Cannot convert NULL value to long.");
0393: } else {
0394: this .dataIn.reset();
0395: throw new MessageFormatException(" not a long type");
0396: }
0397: } catch (NumberFormatException mfe) {
0398: try {
0399: this .dataIn.reset();
0400: } catch (IOException ioe) {
0401: JMSException jmsEx = new JMSException("reset failed");
0402: jmsEx.setLinkedException(ioe);
0403: }
0404: throw mfe;
0405:
0406: } catch (EOFException e) {
0407: JMSException jmsEx = new MessageEOFException(e.getMessage());
0408: jmsEx.setLinkedException(e);
0409: throw jmsEx;
0410: } catch (IOException e) {
0411: JMSException jmsEx = new MessageFormatException(e
0412: .getMessage());
0413: jmsEx.setLinkedException(e);
0414: throw jmsEx;
0415: }
0416: }
0417:
0418: /**
0419: * Reads a <code>float</code> from the stream message.
0420: *
0421: * @return a <code>float</code> value from the stream message
0422: * @throws JMSException if the JMS provider fails to read the message
0423: * due to some internal error.
0424: * @throws MessageEOFException if unexpected end of message stream has
0425: * been reached.
0426: * @throws MessageFormatException if this type conversion is invalid.
0427: * @throws MessageNotReadableException if the message is in write-only
0428: * mode.
0429: */
0430:
0431: public float readFloat() throws JMSException {
0432: initializeReading();
0433: try {
0434: if (this .dataIn.available() == 0) {
0435: throw new MessageEOFException("reached end of data");
0436: }
0437:
0438: this .dataIn.mark(33);
0439: int type = this .dataIn.read();
0440: if (type == FLOAT) {
0441: return this .dataIn.readFloat();
0442: }
0443: if (type == STRING) {
0444: return Float.valueOf(this .dataIn.readUTF());
0445: }
0446: if (type == NULL) {
0447: this .dataIn.reset();
0448: throw new NullPointerException(
0449: "Cannot convert NULL value to float.");
0450: } else {
0451: this .dataIn.reset();
0452: throw new MessageFormatException(" not a float type");
0453: }
0454: } catch (NumberFormatException mfe) {
0455: try {
0456: this .dataIn.reset();
0457: } catch (IOException ioe) {
0458: JMSException jmsEx = new JMSException("reset failed");
0459: jmsEx.setLinkedException(ioe);
0460: }
0461: throw mfe;
0462:
0463: } catch (EOFException e) {
0464: JMSException jmsEx = new MessageEOFException(e.getMessage());
0465: jmsEx.setLinkedException(e);
0466: throw jmsEx;
0467: } catch (IOException e) {
0468: JMSException jmsEx = new MessageFormatException(e
0469: .getMessage());
0470: jmsEx.setLinkedException(e);
0471: throw jmsEx;
0472: }
0473: }
0474:
0475: /**
0476: * Reads a <code>double</code> from the stream message.
0477: *
0478: * @return a <code>double</code> value from the stream message
0479: * @throws JMSException if the JMS provider fails to read the message
0480: * due to some internal error.
0481: * @throws MessageEOFException if unexpected end of message stream has
0482: * been reached.
0483: * @throws MessageFormatException if this type conversion is invalid.
0484: * @throws MessageNotReadableException if the message is in write-only
0485: * mode.
0486: */
0487:
0488: public double readDouble() throws JMSException {
0489: initializeReading();
0490: try {
0491: if (this .dataIn.available() == 0) {
0492: throw new MessageEOFException("reached end of data");
0493: }
0494:
0495: this .dataIn.mark(65);
0496: int type = this .dataIn.read();
0497: if (type == DOUBLE) {
0498: return this .dataIn.readDouble();
0499: }
0500: if (type == FLOAT) {
0501: return this .dataIn.readFloat();
0502: }
0503: if (type == STRING) {
0504: return Double.valueOf(this .dataIn.readUTF());
0505: }
0506: if (type == NULL) {
0507: this .dataIn.reset();
0508: throw new NullPointerException(
0509: "Cannot convert NULL value to double.");
0510: } else {
0511: this .dataIn.reset();
0512: throw new MessageFormatException(" not a double type");
0513: }
0514: } catch (NumberFormatException mfe) {
0515: try {
0516: this .dataIn.reset();
0517: } catch (IOException ioe) {
0518: JMSException jmsEx = new JMSException("reset failed");
0519: jmsEx.setLinkedException(ioe);
0520: }
0521: throw mfe;
0522:
0523: } catch (EOFException e) {
0524: JMSException jmsEx = new MessageEOFException(e.getMessage());
0525: jmsEx.setLinkedException(e);
0526: throw jmsEx;
0527: } catch (IOException e) {
0528: JMSException jmsEx = new MessageFormatException(e
0529: .getMessage());
0530: jmsEx.setLinkedException(e);
0531: throw jmsEx;
0532: }
0533: }
0534:
0535: /**
0536: * Reads a <CODE>String</CODE> from the stream message.
0537: *
0538: * @return a Unicode string from the stream message
0539: * @throws JMSException if the JMS provider fails to read the message
0540: * due to some internal error.
0541: * @throws MessageEOFException if unexpected end of message stream has
0542: * been reached.
0543: * @throws MessageFormatException if this type conversion is invalid.
0544: * @throws MessageNotReadableException if the message is in write-only
0545: * mode.
0546: */
0547:
0548: public String readString() throws JMSException {
0549: initializeReading();
0550: try {
0551: if (this .dataIn.available() == 0) {
0552: throw new MessageEOFException("reached end of data");
0553: }
0554:
0555: this .dataIn.mark(65);
0556: int type = this .dataIn.read();
0557: if (type == NULL) {
0558: return null;
0559: }
0560: if (type == STRING) {
0561: return this .dataIn.readUTF();
0562: }
0563: if (type == LONG) {
0564: return Long.toString(this .dataIn.readLong());
0565: }
0566: if (type == INT) {
0567: return Integer.toString(this .dataIn.readInt());
0568: }
0569: if (type == SHORT) {
0570: return Short.toString(this .dataIn.readShort());
0571: }
0572: if (type == BYTE) {
0573: return new Byte(this .dataIn.readByte()).toString();
0574: }
0575: if (type == FLOAT) {
0576: return Float.toString(this .dataIn.readFloat());
0577: }
0578: if (type == DOUBLE) {
0579: return Double.toString(this .dataIn.readDouble());
0580: }
0581: if (type == BOOLEAN) {
0582: return (this .dataIn.readBoolean() ? Boolean.TRUE
0583: : Boolean.FALSE).toString();
0584: }
0585: if (type == CHAR) {
0586: return new Character(this .dataIn.readChar()).toString();
0587: } else {
0588: this .dataIn.reset();
0589: throw new MessageFormatException(" not a String type");
0590: }
0591: } catch (NumberFormatException mfe) {
0592: try {
0593: this .dataIn.reset();
0594: } catch (IOException ioe) {
0595: JMSException jmsEx = new JMSException("reset failed");
0596: jmsEx.setLinkedException(ioe);
0597: }
0598: throw mfe;
0599:
0600: } catch (EOFException e) {
0601: JMSException jmsEx = new MessageEOFException(e.getMessage());
0602: jmsEx.setLinkedException(e);
0603: throw jmsEx;
0604: } catch (IOException e) {
0605: JMSException jmsEx = new MessageFormatException(e
0606: .getMessage());
0607: jmsEx.setLinkedException(e);
0608: throw jmsEx;
0609: }
0610: }
0611:
0612: /**
0613: * Reads a byte array field from the stream message into the
0614: * specified <CODE>byte[]</CODE> object (the read buffer).
0615: * <p/>
0616: * <P>To read the field value, <CODE>readBytes</CODE> should be
0617: * successively called
0618: * until it returns a value less than the length of the read buffer.
0619: * The value of the bytes in the buffer following the last byte
0620: * read is undefined.
0621: * <p/>
0622: * <P>If <CODE>readBytes</CODE> returns a value equal to the length of the
0623: * buffer, a subsequent <CODE>readBytes</CODE> call must be made. If there
0624: * are no more bytes to be read, this call returns -1.
0625: * <p/>
0626: * <P>If the byte array field value is null, <CODE>readBytes</CODE>
0627: * returns -1.
0628: * <p/>
0629: * <P>If the byte array field value is empty, <CODE>readBytes</CODE>
0630: * returns 0.
0631: * <p/>
0632: * <P>Once the first <CODE>readBytes</CODE> call on a <CODE>byte[]</CODE>
0633: * field value has been made,
0634: * the full value of the field must be read before it is valid to read
0635: * the next field. An attempt to read the next field before that has
0636: * been done will throw a <CODE>MessageFormatException</CODE>.
0637: * <p/>
0638: * <P>To read the byte field value into a new <CODE>byte[]</CODE> object,
0639: * use the <CODE>readObject</CODE> method.
0640: *
0641: * @param value the buffer into which the data is read
0642: * @return the total number of bytes read into the buffer, or -1 if
0643: * there is no more data because the end of the byte field has been
0644: * reached
0645: * @throws JMSException if the JMS provider fails to read the message
0646: * due to some internal error.
0647: * @throws MessageEOFException if unexpected end of message stream has
0648: * been reached.
0649: * @throws MessageFormatException if this type conversion is invalid.
0650: * @throws MessageNotReadableException if the message is in write-only
0651: * mode.
0652: * @see #readObject()
0653: */
0654:
0655: public int readBytes(byte[] value) throws JMSException {
0656: initializeReading();
0657: try {
0658: if (value == null) {
0659: throw new NullPointerException();
0660: }
0661: if (bytesToRead == 0) {
0662: bytesToRead = -1;
0663: return -1;
0664: } else if (bytesToRead > 0) {
0665: if (value.length >= bytesToRead) {
0666: bytesToRead = 0;
0667: return dataIn.read(value, 0, bytesToRead);
0668: } else {
0669: bytesToRead -= value.length;
0670: return dataIn.read(value);
0671: }
0672: } else {
0673: if (this .dataIn.available() == 0) {
0674: throw new MessageEOFException("reached end of data");
0675: }
0676: if (this .dataIn.available() < 1) {
0677: throw new MessageFormatException(
0678: "Not enough data left to read value");
0679: }
0680: this .dataIn.mark(value.length + 1);
0681: int type = this .dataIn.read();
0682: if (this .dataIn.available() < 1) {
0683: return -1;
0684: }
0685: if (type != BYTES) {
0686: throw new MessageFormatException("Not a byte array");
0687: }
0688: int len = this .dataIn.readInt();
0689:
0690: if (len >= value.length) {
0691: bytesToRead = len - value.length;
0692: return this .dataIn.read(value);
0693: } else {
0694: bytesToRead = 0;
0695: return this .dataIn.read(value, 0, len);
0696: }
0697: }
0698: } catch (EOFException e) {
0699: JMSException jmsEx = new MessageEOFException(e.getMessage());
0700: jmsEx.setLinkedException(e);
0701: throw jmsEx;
0702: } catch (IOException e) {
0703: JMSException jmsEx = new MessageFormatException(e
0704: .getMessage());
0705: jmsEx.setLinkedException(e);
0706: throw jmsEx;
0707: }
0708: }
0709:
0710: /**
0711: * Reads an object from the stream message.
0712: * <p/>
0713: * <P>This method can be used to return, in objectified format,
0714: * an object in the Java programming language ("Java object") that has
0715: * been written to the stream with the equivalent
0716: * <CODE>writeObject</CODE> method call, or its equivalent primitive
0717: * <CODE>write<I>type</I></CODE> method.
0718: * <p/>
0719: * <P>Note that byte values are returned as <CODE>byte[]</CODE>, not
0720: * <CODE>Byte[]</CODE>.
0721: * <p/>
0722: * <P>An attempt to call <CODE>readObject</CODE> to read a byte field
0723: * value into a new <CODE>byte[]</CODE> object before the full value of the
0724: * byte field has been read will throw a
0725: * <CODE>MessageFormatException</CODE>.
0726: *
0727: * @return a Java object from the stream message, in objectified
0728: * format (for example, if the object was written as an <CODE>int</CODE>,
0729: * an <CODE>Integer</CODE> is returned)
0730: * @throws JMSException if the JMS provider fails to read the message
0731: * due to some internal error.
0732: * @throws MessageEOFException if unexpected end of message stream has
0733: * been reached.
0734: * @throws MessageFormatException if this type conversion is invalid.
0735: * @throws MessageNotReadableException if the message is in write-only
0736: * mode.
0737: * @see #readBytes(byte[] value)
0738: */
0739:
0740: public Object readObject() throws JMSException {
0741: initializeReading();
0742: try {
0743: if (this .dataIn.available() == 0) {
0744: throw new MessageEOFException("reached end of data");
0745: }
0746:
0747: this .dataIn.mark(65);
0748: int type = this .dataIn.read();
0749: if (type == NULL) {
0750: return null;
0751: }
0752: if (type == STRING) {
0753: return this .dataIn.readUTF();
0754: }
0755: if (type == LONG) {
0756: return this .dataIn.readLong();
0757: }
0758: if (type == INT) {
0759: return this .dataIn.readInt();
0760: }
0761: if (type == SHORT) {
0762: return this .dataIn.readShort();
0763: }
0764: if (type == BYTE) {
0765: return this .dataIn.readByte();
0766: }
0767: if (type == FLOAT) {
0768: return this .dataIn.readFloat();
0769: }
0770: if (type == DOUBLE) {
0771: return this .dataIn.readDouble();
0772: }
0773: if (type == BOOLEAN) {
0774: return this .dataIn.readBoolean() ? Boolean.TRUE
0775: : Boolean.FALSE;
0776: }
0777: if (type == CHAR) {
0778: return this .dataIn.readChar();
0779: }
0780: if (type == BYTES) {
0781: int len = this .dataIn.readInt();
0782: byte[] value = new byte[len];
0783: this .dataIn.readFully(value);
0784: return value;
0785: } else {
0786: this .dataIn.reset();
0787: throw new MessageFormatException("unknown type");
0788: }
0789: } catch (NumberFormatException mfe) {
0790: try {
0791: this .dataIn.reset();
0792: } catch (IOException ioe) {
0793: JMSException jmsEx = new JMSException("reset failed");
0794: jmsEx.setLinkedException(ioe);
0795: }
0796: throw mfe;
0797:
0798: } catch (EOFException e) {
0799: JMSException jmsEx = new MessageEOFException(e.getMessage());
0800: jmsEx.setLinkedException(e);
0801: throw jmsEx;
0802: } catch (IOException e) {
0803: JMSException jmsEx = new MessageFormatException(e
0804: .getMessage());
0805: jmsEx.setLinkedException(e);
0806: throw jmsEx;
0807: }
0808: }
0809:
0810: /**
0811: * Writes a <code>boolean</code> to the stream message.
0812: * The value <code>true</code> is written as the value
0813: * <code>(byte)1</code>; the value <code>false</code> is written as
0814: * the value <code>(byte)0</code>.
0815: *
0816: * @param value the <code>boolean</code> value to be written
0817: * @throws JMSException if the JMS provider fails to write the message
0818: * due to some internal error.
0819: * @throws MessageNotWriteableException if the message is in read-only
0820: * mode.
0821: */
0822:
0823: public void writeBoolean(boolean value) throws JMSException {
0824: initializeWriting();
0825: try {
0826: this .dataOut.write(BOOLEAN);
0827: this .dataOut.writeBoolean(value);
0828: } catch (IOException ioe) {
0829: JMSException jmsEx = new JMSException(ioe.getMessage());
0830: jmsEx.setLinkedException(ioe);
0831: throw jmsEx;
0832: }
0833: }
0834:
0835: /**
0836: * Writes a <code>byte</code> to the stream message.
0837: *
0838: * @param value the <code>byte</code> value to be written
0839: * @throws JMSException if the JMS provider fails to write the message
0840: * due to some internal error.
0841: * @throws MessageNotWriteableException if the message is in read-only
0842: * mode.
0843: */
0844:
0845: public void writeByte(byte value) throws JMSException {
0846: initializeWriting();
0847: try {
0848: this .dataOut.write(BYTE);
0849: this .dataOut.writeByte(value);
0850: } catch (IOException ioe) {
0851: JMSException jmsEx = new JMSException(ioe.getMessage());
0852: jmsEx.setLinkedException(ioe);
0853: throw jmsEx;
0854: }
0855: }
0856:
0857: /**
0858: * Writes a <code>short</code> to the stream message.
0859: *
0860: * @param value the <code>short</code> value to be written
0861: * @throws JMSException if the JMS provider fails to write the message
0862: * due to some internal error.
0863: * @throws MessageNotWriteableException if the message is in read-only
0864: * mode.
0865: */
0866:
0867: public void writeShort(short value) throws JMSException {
0868: initializeWriting();
0869: try {
0870: this .dataOut.write(SHORT);
0871: this .dataOut.writeShort(value);
0872: } catch (IOException ioe) {
0873: JMSException jmsEx = new JMSException(ioe.getMessage());
0874: jmsEx.setLinkedException(ioe);
0875: throw jmsEx;
0876: }
0877: }
0878:
0879: /**
0880: * Writes a <code>char</code> to the stream message.
0881: *
0882: * @param value the <code>char</code> value to be written
0883: * @throws JMSException if the JMS provider fails to write the message
0884: * due to some internal error.
0885: * @throws MessageNotWriteableException if the message is in read-only
0886: * mode.
0887: */
0888:
0889: public void writeChar(char value) throws JMSException {
0890: initializeWriting();
0891: try {
0892: this .dataOut.write(CHAR);
0893: this .dataOut.writeChar(value);
0894: } catch (IOException ioe) {
0895: JMSException jmsEx = new JMSException(ioe.getMessage());
0896: jmsEx.setLinkedException(ioe);
0897: throw jmsEx;
0898: }
0899: }
0900:
0901: /**
0902: * Writes an <code>int</code> to the stream message.
0903: *
0904: * @param value the <code>int</code> value to be written
0905: * @throws JMSException if the JMS provider fails to write the message
0906: * due to some internal error.
0907: * @throws MessageNotWriteableException if the message is in read-only
0908: * mode.
0909: */
0910:
0911: public void writeInt(int value) throws JMSException {
0912: initializeWriting();
0913: try {
0914: this .dataOut.write(INT);
0915: this .dataOut.writeInt(value);
0916: } catch (IOException ioe) {
0917: JMSException jmsEx = new JMSException(ioe.getMessage());
0918: jmsEx.setLinkedException(ioe);
0919: throw jmsEx;
0920: }
0921: }
0922:
0923: /**
0924: * Writes a <code>long</code> to the stream message.
0925: *
0926: * @param value the <code>long</code> value to be written
0927: * @throws JMSException if the JMS provider fails to write the message
0928: * due to some internal error.
0929: * @throws MessageNotWriteableException if the message is in read-only
0930: * mode.
0931: */
0932:
0933: public void writeLong(long value) throws JMSException {
0934: initializeWriting();
0935: try {
0936: this .dataOut.write(LONG);
0937: this .dataOut.writeLong(value);
0938: } catch (IOException ioe) {
0939: JMSException jmsEx = new JMSException(ioe.getMessage());
0940: jmsEx.setLinkedException(ioe);
0941: throw jmsEx;
0942: }
0943: }
0944:
0945: /**
0946: * Writes a <code>float</code> to the stream message.
0947: *
0948: * @param value the <code>float</code> value to be written
0949: * @throws JMSException if the JMS provider fails to write the message
0950: * due to some internal error.
0951: * @throws MessageNotWriteableException if the message is in read-only
0952: * mode.
0953: */
0954:
0955: public void writeFloat(float value) throws JMSException {
0956: initializeWriting();
0957: try {
0958: this .dataOut.write(FLOAT);
0959: this .dataOut.writeFloat(value);
0960: } catch (IOException ioe) {
0961: JMSException jmsEx = new JMSException(ioe.getMessage());
0962: jmsEx.setLinkedException(ioe);
0963: throw jmsEx;
0964: }
0965: }
0966:
0967: /**
0968: * Writes a <code>double</code> to the stream message.
0969: *
0970: * @param value the <code>double</code> value to be written
0971: * @throws JMSException if the JMS provider fails to write the message
0972: * due to some internal error.
0973: * @throws MessageNotWriteableException if the message is in read-only
0974: * mode.
0975: */
0976:
0977: public void writeDouble(double value) throws JMSException {
0978: initializeWriting();
0979: try {
0980: this .dataOut.write(DOUBLE);
0981: this .dataOut.writeDouble(value);
0982: } catch (IOException ioe) {
0983: JMSException jmsEx = new JMSException(ioe.getMessage());
0984: jmsEx.setLinkedException(ioe);
0985: throw jmsEx;
0986: }
0987: }
0988:
0989: /**
0990: * Writes a <code>String</code> to the stream message.
0991: *
0992: * @param value the <code>String</code> value to be written
0993: * @throws JMSException if the JMS provider fails to write the message
0994: * due to some internal error.
0995: * @throws MessageNotWriteableException if the message is in read-only
0996: * mode.
0997: */
0998:
0999: public void writeString(String value) throws JMSException {
1000: initializeWriting();
1001: try {
1002: if (value == null) {
1003: this .dataOut.write(NULL);
1004: } else {
1005: this .dataOut.write(STRING);
1006: this .dataOut.writeUTF(value);
1007: }
1008: } catch (IOException ioe) {
1009: JMSException jmsEx = new JMSException(ioe.getMessage());
1010: jmsEx.setLinkedException(ioe);
1011: throw jmsEx;
1012: }
1013: }
1014:
1015: /**
1016: * Writes a byte array field to the stream message.
1017: * <p/>
1018: * <P>The byte array <code>value</code> is written to the message
1019: * as a byte array field. Consecutively written byte array fields are
1020: * treated as two distinct fields when the fields are read.
1021: *
1022: * @param value the byte array value to be written
1023: * @throws JMSException if the JMS provider fails to write the message
1024: * due to some internal error.
1025: * @throws MessageNotWriteableException if the message is in read-only
1026: * mode.
1027: */
1028:
1029: public void writeBytes(byte[] value) throws JMSException {
1030: writeBytes(value, 0, value.length);
1031: }
1032:
1033: /**
1034: * Writes a portion of a byte array as a byte array field to the stream
1035: * message.
1036: * <p/>
1037: * <P>The a portion of the byte array <code>value</code> is written to the
1038: * message as a byte array field. Consecutively written byte
1039: * array fields are treated as two distinct fields when the fields are
1040: * read.
1041: *
1042: * @param value the byte array value to be written
1043: * @param offset the initial offset within the byte array
1044: * @param length the number of bytes to use
1045: * @throws JMSException if the JMS provider fails to write the message
1046: * due to some internal error.
1047: * @throws MessageNotWriteableException if the message is in read-only
1048: * mode.
1049: */
1050:
1051: public void writeBytes(byte[] value, int offset, int length)
1052: throws JMSException {
1053: initializeWriting();
1054: try {
1055: this .dataOut.write(BYTES);
1056: this .dataOut.writeInt(length);
1057: this .dataOut.write(value, offset, length);
1058: } catch (IOException ioe) {
1059: JMSException jmsEx = new JMSException(ioe.getMessage());
1060: jmsEx.setLinkedException(ioe);
1061: throw jmsEx;
1062: }
1063: }
1064:
1065: /**
1066: * Writes an object to the stream message.
1067: * <p/>
1068: * <P>This method works only for the objectified primitive
1069: * object types (<code>Integer</code>, <code>Double</code>,
1070: * <code>Long</code> ...), <code>String</code> objects, and byte
1071: * arrays.
1072: *
1073: * @param value the Java object to be written
1074: * @throws JMSException if the JMS provider fails to write the message
1075: * due to some internal error.
1076: * @throws MessageFormatException if the object is invalid.
1077: * @throws MessageNotWriteableException if the message is in read-only
1078: * mode.
1079: */
1080:
1081: public void writeObject(Object value) throws JMSException {
1082: initializeWriting();
1083: if (value == null) {
1084: try {
1085: this .dataOut.write(NULL);
1086: } catch (IOException ioe) {
1087: JMSException jmsEx = new JMSException(ioe.getMessage());
1088: jmsEx.setLinkedException(ioe);
1089: throw jmsEx;
1090: }
1091: } else if (value instanceof String) {
1092: writeString(value.toString());
1093: } else if (value instanceof Character) {
1094: writeChar((Character) value);
1095: } else if (value instanceof Boolean) {
1096: writeBoolean((Boolean) value);
1097: } else if (value instanceof Byte) {
1098: writeByte((Byte) value);
1099: } else if (value instanceof Short) {
1100: writeShort((Short) value);
1101: } else if (value instanceof Integer) {
1102: writeInt((Integer) value);
1103: } else if (value instanceof Float) {
1104: writeFloat((Float) value);
1105: } else if (value instanceof Double) {
1106: writeDouble((Double) value);
1107: } else if (value instanceof byte[]) {
1108: writeBytes((byte[]) value);
1109: }
1110: }
1111:
1112: /**
1113: * Puts the message body in read-only mode and repositions the stream of
1114: * bytes to the beginning.
1115: *
1116: * @throws JMSException if an internal error occurs
1117: */
1118:
1119: public void reset() throws JMSException {
1120: readOnlyMode = true;
1121: if (this .dataOut != null) {
1122: try {
1123: this .dataOut.flush();
1124: dataOut.close();
1125: this .dataOut = null;
1126: } catch (IOException ioe) {
1127: JMSException jmsEx = new JMSException("reset failed: "
1128: + ioe.getMessage());
1129: jmsEx.setLinkedException(ioe);
1130: throw jmsEx;
1131: }
1132: }
1133: this .dataIn = null;
1134: }
1135:
1136: private void initializeWriting()
1137: throws MessageNotWriteableException {
1138: if (readOnlyMode) {
1139: throw new MessageNotWriteableException(
1140: "This message is in read-only mode");
1141: }
1142: if (this .dataOut == null) {
1143: this .bytesOut = new Buffer();
1144: this .dataOut = new DataOutputStream(this .bytesOut);
1145: }
1146: dataIn = null;
1147: }
1148:
1149: private void initializeReading() throws MessageNotReadableException {
1150: if (!readOnlyMode) {
1151: throw new MessageNotReadableException(
1152: "This message is in write-only mode");
1153: }
1154: if (dataIn == null) {
1155: dataIn = new DataInputStream(bytesOut.newInputStream());
1156: }
1157: dataOut = null;
1158: }
1159:
1160: /**
1161: * message property types
1162: */
1163: private final static byte BYTES = 3;
1164: private final static byte STRING = 4;
1165: private final static byte BOOLEAN = 5;
1166: private final static byte CHAR = 6;
1167: private final static byte BYTE = 7;
1168: private final static byte SHORT = 8;
1169: private final static byte INT = 9;
1170: private final static byte LONG = 10;
1171: private final static byte FLOAT = 11;
1172: private final static byte DOUBLE = 12;
1173: private final static byte NULL = 13;
1174:
1175: private static final long serialVersionUID = 1L;
1176: }
|