Package org.jivesoftware.smackx.packet

Source Code of org.jivesoftware.smackx.packet.StreamInitiation$Feature

/**
* $RCSfile$
* $Revision: 2407 $
* $Date: 2004-11-02 17:37:00 -0600 (Tue, 02 Nov 2004) $
*
* Copyright 2003-2004 Jive Software.
*
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.packet;

import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.util.*;
import org.jivesoftware.smackx.*;
import org.jivesoftware.smackx.filetransfer.*;

import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;

/**
*  represents information passed in <si> (stream initiation) packet
*
*@author     Lukasz Wiechec
*@version    1.0
*/

public class StreamInitiation extends IQ {
    private final static String NAMESPACE = "http://jabber.org/protocol/si";
    private final static String PROFILE =
    "http://jabber.org/protocol/si/profile/file-transfer";
   
    private FileDetails fileDetails = null;
    private Feature feature = null;
    private String id = null;
    private int preferred = -1;
   
   
    /**
     *  Creates a new StreamInitiation object and sets a random session id
     */
    public StreamInitiation(int type) {
        this.preferred = type;
        setType(IQ.Type.SET);
        id = StringUtils.randomString(20);
        feature = new Feature(type);
    }
   
    public StreamInitiation()
    {
        this(-1);
    }
   
   
    /**
     *  Returns details about the file in the stream initiation
     *
     *@return    The details of the file in this stream initiation
     */
    public FileDetails getFileDetails() {
        return fileDetails;
    }
   
   
    /**
     *  Sets the file details of the file sent/received in this packet
     *
     *@param  aFile  The new file details
     */
    public void setFileDetails(FileDetails aFile) {
        fileDetails = aFile;
    }
   
    /**
     *  Returns the session id for this packet
     *
     *@return   The session id
     */
    public String getSid() {
        return id;
    }
   
    /**
     *  Sets the feature for this packet
     *
     *@param  aFeature  the new feature
     */
    public void setFeature(Feature aFeature) {
        feature = aFeature;
    }
   
    /**
     * Returns the features of this packet
     *@return Feature of this packet
     */
    public Feature getFeature() { return feature; }
   
    /**
     *  Sets the session id for this packet
     *
     *@param  aID  The new session id
     */
    public void setSid(String aID) {
        id = aID;
    }
   
   
    /**
     *  Returns the XML representation of this packet
     *
     *@return    The XML representation of this packet
     */
    public String getChildElementXML() {
        StringBuffer buf = new StringBuffer();
        buf.append("<si xmlns=\"" + NAMESPACE + "\" profile=\"" + PROFILE + "\"");
        if (id != null) {
            buf.append(" id=\"" + id + "\"");
        }
        buf.append(">");
        if (fileDetails != null) {
            buf.append(fileDetails.getXML());
        }
        if (feature != null) {
            buf.append(feature.getXML());
        }
        buf.append("</si>");
        return buf.toString();
    }
   
   
    /**
     *  helper method for creating "confirmation" <si> messages
     *
     *@return    StreamInitiation message of type RESULT
     */
    public StreamInitiation createConfirmationMessage(int type) {
       
        // prepare a confirmation <si> message; it should have null stream id
        // now we're replying, so to=from and vice versa
        StreamInitiation confirmSI = new StreamInitiation();
        confirmSI.setFrom(getTo());
        confirmSI.setTo(getFrom());
        confirmSI.setType(IQ.Type.RESULT);
        confirmSI.setPacketID(getPacketID());
        Feature feature = new Feature("submit");
        FormField formfield = new FormField("stream-method");
        formfield.setType(null);
       
        if(this.feature.providesBytestreamOption() || type == FileTransferManager.TYPE_SOCKS5)
        {
            formfield.addValue("http://jabber.org/protocol/bytestreams");
        }
        else if(this.feature.providesIBBOption() || type == FileTransferManager.TYPE_IBB);
        {
            formfield.addValue("http://jabber.org/protocol/ibb");
        }
        feature.getDataForm().addField(formfield);
        confirmSI.setFeature(feature);
        confirmSI.setSid(null);
       
        return confirmSI;
    }
   
     /**
     *  helper method for creating "confirmation" <si> messages
     *
     *@return    StreamInitiation message of type RESULT
     */
    public StreamInitiation createConfirmationMessage() {
        return createConfirmationMessage(-1);
    }
   
   
    /**
     *  subclass that carry file information
     */
    public static class FileDetails {
        private File fFile;
        private String fFileName;
        private long fFileSize = 0;
        private String fDescription;
        private String fHash;
        private String fDate = DateTimeUtils.getDateTime();
        private File fDestFile;
       
        /**
         *  Creates a file details based on name, description, size
         *
         *@param  name         The name of the file
         *@param  description  Description of file
         *@param  size         Size of the file
         */
        public FileDetails(String name, String description, long size) {
            fFileSize = size;
            fDescription = description;
            fFileName = name;
        }
       
       
        /**
         *  Creates a file details object based on a <tt>File</tt> object
         *
         *@param  aFile  The file for which to create the details
         */
        public FileDetails(File aFile) {
            fFile = aFile;
            fFileName = aFile.getName();
            fFileSize = aFile.length();
            fHash = createMD5Sum();
            fDestFile = new File(aFile.getName());
        }
       
       
        /**
         *  Creates a FileDetails object based on the location of the file
         *
         *@param  aFilename        The location of the file
         *@throws  FileNotFoundException  if the file cannot be found
         */
        public FileDetails(String aFilename) throws FileNotFoundException {
            fFile = new File(aFilename);
            fFileName = fFile.getName();
            fFileSize = fFile.length();
            fHash = new String();
            fDestFile = new File(aFilename);
        }
       
       
        /**
         *  Gets the name of the file
         *
         *@return    The name of the file
         */
        public String getFileName() {
            return fFileName;
        }
       
       
        /**
         *  Sets the name of the file
         *
         *@param  aFileName  The new name of the file
         */
        public void setFileName(String aFileName) {
            this.fFileName = aFileName;
        }
       
       
        /**
         *  Gets the size of the file
         *
         *@return    The size of the file
         */
        public long getFileSize() {
            return fFileSize;
        }
       
       
        /**
         *  Sets the size of a file
         *
         *@param  aFileSize  The new size of the file
         */
        public void setFileSize(long aFileSize) {
            this.fFileSize = aFileSize;
        }
       
       
        /**
         *  Gets the description of the file
         *
         *@return    The description of the file
         */
        public String getDescription() {
            return fDescription;
        }
       
       
        /**
         *  Sets the description of the file
         *
         *@param  aDescription  The new description
         */
        public void setDescription(String aDescription) {
            this.fDescription = aDescription;
        }
       
       
        /**
         *  Gets the md5 hash of the file
         *
         *@return    The md5 hash of the file, or <tt>null</tt> if it isn't available
         */
        public String getHash() {
            return fHash;
        }
       
       
        /**
         *  Sets the md5 hash of the file
         *
         *@param  aHash  The new md5 hash of the file
         */
        public void setHash(String aHash) {
            this.fHash = aHash;
        }
       
       
        /**
         *  Gets the creation date of the file
         *
         *@return    The creation date of the file, or <tt>null</tt> if it isn't available
         */
        public String getDate() {
            return fDate;
        }
       
       
        /**
         *  Gets the <tt>File</tt> object for this file
         *
         *@return    The <tt>File</tt> for this file, or <tt>null</tt> if it's not available
         */
        public File getFile() {
            return fFile;
        }
       
       
        /**
         *  Sets the <tt>File</tt> object for this file
         *
         *@param  aFile  The <tt>File</tt> object for this file
         */
        public void setFile(File aFile) {
            this.fFile = aFile;
        }
       
       
        /**
         *  Returns the XML representation of this packet
         *
         *@return    Returns the XML representation of this packet
         */
        public String getXML() {
            StringBuffer buf = new StringBuffer();
            buf.append("<file xmlns=\"").append(PROFILE).append("\"");
            if (getFileName() != null) {
                buf.append(" name=\"").append(getFileName()).append("\"");
            }
            if (getFileSize() != 0) {
                buf.append(" size=\"").append(getFileSize()).append("\"");
            }
            if (getDate() != null) {
                buf.append(" date=\"").append(getDate()).append("\"");
            }
            if (getHash() != null) {
                buf.append(" hash=\"").append(getHash()).append("\"");
            }
            buf.append(">");
            if (getDescription() != null) {
                buf.append("<desc>").append(getDescription()).append("</desc>");
            }
            buf.append("</file>");
           
            return buf.toString();
        }
       
       
        /**
         *  returns MD5 sum of a file
         *
         *@return    returns the md5 sum of a file
         */
        public String createMD5Sum() {
            String out = "";
            try {
                byte[] digest;
                MessageDigest md = MessageDigest.getInstance("MD5");
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fFile));
                byte[] buff = new byte[1024];
                int chunk = 1024;
                int bytesRead = 0;
                while ((bytesRead = bis.read(buff, 0, chunk)) != -1) {
                    md.update(buff, 0, bytesRead);
                }
                digest = md.digest();
                String hexChar = null;
                if (digest != null) {
                    for (int i = 0; i < digest.length; i++) {
                        if (digest[i] > 0) {
                            hexChar = Integer.toHexString(digest[i]);
                        } else if (digest[i] < 0) {
                            hexChar = Integer.toHexString(digest[i]).substring(6);
                        } else {
                            hexChar = "00";
                        }
                        out += hexChar;
                    }
                }
                return out;
            } catch (FileNotFoundException e) {
               
                return null;
            } catch (NoSuchAlgorithmException e) {
               
                return null;
            } catch (IOException e) {
            }
           
            return null;
        }
       
    }
   
   
    /**
     *  class that will hold feature information re-using DataForm code to
     *
     */
    public static class Feature {
       
        private final static String BYTESTREAMS_FEATURE =
        "http://jabber.org/protocol/bytestreams";
       
        private final static String IBB_FEATURE = "http://jabber.org/protocol/ibb";
       
        DataForm fDataForm;
        int preferred = -1;
       
       
        /**
         *  Creates the "features" portion of the StreamInitiation packet
         */
        public Feature(int type) {
            this("form");
            preferred = type;
            createForm();
        }
       
        public Feature()
        {
            this(-1);
        }
       
        /**
         * Adds the various data fields to the data form
         **/
        private void createForm() {
            FormField field = new FormField("stream-method");
            field.setType(FormField.TYPE_LIST_SINGLE);
            if(preferred == -1 || preferred == FileTransferManager.TYPE_SOCKS5)
                field.addOption(new FormField.Option("http://jabber.org/protocol/bytestreams"));
            if(preferred == -1 || preferred == FileTransferManager.TYPE_IBB)
                field.addOption(new FormField.Option("http://jabber.org/protocol/ibb"));
            fDataForm.addField(field);
        }
       
       
        /**
         *  Creates the "features" portion of the StreamInitiation object
         *
         *@param  aDataFormType  The type of data form you wish to use for this packet
         */
        public Feature(String aDataFormType) {
           
            fDataForm = new DataForm(aDataFormType);
           
        }
       
        /**
         * Returns the data form for this packet
         *@return the DataForm for this packet
         */
        public DataForm getDataForm() { return fDataForm; }
       
       
        /**
         * Gets the XML representation of this part of the packet
         *
         *@return    the XML representation of this part of the packet
         */
        public String getXML() {
            StringBuffer buf = new StringBuffer();
            buf.append("<feature xmlns=\"http://jabber.org/protocol/feature-neg\">");
            if (fDataForm != null) {
                buf.append(fDataForm.toXML());
            }
            buf.append("</feature>");
           
            return buf.toString();
        }
       
       
        /**
         *  Sets the DataForm to be used
         *
         *@param  fFeatureForm  The new DataForm
         */
        public void setDataForm(DataForm fFeatureForm) {
            this.fDataForm = fFeatureForm;
        }
       
        /**
         *  Determines if this packet supports IBB
         *
         *@return   <tt>true</tt> if this packet supports IBB
         */
        public boolean providesIBBOption() {
            return providesOption(IBB_FEATURE);
        }
       
       
        /**
         *  check if this Feature provides bytestream option this method works
         *  with both "set" and "result" <si> requests, the one in form:
         *
         *@return    <tt>true</tt> if this feature provides bytestreams
         */
        public boolean providesBytestreamOption() {
            return providesOption(BYTESTREAMS_FEATURE);
        }
       
       
        /**
         *  Checks if this packet supports a feature
         *
         *@param  o  The feature to check
         *@return    <tt>true</tt> if the feature is supported
         */
        private boolean providesOption(String o) {
            // check if the caller asks for bytestream feature
            Iterator iFields = fDataForm.getFields();
            while (iFields.hasNext()) {
                FormField field = (FormField) iFields.next();
                if (field.getVariable().equals("stream-method")) {
                    Iterator iOptions = field.getOptions();
                    while (iOptions.hasNext()) {
                        FormField.Option option = (FormField.Option) iOptions.next();
                       
                        if (option.getValue().equals(o)) {
                            return true;
                        }
                    }
                    Iterator iValues = field.getValues();
                    while (iValues.hasNext()) {
                        String value = (String) iValues.next();
                        if (value.equals(o)) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
       
    }
}
TOP

Related Classes of org.jivesoftware.smackx.packet.StreamInitiation$Feature

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.