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