com.penbase.dma.Dalyo.HTTPConnection.DmaHttpClient.java Source code

Java tutorial

Introduction

Here is the source code for com.penbase.dma.Dalyo.HTTPConnection.DmaHttpClient.java

Source

/**
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.penbase.dma.Dalyo.HTTPConnection;

import android.content.Context;
import android.content.SharedPreferences;

import com.penbase.dma.Common;
import com.penbase.dma.Binary.Binary;
import com.penbase.dma.Constant.Constant;
import com.penbase.dma.Constant.DatabaseTag;
import com.penbase.dma.Constant.ErrorCode;
import com.penbase.dma.Constant.ResourceTag;
import com.penbase.dma.Dalyo.Database.DatabaseAdapter;
import com.penbase.dma.Dalyo.Function.Function;
import com.penbase.dma.View.ApplicationListView;
import com.penbase.dma.View.ApplicationView;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
 * Manages HTTP connection
 */
public class DmaHttpClient {
    private int mLastError = 0;
    private int mErrorCode = 0;

    // Booleans of sending requests
    private boolean mSendBehavior = true;
    private boolean mSendDb = true;
    private boolean mSendDesign = true;
    private boolean mSendResource = true;

    // XML files
    private static StringBuffer sDirectory;
    private static String sDb_XML;
    private String mDesign_XML;
    private String mBehavior_XML;
    private String mResources_XML;

    // Resource file's path
    private static StringBuffer sResourceFilePath;

    private SharedPreferences mPreference;
    private Context mContext;

    public DmaHttpClient(Context context, String login, String id) {
        createFilesPath(login, id);
        mPreference = context.getSharedPreferences(Constant.PREFERENCE, Context.MODE_PRIVATE);
        mContext = context;
    }

    /**
     * Creates directories if necessary
     * @param login
     * @param id
     */
    private void createFilesPath(String login, String id) {
        if (id != null) {
            sDirectory = new StringBuffer(Constant.APPPACKAGE);
            sDirectory.append(Constant.USERDIRECTORY);
            File directory = new File(sDirectory.toString());
            if (!directory.exists()) {
                directory.mkdir();
            }

            sDirectory.append(login).append("/");
            directory = new File(sDirectory.toString());
            if (!directory.exists()) {
                directory.mkdir();
            }

            sResourceFilePath = new StringBuffer(sDirectory);
            sResourceFilePath.append(Constant.RESOURCE);
            File resourceFileDirectory = new File(sResourceFilePath.toString());
            if (!resourceFileDirectory.exists()) {
                resourceFileDirectory.mkdir();
            }

            sDirectory.append(id).append("/");
            directory = new File(sDirectory.toString());
            if (!directory.exists()) {
                directory.mkdir();
            }

            sDb_XML = sDirectory + Constant.DBXML;
            mDesign_XML = sDirectory + Constant.DESIGNXML;
            mBehavior_XML = sDirectory + Constant.BEHAVIORXML;
            mResources_XML = sDirectory + Constant.RESOURCEXML;
        }
    }

    public int GetLastError() {
        return mLastError;
    }

    /**
     * Authenticate process
     * @param login
     * @param password
     * @return
     */
    public String Authentication(String login, String password) {
        StringBuffer loginAction = new StringBuffer("act=login&from=runtime&login=");
        loginAction.append(login);
        loginAction.append("&passwd_md5=");
        loginAction.append(password);
        loginAction.append("&probe=");
        loginAction.append(mPreference.getString(Constant.VERSION, null));
        loginAction.append("&useragent=ANDROID");
        String result = null;
        try {
            byte[] bytes = sendPost(loginAction.toString());
            if (bytes != null) {
                result = new String(bytes, "UTF8");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String getFilesPath() {
        return sDirectory.toString();
    }

    public static String getResourcePath() {
        return sResourceFilePath.toString();
    }

    /**
     * Manages post services
     * @param parameters
     * @return
     */
    public byte[] sendPost(String parameters) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        HttpClient httpClient = new DefaultHttpClient();
        // HttpPost httpPost = new HttpPost(Constant.SECUREDSERVER +
        // parameters);
        HttpPost httpPost = new HttpPost(Constant.SERVER + parameters);
        try {
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            InputStream in = entity.getContent();
            int c;
            byte[] readByte = new byte[32 * 1024];
            while ((c = in.read(readByte)) > 0) {
                bos.write(readByte, 0, c);
            }
            in.close();
            httpPost.abort();
            httpClient.getConnectionManager().shutdown();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (bos.size() > 0) {
            byte[] data = bos.toByteArray();
            String codeStr = "";
            int i = 0;
            int length = data.length;
            while (i < length && data[i] != (int) '\n') {
                codeStr += (char) data[i];
                i++;
            }
            mErrorCode = Integer.valueOf(codeStr);
            if (mErrorCode != ErrorCode.OK) {
                return null;
            } else {
                int newLength = data.length - codeStr.length() - 1;
                byte[] result = new byte[newLength];
                System.arraycopy(data, codeStr.length() + 1, result, 0, result.length);
                return result;
            }
        } else {
            return null;
        }
    }

    /**
     * Creates a parsing object from a string stream or a xml file
     * 
     * @param xmlStream
     * @param xmlFile
     * @return
     */
    public static Document createParseDocument(byte[] xmlStream, File xmlFile) {
        DocumentBuilder docBuild;
        Document document = null;
        ByteArrayInputStream stream = null;
        try {
            docBuild = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            if (xmlStream != null) {
                stream = new ByteArrayInputStream(xmlStream);
                document = docBuild.parse(stream);
            } else if (xmlFile != null) {
                document = docBuild.parse(xmlFile);
            }
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        return document;
    }

    public void checkXmlFiles() {
        if (new File(mDesign_XML).exists()) {
            this.mSendDesign = false;
        }
        if (new File(sDb_XML).exists()) {
            this.mSendDb = false;
        }
        if (new File(mBehavior_XML).exists()) {
            this.mSendBehavior = false;
        }
        if (new File(mResources_XML).exists()) {
            this.mSendResource = false;
        }
    }

    public int getIdDb(File dbXml) {
        Document dbDoc = createParseDocument(null, dbXml);
        Element tagID = (Element) dbDoc.getElementsByTagName(DatabaseTag.DB).item(0);
        return Integer.valueOf(tagID.getAttribute(DatabaseTag.DB_ID));
    }

    /**
     * Gets the design of an application
     * 
     * @return
     */
    public Reader getDesignReader(String urlRequest) throws FileNotFoundException {
        if (mSendDesign) {
            StringBuffer getDesign = new StringBuffer("act=getdesign");
            getDesign.append(urlRequest);
            byte[] bytes = sendPost(getDesign.toString());
            Common.streamToFile(bytes, mDesign_XML, false);
            return new InputStreamReader(new ByteArrayInputStream(bytes));
        } else {
            return new FileReader(new File(mDesign_XML));
        }
    }

    /**
     * Gets the resources of an application
     */
    public void getResource(String urlRequest) {
        if (mSendResource) {
            StringBuffer getResources = new StringBuffer("act=getresources");
            getResources.append(urlRequest);
            byte[] bytes = sendPost(getResources.toString());
            SAXParserFactory spFactory = SAXParserFactory.newInstance();
            SAXParser saxParser;
            try {
                saxParser = spFactory.newSAXParser();
                XMLReader xmlReader = saxParser.getXMLReader();
                EventsHandler eventsHandler = new EventsHandler(urlRequest);
                xmlReader.setContentHandler(eventsHandler);
                xmlReader.parse(new InputSource(new ByteArrayInputStream(bytes)));
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            } catch (SAXException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Common.streamToFile(bytes, mResources_XML, false);
        } else {
            SAXParserFactory spFactory = SAXParserFactory.newInstance();
            SAXParser saxParser;
            try {
                saxParser = spFactory.newSAXParser();
                XMLReader xmlReader = saxParser.getXMLReader();
                EventsHandler eventsHandler = new EventsHandler(urlRequest);
                xmlReader.setContentHandler(eventsHandler);
                xmlReader.parse(new InputSource(new FileInputStream(new File(mResources_XML))));
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            } catch (SAXException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Sax handler to parse xml files
     */
    private class EventsHandler extends DefaultHandler {
        private String mUrlRequest;
        private boolean mWillDownload;

        public EventsHandler(String url) {
            mUrlRequest = url;
            mWillDownload = true;
        }

        @Override
        public void startDocument() throws SAXException {

        }

        @Override
        public void endDocument() throws SAXException {

        }

        public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
                throws SAXException {
            if (localName.equals(ResourceTag.RESOURCES_R)) {
                String id = atts.getValue(ResourceTag.RESOURCES_R_ID);
                String hashcode = atts.getValue(ResourceTag.RESOURCES_R_HASHCODE);
                String ext = atts.getValue(ResourceTag.RESOURCES_R_EXT);
                StringBuffer fileName = new StringBuffer(sResourceFilePath);
                fileName.append("/");
                fileName.append(id);
                fileName.append(".");
                fileName.append(ext);
                File resourceFile = new File(fileName.toString());
                if (resourceFile.exists()) {
                    byte[] bytes = null;
                    try {
                        bytes = Common.getBytesFromFile(resourceFile);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    String hexString = Common.md5HexStringFromBytes(bytes);
                    if (hexString.equals(hashcode)) {
                        mWillDownload = false;
                    }
                }
                if (mWillDownload) {
                    StringBuffer getResource = new StringBuffer("act=getresource");
                    getResource.append(mUrlRequest);
                    getResource.append("&resourceid=");
                    getResource.append(id);
                    byte[] resourceStream = sendPost(getResource.toString());
                    String hexString = Common.md5HexStringFromBytes(resourceStream);

                    if (hexString.equals(hashcode)) {
                        Common.streamToFile(resourceStream, fileName.toString(), true);
                    }
                }
            }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {

        }

        @Override
        public void endElement(String namespaceURI, String localName, String qName) throws SAXException {

        }
    }

    /**
     * Gets the DB of an application
     * 
     * @return
     */
    public Document getDB(String urlRequest) {
        if (mSendDb) {
            StringBuffer getDB = new StringBuffer("act=getdb");
            getDB.append(urlRequest);
            byte[] bytes = sendPost(getDB.toString());
            Common.streamToFile(bytes, sDb_XML, false);
            return createParseDocument(bytes, null);
        } else {
            return createParseDocument(null, new File(sDb_XML));
        }
    }

    /**
     * Gets the behavior of an application
     * 
     * @return
     */
    public Document getBehavior(String urlRequest) {
        if (mSendBehavior) {
            StringBuffer getBehavior = new StringBuffer("act=getbehavior");
            getBehavior.append(urlRequest);
            byte[] bytes = sendPost(getBehavior.toString());
            Common.streamToFile(bytes, mBehavior_XML, false);
            return createParseDocument(bytes, null);
        } else {
            return createParseDocument(null, new File(mBehavior_XML));
        }
    }

    /**
     * Imports data
     * 
     * @param AppId
     * @param DbId
     * @param login
     * @param pwd
     * @param tables
     * @param filters
     * @return
     */
    @SuppressWarnings("unchecked")
    public boolean importData(String AppId, String DbId, String login, String pwd, ArrayList<String> tables,
            Object filters) {
        if (ApplicationListView.getNetworkInfo() == null) {
            return false;
        } else {
            boolean result = false;
            String syncUrlRequest = generateSyncUrlRequest(AppId, DbId, login, pwd);
            StringBuffer ask = new StringBuffer("act=ask");
            ask.append(syncUrlRequest);
            StringBuffer getBlob = new StringBuffer("act=getblob");
            getBlob.append(syncUrlRequest);
            StringBuffer report = new StringBuffer("act=rep");
            report.append(syncUrlRequest);

            if (filters != null) {
                int filtersSize = ((ArrayList<?>) filters).size();
                if (filtersSize > 0) {
                    ask.append("&fcount=");
                    ask.append(filtersSize);
                    for (int i = 0; i < filtersSize; i++) {
                        ArrayList<Object> filter = (ArrayList<Object>) ((ArrayList<Object>) filters).get(i);
                        ask.append("&ff");
                        ask.append(i);
                        ask.append("=");
                        ask.append(filter.get(0).toString());
                        ask.append("&fo");
                        ask.append(i);
                        ask.append("=");
                        ask.append(urlEncode(Function.getOperatorForImport(filter.get(1))));
                        ask.append("&fv");
                        ask.append(i);
                        ask.append("=");
                        ask.append(filter.get(2).toString());
                    }
                }
            }
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DmaHttpBinarySync importSync = null;
            try {
                if (tables != null) {
                    int tablesNb = tables.size();
                    baos.write(Binary.intToByteArray(tablesNb));
                    for (int i = 0; i < tablesNb; i++) {
                        baos.write(Binary.intToByteArray(Integer.valueOf(tables.get(i))));
                    }
                } else {
                    ArrayList<Integer> importTableList = DatabaseAdapter.getImportTableId();
                    baos.write(Binary.intToByteArray(importTableList.size()));
                    for (int id : importTableList) {
                        baos.write(Binary.intToByteArray(id));
                    }
                }
                byte[] inputbytes = baos.toByteArray();
                importSync = new DmaHttpBinarySync(mContext, ask.toString(), getBlob.toString(), report.toString(),
                        inputbytes, Constant.IMPORTACTION);
                result = importSync.run();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }
    }

    /**
     * Exports local data to server
     * 
     * @param AppId
     * @param DbId
     * @param login
     * @param pwd
     * @param tables
     * @param filters
     * @return
     */
    public boolean exportData(String AppId, String DbId, String login, String pwd, ArrayList<String> tables,
            Object filters) {
        if (ApplicationListView.getNetworkInfo() == null) {
            return false;
        } else {
            String syncUrlRequest = generateSyncUrlRequest(AppId, DbId, login, pwd);
            StringBuffer sync = new StringBuffer("act=sync");
            sync.append(syncUrlRequest);
            StringBuffer send = new StringBuffer("act=send");
            send.append(syncUrlRequest);
            StringBuffer commit = new StringBuffer("act=commit");
            commit.append(syncUrlRequest);

            byte[] exportData = ApplicationView.getDataBase().syncExportTable(tables, filters);
            DmaHttpBinarySync exportSync = new DmaHttpBinarySync(mContext, sync.toString(), send.toString(),
                    commit.toString(), exportData, Constant.EXPORTACTION);
            return exportSync.run();
        }
    }

    /**
     * Encodes a given string
     * @param s
     * @return
     */
    private String urlEncode(String s) {
        String result = "";
        try {
            result = java.net.URLEncoder.encode(s, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * Generates synchronization url request
     * @param AppId
     * @param DbId
     * @param login
     * @param pwd
     * @return
     */
    private String generateSyncUrlRequest(String AppId, String DbId, String login, String pwd) {
        StringBuffer result = new StringBuffer("&from=runtime&appid=");
        result.append(AppId);
        result.append("&dataid=");
        result.append(DbId);
        result.append("&login=");
        result.append(login);
        result.append("&passwd_md5=");
        result.append(pwd);
        result.append("&probe=");
        result.append(mPreference.getString(Constant.VERSION, null));
        result.append("&stream=1&useragent=ANDROID&did=");
        result.append(mPreference.getString(Constant.DEVICEID, null));
        return result.toString();
    }

    /**
     * Generates regular url request
     * @param AppId
     * @param AppVer
     * @param AppBuild
     * @param SubId
     * @param login
     * @param pwd
     * @return
     */
    public String generateRegularUrlRequest(String AppId, String AppVer, String AppBuild, String SubId,
            String login, String pwd) {
        StringBuffer result = new StringBuffer("&from=runtime&appid=");
        result.append(AppId);
        result.append("&appversion=");
        result.append(AppVer);
        result.append("&appbuild=");
        result.append(AppBuild);
        result.append("&subid=");
        result.append(SubId);
        result.append("&did=");
        result.append(mPreference.getString(Constant.DEVICEID, null));
        result.append("&login=");
        result.append(login);
        result.append("&passwd_md5=");
        result.append(pwd);
        result.append("&probe=");
        result.append(mPreference.getString(Constant.VERSION, null));
        result.append("&useragent=ANDROID");
        return result.toString();
    }
}