1 /** 2 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 3 * you may not use this file except in compliance with the License. 4 * You may obtain a copy of the License at 5 * 6 * http://www.apache.org/licenses/LICENSE-2.0 7 * 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 package org.jivesoftware.smackx.bytestreams.ibb.packet; 15 16 import org.jivesoftware.smack.packet.PacketExtension; 17 import org.jivesoftware.smack.util.StringUtils; 18 import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; 19 20 /** 21 * Represents a chunk of data of an In-Band Bytestream within an IQ stanza or a 22 * message stanza 23 * 24 * @author Henning Staib 25 */ 26 public class DataPacketExtension implements PacketExtension { 27 28 /** 29 * The element name of the data packet extension. 30 */ 31 public final static String ELEMENT_NAME = "data"; 32 33 /* unique session ID identifying this In-Band Bytestream */ 34 private final String sessionID; 35 36 /* sequence of this packet in regard to the other data packets */ 37 private final long seq; 38 39 /* the data contained in this packet */ 40 private final String data; 41 42 private byte[] decodedData; 43 44 /** 45 * Creates a new In-Band Bytestream data packet. 46 * 47 * @param sessionID unique session ID identifying this In-Band Bytestream 48 * @param seq sequence of this packet in regard to the other data packets 49 * @param data the base64 encoded data contained in this packet 50 */ DataPacketExtension(String sessionID, long seq, String data)51 public DataPacketExtension(String sessionID, long seq, String data) { 52 if (sessionID == null || "".equals(sessionID)) { 53 throw new IllegalArgumentException("Session ID must not be null or empty"); 54 } 55 if (seq < 0 || seq > 65535) { 56 throw new IllegalArgumentException("Sequence must not be between 0 and 65535"); 57 } 58 if (data == null) { 59 throw new IllegalArgumentException("Data must not be null"); 60 } 61 this.sessionID = sessionID; 62 this.seq = seq; 63 this.data = data; 64 } 65 66 /** 67 * Returns the unique session ID identifying this In-Band Bytestream. 68 * 69 * @return the unique session ID identifying this In-Band Bytestream 70 */ getSessionID()71 public String getSessionID() { 72 return sessionID; 73 } 74 75 /** 76 * Returns the sequence of this packet in regard to the other data packets. 77 * 78 * @return the sequence of this packet in regard to the other data packets. 79 */ getSeq()80 public long getSeq() { 81 return seq; 82 } 83 84 /** 85 * Returns the data contained in this packet. 86 * 87 * @return the data contained in this packet. 88 */ getData()89 public String getData() { 90 return data; 91 } 92 93 /** 94 * Returns the decoded data or null if data could not be decoded. 95 * <p> 96 * The encoded data is invalid if it contains bad Base64 input characters or 97 * if it contains the pad ('=') character on a position other than the last 98 * character(s) of the data. See <a 99 * href="http://xmpp.org/extensions/xep-0047.html#sec">XEP-0047</a> Section 100 * 6. 101 * 102 * @return the decoded data 103 */ getDecodedData()104 public byte[] getDecodedData() { 105 // return cached decoded data 106 if (this.decodedData != null) { 107 return this.decodedData; 108 } 109 110 // data must not contain the pad (=) other than end of data 111 if (data.matches(".*={1,2}+.+")) { 112 return null; 113 } 114 115 // decodeBase64 will return null if bad characters are included 116 this.decodedData = StringUtils.decodeBase64(data); 117 return this.decodedData; 118 } 119 getElementName()120 public String getElementName() { 121 return ELEMENT_NAME; 122 } 123 getNamespace()124 public String getNamespace() { 125 return InBandBytestreamManager.NAMESPACE; 126 } 127 toXML()128 public String toXML() { 129 StringBuilder buf = new StringBuilder(); 130 buf.append("<"); 131 buf.append(getElementName()); 132 buf.append(" "); 133 buf.append("xmlns=\""); 134 buf.append(InBandBytestreamManager.NAMESPACE); 135 buf.append("\" "); 136 buf.append("seq=\""); 137 buf.append(seq); 138 buf.append("\" "); 139 buf.append("sid=\""); 140 buf.append(sessionID); 141 buf.append("\">"); 142 buf.append(data); 143 buf.append("</"); 144 buf.append(getElementName()); 145 buf.append(">"); 146 return buf.toString(); 147 } 148 149 } 150