//$Header: /cvsroot-fuse/mec-as2/39/mendelson/comm/as2/message/AS2Message.java,v 1.1 2012/04/18 14:10:30 heller Exp $ package de.mendelson.comm.as2.message; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Formatter; import java.util.List; import java.util.Locale; import java.util.Properties; /** * Stores a AS2 message * @author S.Heller * @version $Revision: 1.1 $ */ public class AS2Message implements Serializable { public static final int ENCRYPTION_UNKNOWN = 0; public static final int ENCRYPTION_NONE = 1; public static final int ENCRYPTION_3DES = 2; public static final int ENCRYPTION_RC2_40 = 3; public static final int ENCRYPTION_RC2_64 = 4; public static final int ENCRYPTION_RC2_128 = 5; public static final int ENCRYPTION_RC2_196 = 6; public static final int ENCRYPTION_RC2_UNKNOWN = 7; public static final int ENCRYPTION_AES_128 = 8; public static final int ENCRYPTION_AES_192 = 9; public static final int ENCRYPTION_AES_256 = 10; public static final int ENCRYPTION_RC4_40 = 11; public static final int ENCRYPTION_RC4_56 = 12; public static final int ENCRYPTION_RC4_128 = 13; public static final int ENCRYPTION_RC4_UNKNOWN = 14; public static final int ENCRYPTION_DES = 15; public static final int ENCRYPTION_UNKNOWN_ALGORITHM = 99; public static final int SIGNATURE_UNKNOWN = 0; public static final int SIGNATURE_NONE = 1; public static final int SIGNATURE_SHA1 = 2; public static final int SIGNATURE_MD5 = 3; public static final int COMPRESSION_UNKNOWN = 0; public static final int COMPRESSION_NONE = 1; public static final int COMPRESSION_ZLIB = 2; public static final int STATE_FINISHED = 1; public static final int STATE_PENDING = 2; public static final int STATE_STOPPED = 3; public static final int CONTENT_TRANSFER_ENCODING_BINARY = 1; public static final int CONTENT_TRANSFER_ENCODING_BASE64 = 2; public static final int MESSAGETYPE_AS2 = 1; public static final int MESSAGETYPE_CEM = 2; /**Stores all details about the message*/ private AS2Info as2Info = null; /**Stores the raw message data*/ private ByteStorage rawData = new ByteStorage(); /**Stores the raw message data, decrypted. Contains the same data as the raw data *if the message has been sent unencrypted */ private ByteStorage decryptedRawData = new ByteStorage(); /**Payload of the as2 message, will be only one if the AS2 version is < AS2 1.2 */ private List<AS2Payload> payload = new ArrayList<AS2Payload>(); private Properties header = new Properties(); private String contentType; /**Constructor to create a new message, empty message object */ public AS2Message(AS2Info as2Info) { this.as2Info = as2Info; } public boolean isMDN(){ return( this.as2Info.isMDN()); } /**Escapes the AS2-TO and AS2-FROM headers in sending direction, related to * RFC 4130 section 6.2 * @param identification as2-from or as2-to value to escape * @return escaped value */ public static String escapeFromToHeader(String identification) { boolean containsBlank = false; StringBuilder builder = new StringBuilder(); for (int i = 0; i < identification.length(); i++) { char singleChar = identification.charAt(i); if (singleChar == ' ') { containsBlank = true; } else if (singleChar == '"') { builder.append("\\"); } else if (singleChar == '\\') { builder.append("\\"); } builder.append(singleChar); } //quote the value if it contains blanks if (containsBlank) { builder.insert(0, "\""); builder.append("\""); } return (builder.toString()); } /**Returns the number of attachments of the AS2 message. This will mainly be 1 if the AS2 version is < AS2 1.2 */ public int getPayloadCount() { return (this.payload.size()); } /**Copies all data from one stream to another*/ private void copyStreams(InputStream in, OutputStream out) throws IOException { BufferedInputStream inStream = new BufferedInputStream(in); BufferedOutputStream outStream = new BufferedOutputStream(out); //copy the contents to an output stream byte[] buffer = new byte[2048]; int read = 2048; //a read of 0 must be allowed, sometimes it takes time to //extract data from the input while (read != -1) { read = inStream.read(buffer); if (read > 0) { outStream.write(buffer, 0, read); } } outStream.flush(); } /**Returns the actual size of the stored raw data*/ public int getRawDataSize() { return (this.rawData.getSize()); } public InputStream getRawDataInputStream() throws Exception { return (this.rawData.getInputStream()); } public byte[] getRawData() throws Exception { return (this.rawData.get()); } public void setRawData(byte[] rawData) throws Exception { this.rawData.put(rawData); } /**Returns the actual size of the stored decrypted raw data*/ public int getDecryptedRawDataSize() { return (this.rawData.getSize()); } public InputStream getDecryptedRawDataInputStream() throws Exception { return (this.decryptedRawData.getInputStream()); } public byte[] getDecryptedRawData() throws Exception { return (this.decryptedRawData.get()); } public void setDecryptedRawData(byte[] decryptedRawData) throws Exception { this.decryptedRawData.put(decryptedRawData); } public Properties getHeader() { return header; } public void setHeader(Properties header) { this.header = header; } /**Will return the payload of the passed index. The index should be 0 if the AS2 version is < AS2 1.2 */ public AS2Payload getPayload(int index) { if (this.payload == null || this.payload.isEmpty()) { throw new IllegalArgumentException("AS2 message does not contain " + index + " payloads."); } return (this.payload.get(index)); } public void addPayload(AS2Payload data) { this.payload.add(data); } /**Will return the payloads of the message */ public List<AS2Payload> getPayloads() { List<AS2Payload> list = new ArrayList<AS2Payload>(); list.addAll(this.payload); return( list ); } /**Deletes the actual payloads and adds the passed ones*/ public void setPayloads( List<AS2Payload> payloads ){ this.payload.clear(); this.payload.addAll(payloads); } /**Writes the payload to the message to the passed file*/ public void writeRawDecryptedTo(File file) throws Exception { FileOutputStream outStream = new FileOutputStream(file); InputStream inStream = this.decryptedRawData.getInputStream(); this.copyStreams(inStream, outStream); outStream.flush(); outStream.close(); inStream.close(); } public String getContentType() { return contentType; } public void setContentType(String contentType) { this.contentType = contentType; } /** * @return the as2Info */ public AS2Info getAS2Info() { return as2Info; } /** * @param as2Info the as2Info to set */ public void setAS2Info(AS2Info as2Info) { this.as2Info = as2Info; } }