com.rothconsulting.android.websms.connector.hispeed.ConnectorHispeed.java Source code

Java tutorial

Introduction

Here is the source code for com.rothconsulting.android.websms.connector.hispeed.ConnectorHispeed.java

Source

/*
 * Copyright (C) 2010 Koni
 *
 * This file is only usefull as part of WebSMS.
 *
 * 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.rothconsulting.android.websms.connector.hispeed;

import java.net.HttpURLConnection;
import java.util.ArrayList;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;

import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;

import de.ub0r.android.websms.connector.common.Connector;
import de.ub0r.android.websms.connector.common.ConnectorCommand;
import de.ub0r.android.websms.connector.common.ConnectorSpec;
import de.ub0r.android.websms.connector.common.ConnectorSpec.SubConnectorSpec;
import de.ub0r.android.websms.connector.common.Utils;
import de.ub0r.android.websms.connector.common.Utils.HttpOptions;
import de.ub0r.android.websms.connector.common.WebSMSException;

/**
 * AsyncTask to manage IO to Hispeed API.
 *
 * @author koni
 */
public class ConnectorHispeed extends Connector {
    /** Tag for output. */
    private static final String TAG = "Hispeed.ch";
    /** Login URL. */
    private static String URL_LOGIN = "https://your.hispeed.ch/setcookie.cgi";
    /** SMS URL. */
    private static final String URL_SMS_UPDATE = "https://your.hispeed.ch/glue.cgi?https://messenger.hispeed.ch/walrus/app/login.do?language=de&hostname=your.hispeed.ch";
    /** URL to get balance */
    private static final String URL_SMS_SEND = "https://messenger.hispeed.ch/walrus/app/sms_send.do";
    /** SMS Credit */
    private String SMS_CREDIT = "";
    /** HTTP User agent. */
    private static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.122 Safari/537.36";
    /** SMS Encoding */
    private static final String ENCODING = "UTF-8";
    /** Check whether this connector is bootstrapping. */
    private static boolean inBootstrap = false;
    /** The phone number from parsing the http response */
    /** Only when mobile number is entered, check for sender errors. */
    private static boolean checkForSenderErrors = false;
    /** My Ad-ID */
    private static final String AD_UNITID = "ca-app-pub-5619114666968507/9953800139";
    /** My Analytics-ID */
    private static final String ANALYTICS_ID = "UA-38114228-3";

    GoogleAnalytics analytics;
    Tracker tracker;

    /**
     * {@inheritDoc}
     */
    @Override
    public final ConnectorSpec initSpec(final Context context) {
        final String name = context.getString(R.string.connector_hispeed_name);
        ConnectorSpec c = new ConnectorSpec(name);
        c.setAuthor(context.getString(R.string.connector_hispeed_author));
        c.setBalance("");
        c.setLimitLength(1539);
        c.setAdUnitId(AD_UNITID);
        c.setCapabilities(ConnectorSpec.CAPABILITIES_BOOTSTRAP | ConnectorSpec.CAPABILITIES_UPDATE
                | ConnectorSpec.CAPABILITIES_SEND | ConnectorSpec.CAPABILITIES_PREFS);
        c.addSubConnector("hispeed", c.getName(), SubConnectorSpec.FEATURE_MULTIRECIPIENTS);

        return c;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final ConnectorSpec updateSpec(final Context context, final ConnectorSpec connectorSpec) {
        this.log("************************************************");
        this.log("*** Start updateSpec");
        this.log("************************************************");
        final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context);
        if (p.getBoolean(Preferences.PREFS_ENABLED, false)) {
            if (p.getString(Preferences.PREFS_USER, "").length() > 0 && p.getString(Preferences.PREFS_PASSWORD, "") // .
                    .length() > 0) {
                connectorSpec.setReady();
            } else {
                connectorSpec.setStatus(ConnectorSpec.STATUS_ENABLED);
            }
        } else {
            connectorSpec.setStatus(ConnectorSpec.STATUS_INACTIVE);
        }
        this.log("************************************************");
        this.log("*** End updateSpec");
        this.log("************************************************");
        return connectorSpec;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected final void doBootstrap(final Context context, final Intent intent) throws WebSMSException {
        this.log("************************************************");
        this.log("*** Start doBootstrap");
        this.log("************************************************");
        checkForSenderErrors = false;

        final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context);

        if (inBootstrap) {
            this.log("already in bootstrap: skip bootstrap");
            return;
        }

        this.log("In new bootstrap");

        inBootstrap = true;

        this.log("Enter in new bootstrap");

        String username = p.getString(Preferences.PREFS_USER, "");
        String password = p.getString(Preferences.PREFS_PASSWORD, "");

        ArrayList<BasicNameValuePair> postParameter = new ArrayList<BasicNameValuePair>();
        postParameter.add(new BasicNameValuePair("url", "https://your.hispeed.ch/de/apps/messenger/"));
        postParameter.add(new BasicNameValuePair("redirect", "messenger"));
        postParameter.add(new BasicNameValuePair("mail", username));
        postParameter.add(new BasicNameValuePair("password", password));
        postParameter.add(new BasicNameValuePair("login", ""));
        this.sendData(URL_LOGIN, context, postParameter);

        this.log("************************************************");
        this.log("*** Ende doBootstrap");
        this.log("************************************************");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected final void doUpdate(final Context context, final Intent intent) throws WebSMSException {
        this.log("************************************************");
        this.log("*** Start doUpdate");
        this.log("************************************************");
        this.doBootstrap(context, intent);

        // Google analytics
        if (analytics == null) {
            analytics = GoogleAnalytics.getInstance(context);
        }
        if (tracker == null) {
            tracker = analytics.newTracker(ANALYTICS_ID);
        }
        tracker.send(new HitBuilders.EventBuilder().setCategory(TAG).setAction("doUpdate V4")
                .setLabel("Balance: " + this.getSpec(context).getBalance()).build());

        this.sendData(URL_SMS_UPDATE, context, null); // get credit

        this.getSpec(context).setBalance(this.SMS_CREDIT);

        this.log("************************************************");
        this.log("*** Ende doUpdate");
        this.log("************************************************");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected final void doSend(final Context context, final Intent intent) throws WebSMSException {
        this.log("************************************************");
        this.log("*** Start doSend");
        this.log("************************************************");
        this.doBootstrap(context, intent);

        final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context);

        ConnectorCommand command = new ConnectorCommand(intent);
        // SMS Text
        String text = command.getText();
        this.log("text.length()=" + text.length());
        this.log("text=" + text);

        boolean splitMessage = false;
        if (text != null && text.length() > 160) {
            splitMessage = true;
        }
        this.log("Long SMS. splitMessage=" + splitMessage);

        // SMS Recipients
        String[] to = command.getRecipients();
        if (to == null || to.length > 10) {
            String error = context.getString(R.string.connector_hispeed_max_10_recipients);
            this.log("----- throwing WebSMSException: " + error);
            throw new WebSMSException(error);
        }

        // should registered sender be used?
        String originator = "originatorNone";
        boolean useOriginator = p.getBoolean(Preferences.PREFS_DEFINED_SENDER_NUMBER, false);
        if (useOriginator) {
            originator = "originatorUser";
        }

        ArrayList<BasicNameValuePair> postParameter = new ArrayList<BasicNameValuePair>();
        for (String recipient : to) {
            recipient = this.formatRecipient(recipient);
            this.log("recipient = " + recipient);
            // Building POST parameter
            postParameter = new ArrayList<BasicNameValuePair>();
            postParameter.add(new BasicNameValuePair("hostname", "your.hispeed.ch"));
            postParameter.add(new BasicNameValuePair("action", "send"));
            postParameter.add(new BasicNameValuePair("groupName", "::__DEFAULTGROUP__::"));
            postParameter.add(new BasicNameValuePair("message", text));
            postParameter.add(new BasicNameValuePair("numCount", "" + text.length()));
            postParameter.add(new BasicNameValuePair("sendingMoment", "now"));
            postParameter.add(new BasicNameValuePair("sendDate", ""));
            postParameter.add(new BasicNameValuePair("sendTime", ""));
            postParameter.add(new BasicNameValuePair("notifAddress", "notifNone"));
            postParameter.add(new BasicNameValuePair("originator", originator));
            postParameter.add(new BasicNameValuePair("recipientChecked", "yes"));
            postParameter.add(new BasicNameValuePair("recipient", recipient));
            if (splitMessage) {
                postParameter.add(new BasicNameValuePair("splitMessage", "on"));
            }

            checkForSenderErrors = true;
            this.sendData(URL_SMS_SEND, context, postParameter);
        }

        // Google analytics
        if (analytics == null) {
            analytics = GoogleAnalytics.getInstance(context);
        }
        if (tracker == null) {
            tracker = analytics.newTracker(ANALYTICS_ID);
        }
        tracker.send(new HitBuilders.EventBuilder().setCategory(TAG).setAction("Send SMS V4")
                .setLabel("Absender definiert: " + useOriginator).build());

        inBootstrap = false;

        this.log("************************************************");
        this.log("*** Ende doSend");
        this.log("************************************************");
    }

    /**
     * Sending the SMS
     *
     * @throws WebSMSException
     */
    private void sendData(final String fullTargetURL, final Context context,
            final ArrayList<BasicNameValuePair> postParameter) throws WebSMSException {

        this.log("************************************************");
        this.log("*** Start sendData");
        this.log("************************************************");
        try {

            this.log("URL: " + fullTargetURL);
            // send data
            this.log("prepare: getHttpClient(...)");

            HttpOptions httpOptions = new HttpOptions();
            httpOptions.url = fullTargetURL;
            httpOptions.userAgent = USER_AGENT;
            // httpOptions.encoding = ENCODING;
            httpOptions.trustAll = true;
            this.log("UrlEncodedFormEntity(); POST=" + postParameter);
            if (postParameter != null) {
                httpOptions.postData = new UrlEncodedFormEntity(postParameter, ENCODING);
            }

            this.log("send data: getHttpClient(...)");
            HttpResponse response = Utils.getHttpClient(httpOptions);

            int respStatus = response.getStatusLine().getStatusCode();
            this.log("response status=" + respStatus);
            this.log("response=\n" + response);
            if (respStatus != HttpURLConnection.HTTP_OK) {
                throw new WebSMSException(context, R.string.error_http, "" + respStatus);
            }

            // Headers
            Header[] headers = response.getAllHeaders();
            if (headers != null) {
                for (Header header : headers) {
                    this.log("Head: " + header.getName() + " / " + header.getValue());
                }
            }
            this.log("headers: " + headers);

            this.log("----- Start EntityUtils --");
            String htmlText = EntityUtils.toString(response.getEntity()).trim();
            this.log("htmlText size=" + htmlText.length());
            // this.log("htmlText=" + htmlText);
            this.log("----- End EntityUtils--");

            if (htmlText == null || htmlText.length() == 0) {
                throw new WebSMSException(context, R.string.error_service);
            }

            if (fullTargetURL.equals(URL_SMS_SEND) || fullTargetURL.equals(URL_SMS_UPDATE)) {
                String punkte = this.getPunkte(htmlText, context);

                if (punkte != null && !punkte.equals("")) {
                    this.SMS_CREDIT = punkte;
                }
            }

            this.getSpec(context).setBalance(this.SMS_CREDIT);

            String errorMessage = this.getErrorMessage(htmlText, context);
            if (errorMessage != null && !errorMessage.equals("")) {
                this.log("----- throwing WebSMSException: " + errorMessage);
                throw new WebSMSException(errorMessage);
            }

            htmlText = null;

        } catch (Exception e) {
            Log.e(TAG, null, e);
            throw new WebSMSException(e.getMessage());
        }
        this.log("************************************************");
        this.log("*** Ende sendData");
        this.log("************************************************");

    }

    private String getPunkte(final String htmlText, final Context context) {
        String punkte = "";
        try {
            int index1 = htmlText.indexOf("<td>&nbsp;");
            this.log("++++++++++++++++++++++++ Punkte: index = " + index1);
            if (index1 > 0) {
                String tmpPunkte = htmlText.substring(index1 + 10, index1 + 20);
                this.log("tmpPunkte = " + tmpPunkte);
                if (tmpPunkte != null && tmpPunkte.length() > 0) {
                    int index2 = tmpPunkte.indexOf("</td>");
                    if (index2 > 0) {
                        punkte = tmpPunkte.substring(0, index2);
                    }
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "Error getting Punkte Guthaben. ", e);
        }
        this.log("punkte = " + punkte);
        return punkte;
    }

    private String getErrorMessage(final String htmlText, final Context context) {
        String message = "";
        boolean hasError = false;

        if (checkForSenderErrors && htmlText != null) {
            int indexStartErrorBlockDe = htmlText.indexOf("Die eingegebene Nummer");
            int indexEndeErrorBlockDe = htmlText.indexOf("ist keine g");

            if (indexStartErrorBlockDe > 0 && indexEndeErrorBlockDe > 0) {
                hasError = true;
                this.log("ErrorBlockDe indexStart=" + indexStartErrorBlockDe + ", indexEnd="
                        + indexEndeErrorBlockDe);
            } else {
                int indexStartErrorBlockFr = htmlText.indexOf("Le num");
                int indexEndeErrorBlockFr = htmlText.indexOf("mobile valide");

                if (indexStartErrorBlockFr > 0 && indexEndeErrorBlockFr > 0) {
                    hasError = true;
                    this.log("ErrorBlockFr indexStart=" + indexStartErrorBlockFr + ", indexEnd="
                            + indexEndeErrorBlockFr);
                } else {
                    int indexStartErrorBlockIt = htmlText.indexOf("Il numero");
                    int indexEndeErrorBlockIt = htmlText.indexOf("mobile valido");

                    if (indexStartErrorBlockIt > 0 && indexEndeErrorBlockIt > 0) {
                        hasError = true;
                        this.log("ErrorBlockIt indexStart=" + indexStartErrorBlockIt + ", indexEnd="
                                + indexEndeErrorBlockIt);
                    }
                }
            }
            if (hasError) {
                message = context.getString(R.string.connector_hispeed_error_numbernotvalid);
            }
        }
        this.log("Error Message=" + message);
        return message;
    }

    private String formatRecipient(String recipient) {
        try {
            if (recipient != null) {
                if (recipient.contains("<") && recipient.contains(">")) {
                    int index1 = recipient.indexOf("<");
                    int index2 = recipient.indexOf(">");
                    recipient = recipient.substring(index1 + 1, index2);
                }
                recipient = recipient.replaceAll(" ", "");
                recipient = recipient.replace("+417", "07");
                recipient = recipient.replace("+4107", "07");
                recipient = recipient.replace("+41(0)7", "07");
                recipient = recipient.replace("(0)7", "07");
                recipient = recipient.trim();
            }
        } catch (Exception e) {
            Log.e(TAG, "Error formating Recipient. ", e);
        }
        return recipient;
    }

    /**
     * central logger
     */
    private void log(final String message) {
        // Log.d(TAG, message);
    }
}