Home | History | Annotate | Download | only in packet
      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      */
     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      */
     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      */
     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      */
     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      */
    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 
    120     public String getElementName() {
    121         return ELEMENT_NAME;
    122     }
    123 
    124     public String getNamespace() {
    125         return InBandBytestreamManager.NAMESPACE;
    126     }
    127 
    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