001/** 002 * 003 * Copyright the original author or authors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.bytestreams.ibb.packet; 018 019import org.jivesoftware.smack.packet.PacketExtension; 020import org.jivesoftware.smack.util.StringUtils; 021import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; 022 023/** 024 * Represents a chunk of data of an In-Band Bytestream within an IQ stanza or a 025 * message stanza 026 * 027 * @author Henning Staib 028 */ 029public class DataPacketExtension implements PacketExtension { 030 031 /** 032 * The element name of the data packet extension. 033 */ 034 public final static String ELEMENT_NAME = "data"; 035 036 /* unique session ID identifying this In-Band Bytestream */ 037 private final String sessionID; 038 039 /* sequence of this packet in regard to the other data packets */ 040 private final long seq; 041 042 /* the data contained in this packet */ 043 private final String data; 044 045 private byte[] decodedData; 046 047 /** 048 * Creates a new In-Band Bytestream data packet. 049 * 050 * @param sessionID unique session ID identifying this In-Band Bytestream 051 * @param seq sequence of this packet in regard to the other data packets 052 * @param data the base64 encoded data contained in this packet 053 */ 054 public DataPacketExtension(String sessionID, long seq, String data) { 055 if (sessionID == null || "".equals(sessionID)) { 056 throw new IllegalArgumentException("Session ID must not be null or empty"); 057 } 058 if (seq < 0 || seq > 65535) { 059 throw new IllegalArgumentException("Sequence must not be between 0 and 65535"); 060 } 061 if (data == null) { 062 throw new IllegalArgumentException("Data must not be null"); 063 } 064 this.sessionID = sessionID; 065 this.seq = seq; 066 this.data = data; 067 } 068 069 /** 070 * Returns the unique session ID identifying this In-Band Bytestream. 071 * 072 * @return the unique session ID identifying this In-Band Bytestream 073 */ 074 public String getSessionID() { 075 return sessionID; 076 } 077 078 /** 079 * Returns the sequence of this packet in regard to the other data packets. 080 * 081 * @return the sequence of this packet in regard to the other data packets. 082 */ 083 public long getSeq() { 084 return seq; 085 } 086 087 /** 088 * Returns the data contained in this packet. 089 * 090 * @return the data contained in this packet. 091 */ 092 public String getData() { 093 return data; 094 } 095 096 /** 097 * Returns the decoded data or null if data could not be decoded. 098 * <p> 099 * The encoded data is invalid if it contains bad Base64 input characters or 100 * if it contains the pad ('=') character on a position other than the last 101 * character(s) of the data. See <a 102 * href="http://xmpp.org/extensions/xep-0047.html#sec">XEP-0047</a> Section 103 * 6. 104 * 105 * @return the decoded data 106 */ 107 public byte[] getDecodedData() { 108 // return cached decoded data 109 if (this.decodedData != null) { 110 return this.decodedData; 111 } 112 113 // data must not contain the pad (=) other than end of data 114 if (data.matches(".*={1,2}+.+")) { 115 return null; 116 } 117 118 // decodeBase64 will return null if bad characters are included 119 this.decodedData = StringUtils.decodeBase64(data); 120 return this.decodedData; 121 } 122 123 public String getElementName() { 124 return ELEMENT_NAME; 125 } 126 127 public String getNamespace() { 128 return InBandBytestreamManager.NAMESPACE; 129 } 130 131 public String toXML() { 132 StringBuilder buf = new StringBuilder(); 133 buf.append("<"); 134 buf.append(getElementName()); 135 buf.append(" "); 136 buf.append("xmlns=\""); 137 buf.append(InBandBytestreamManager.NAMESPACE); 138 buf.append("\" "); 139 buf.append("seq=\""); 140 buf.append(seq); 141 buf.append("\" "); 142 buf.append("sid=\""); 143 buf.append(sessionID); 144 buf.append("\">"); 145 buf.append(data); 146 buf.append("</"); 147 buf.append(getElementName()); 148 buf.append(">"); 149 return buf.toString(); 150 } 151 152}