net.naonedbus.activity.impl.CommentaireActivity.java Source code

Java tutorial

Introduction

Here is the source code for net.naonedbus.activity.impl.CommentaireActivity.java

Source

/**
 * Copyright (C) 2013 Romain Guefveneu.
 *   
 *  This file is part of naonedbus.
 *   
 *  Naonedbus 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.
 *  
 *  Naonedbus 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 net.naonedbus.activity.impl;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.List;

import net.naonedbus.BuildConfig;
import net.naonedbus.R;
import net.naonedbus.bean.Arret;
import net.naonedbus.bean.Commentaire;
import net.naonedbus.bean.Ligne;
import net.naonedbus.bean.Sens;
import net.naonedbus.manager.impl.ArretManager;
import net.naonedbus.manager.impl.LigneManager;
import net.naonedbus.manager.impl.SensManager;
import net.naonedbus.rest.controller.impl.CommentaireController;
import net.naonedbus.security.KeyType;
import net.naonedbus.security.RSAUtils;
import net.naonedbus.utils.ColorUtils;
import net.naonedbus.utils.InfoDialogUtils;
import net.naonedbus.validator.CommentaireContentTypeValidator;
import net.naonedbus.validator.CommentaireSizeValidator;
import net.naonedbus.validator.CommentaireValidator;
import net.naonedbus.widget.adapter.impl.ArretArrayAdapter;
import net.naonedbus.widget.adapter.impl.LignesArrayAdapter;
import net.naonedbus.widget.adapter.impl.SensArrayAdapter;

import org.apache.http.HttpException;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.bugsense.trace.BugSenseHandler;

public class CommentaireActivity extends SherlockActivity {

    public static final String ACTION_COMMENTAIRE_SENT = "net.naonedbus.action.COMMENTAIRE_SENT";

    public static final String PARAM_LIGNE = "ligne";
    public static final String PARAM_SENS = "sens";
    public static final String PARAM_ARRET = "arret";

    private static final String LOG_TAG = "CommentaireActivity";
    private static final boolean DBG = BuildConfig.DEBUG;

    private static final String BUNDLE_KEY_LIGNE = "ligne";
    private static final String BUNDLE_KEY_SENS = "sens";
    private static final String BUNDLE_KEY_ARRET = "arret";

    private EditText mCommentText;

    private LigneManager mLigneManager;
    private SensManager mSensManager;
    private ArretManager mArretManager;

    private Ligne mLigne;
    private Sens mSens;
    private Arret mArret;

    private Ligne mAllLignes;
    private Sens mAllSens;
    private Arret mAllArrets;

    private View mBtnChangeLigne;
    private View mBtnChangeSens;
    private View mBtnChangeArret;

    private TextView mTextLigne;
    private TextView mTextSens;
    private TextView mTextArret;

    private ListAdapter mLignesAdapter;
    private ListAdapter mSensAdapter;
    private ListAdapter mArretsAdapter;

    private int mSelectedLignePosition;
    private int mSelectedSensPosition;
    private int mSelectedArretPosition;

    private SendTask mSendTask;

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_comment);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mLigneManager = LigneManager.getInstance();
        mSensManager = SensManager.getInstance();
        mArretManager = ArretManager.getInstance();

        mAllLignes = Ligne.buildAllLigneItem(this);
        mAllSens = new Sens(-1, getString(R.string.target_tous_sens));
        mAllArrets = new Arret.Builder().setId(-1).setNomArret(getString(R.string.target_tous_arrets)).build();

        mLignesAdapter = getLignesAdapter();

        mCommentText = (EditText) findViewById(android.R.id.input);
        mTextLigne = (TextView) findViewById(R.id.commentaireLigne);
        mTextSens = (TextView) findViewById(R.id.commentaireSens);
        mTextArret = (TextView) findViewById(R.id.commentaireArret);

        mBtnChangeLigne = findViewById(R.id.commentaireLigneSpinner);
        mBtnChangeLigne.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(final View v) {
                showSelectLigneDialog();
            }
        });
        mBtnChangeSens = findViewById(R.id.commentaireSens);
        mBtnChangeSens.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(final View v) {
                showSelectSensDialog(mLigne.getCode());
            }
        });
        mBtnChangeArret = findViewById(R.id.commentaireArret);
        mBtnChangeArret.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(final View v) {
                showSelectArretDialog(mLigne.getCode(), mSens.code);
            }
        });

        Ligne ligne;
        Sens sens;
        Arret arret;

        if (savedInstanceState != null && savedInstanceState.containsKey(BUNDLE_KEY_LIGNE)) {
            ligne = (Ligne) savedInstanceState.getParcelable(BUNDLE_KEY_LIGNE);
            sens = (Sens) savedInstanceState.getParcelable(BUNDLE_KEY_SENS);
            arret = (Arret) savedInstanceState.getParcelable(BUNDLE_KEY_ARRET);
        } else {
            ligne = getIntent().getParcelableExtra(PARAM_LIGNE);
            sens = getIntent().getParcelableExtra(PARAM_SENS);
            arret = getIntent().getParcelableExtra(PARAM_ARRET);
        }

        if (ligne != null) {
            setLigne(ligne);
        }
        if (sens != null) {
            setSens(sens);
        }
        if (arret != null) {
            setArret(arret);
        }

    }

    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        final MenuInflater menuInflater = getSupportMenuInflater();
        menuInflater.inflate(R.menu.activity_commentaire, menu);

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    protected void onSaveInstanceState(final Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(BUNDLE_KEY_LIGNE, mLigne);
        outState.putParcelable(BUNDLE_KEY_SENS, mSens);
        outState.putParcelable(BUNDLE_KEY_ARRET, mArret);
    }

    @Override
    public boolean onMenuItemSelected(final int featureId, final MenuItem item) {

        switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            break;
        case R.id.menu_send:
            prepareAndSendComment();
            break;
        }
        return super.onMenuItemSelected(featureId, item);
    }

    private ListAdapter getLignesAdapter() {
        final List<Ligne> lignes = mLigneManager.getAll(getContentResolver());
        lignes.add(0, mAllLignes);
        final LignesArrayAdapter adapter = new LignesArrayAdapter(this, lignes);
        adapter.setHideDivider(true);
        return adapter;
    }

    private ListAdapter getSensAdapter(final String codeLigne) {
        final List<Sens> sens = mSensManager.getAll(getContentResolver(), codeLigne);
        sens.add(0, mAllSens);
        return new SensArrayAdapter(this, sens);
    }

    private ListAdapter getArretsAdapter(final String codeLigne, final String codeSens) {
        final List<Arret> arrets = mArretManager.getAll(getContentResolver(), codeLigne, codeSens);
        arrets.add(0, mAllArrets);
        return new ArretArrayAdapter(this, arrets);
    }

    /**
     * Afficher la dialog de slection de la ligne.
     */
    private void showSelectLigneDialog() {
        showSelectDialog(R.string.target_ligne, mLignesAdapter, mSelectedLignePosition,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(final DialogInterface dialog, final int which) {
                        mSelectedLignePosition = which;
                        setLigne((Ligne) mLignesAdapter.getItem(which));
                        dialog.dismiss();
                    }
                });
    }

    /**
     * Afficher la dialog de slection du sens.
     */
    private void showSelectSensDialog(final String codeLigne) {
        if (!codeLigne.equals(mSens.codeLigne) || mSensAdapter == null) {
            mSensAdapter = getSensAdapter(codeLigne);
            mSelectedSensPosition = -1;
        }
        showSelectDialog(R.string.target_sens, mSensAdapter, mSelectedSensPosition,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(final DialogInterface dialog, final int which) {
                        mSelectedSensPosition = which;
                        setSens((Sens) mSensAdapter.getItem(which));
                        dialog.dismiss();
                    }
                });
    }

    /**
     * Afficher la dialog de slection de l'arret.
     */
    private void showSelectArretDialog(final String codeLigne, final String codeSens) {
        if (!(codeLigne.equals(mArret.getCodeLigne()) && codeSens.equals(mArret.getCodeSens()))
                || mArretsAdapter == null) {
            mArretsAdapter = getArretsAdapter(codeLigne, codeSens);
            mSelectedArretPosition = -1;
        }
        showSelectDialog(R.string.target_arret, mArretsAdapter, mSelectedArretPosition,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(final DialogInterface dialog, final int which) {
                        mSelectedArretPosition = which;
                        setArret((Arret) mArretsAdapter.getItem(which));
                        dialog.dismiss();
                    }
                });
    }

    /**
     * Afficher une dialog de selection.
     * 
     * @param title
     *            Le titre
     * @param adapter
     *            L'adapter
     * @param defaultPosition
     *            La position de l'lment slectionn par dfaut
     * @param onClickListener
     *            Le callback
     */
    private void showSelectDialog(final int title, final ListAdapter adapter, final int defaultPosition,
            final DialogInterface.OnClickListener onClickListener) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(title);
        builder.setSingleChoiceItems(adapter, defaultPosition, onClickListener);
        builder.show();
    }

    /**
     * Envoyer le commentaire s'il a pass les test de
     * {@link #validateComment(Commentaire)}
     */
    private void prepareAndSendComment() {
        final Commentaire commentaireItem = new Commentaire();
        if (mArret != null) {
            commentaireItem.setCodeArret(mArret.getCodeArret());
        }
        if (mSens != null) {
            commentaireItem.setCodeSens(mSens.code);
        }
        if (mLigne != null) {
            commentaireItem.setCodeLigne(mLigne.getCode());
        }
        commentaireItem.setMessage(mCommentText.getText().toString().trim());

        if (validateComment(commentaireItem)) {
            sendComment(commentaireItem);
        } else {
            InfoDialogUtils.show(this, R.string.dialog_title_invalid_comment, R.string.msg_warning_send_comment);
        }

    }

    /**
     * Dfinir la ligne du commentaire et changer la valeur du selecteur.
     * 
     * @param ligne
     *            Le nouvelle ligne
     */
    private void setLigne(final Ligne ligne) {
        this.mLigne = ligne;
        mTextLigne.setText(ligne.getLettre());
        mTextLigne.setTextColor(ligne.getCouleurTexte());
        if (ligne.getCouleur() == 0) {
            mTextLigne.setBackgroundResource(R.drawable.item_symbole_back);
        } else {
            mTextLigne.setBackgroundDrawable(ColorUtils.getCircle(ligne.getCouleur()));
        }

        setSens(mAllSens);

        mBtnChangeSens.setEnabled(!ligne.equals(mAllLignes));
    }

    /**
     * Dfinir le sens du commentaire et changer la valeur du selecteur.
     * 
     * @param sens
     *            Le nouveau sens
     */
    private void setSens(final Sens sens) {
        this.mSens = sens;
        mTextSens.setText(sens.text);

        setArret(mAllArrets);

        mBtnChangeArret.setEnabled(!sens.equals(mAllSens));
    }

    /**
     * Dfinir l'arret du commentaire et changer la valeur du selecteur.
     * 
     * @param arret
     *            Le nouvel arret
     */
    private void setArret(final Arret arret) {
        mArret = arret;
        mTextArret.setText(arret.getNomArret());
    }

    /**
     * @return vrai si valid, faux s'il semble louche
     */
    private boolean validateComment(final Commentaire comment) {
        boolean ret = true;
        final List<CommentaireValidator> validators = new ArrayList<CommentaireValidator>();
        validators.add(new CommentaireSizeValidator());
        validators.add(new CommentaireContentTypeValidator());

        for (final CommentaireValidator commentaireValidator : validators) {
            ret &= commentaireValidator.validate(comment.getMessage());
        }

        return ret;
    }

    private void sendComment(final Commentaire commentaire) {
        if (mSendTask == null || mSendTask.getStatus() == AsyncTask.Status.FINISHED) {
            mSendTask = (SendTask) new SendTask().execute(commentaire);
        }
    }

    /**
     * Classe d'envoi du message
     * 
     * @author romain
     * 
     */
    private class SendTask extends AsyncTask<Commentaire, Void, Boolean> {
        private ProgressDialog progressDialog;
        private Exception exception;

        @Override
        protected void onPreExecute() {
            progressDialog = ProgressDialog.show(CommentaireActivity.this, "",
                    getString(R.string.commentaire_action_transmission), true);
            super.onPreExecute();
        }

        @Override
        protected Boolean doInBackground(final Commentaire... args) {
            try {
                final Commentaire messageItem = args[0];

                final PrivateKey privateKey = genKey();
                final String messageHashCode = getMessageHashCode(messageItem, privateKey);

                final CommentaireController commentaireController = new CommentaireController();
                commentaireController.post(messageItem.getCodeLigne(), messageItem.getCodeSens(),
                        messageItem.getCodeArret(), messageItem.getMessage(), messageHashCode);

                return true;

            } catch (final Exception e) {
                this.exception = e;
                return false;
            }
        }

        @Override
        protected void onPostExecute(final Boolean success) {
            progressDialog.dismiss();

            if (!success) {
                final int msgError = (this.exception instanceof HttpException)
                        ? R.string.dialog_content_comment_sending_error
                        : R.string.dialog_content_key_error;

                InfoDialogUtils.show(CommentaireActivity.this, R.string.dialog_title_comment_sending_error,
                        msgError);

                if (DBG)
                    Log.e(LOG_TAG, "Erreur lors de l'envoi du message.", this.exception);
                BugSenseHandler.sendExceptionMessage("Erreur lors de l'envoi du message.", null, this.exception);
            } else {

                final Intent actionCommentaireSent = new Intent(ACTION_COMMENTAIRE_SENT);
                sendBroadcast(actionCommentaireSent);

                setResult(RESULT_OK, null);

                finish();
            }
            super.onPostExecute(success);
        }

        /**
         * Gnrer la cl prive
         */
        private PrivateKey genKey() {
            BigInteger mod;
            BigInteger exp;
            PrivateKey privateKey = null;

            mod = new BigInteger(getApplicationContext().getString(R.string.mod));
            exp = new BigInteger(getApplicationContext().getString(R.string.exp));

            try {
                privateKey = (PrivateKey) RSAUtils.genNaonedbusKey(KeyType.PRIVATE, mod, exp);
            } catch (final GeneralSecurityException e) {
                BugSenseHandler.sendExceptionMessage("Erreur lors de la gnration de la cl.", null, e);
            }

            return privateKey;
        }

        /**
         * Gnrer les hashCode du message
         * 
         * @param messageItem
         * @return
         * @throws GeneralSecurityException
         * @throws UnsupportedEncodingException
         */
        private String getMessageHashCode(final Commentaire messageItem, final PrivateKey privateKey)
                throws UnsupportedEncodingException, GeneralSecurityException {
            String concatHashCode;
            String result = null;

            concatHashCode = RSAUtils.getConcatHashCode(messageItem.getCodeLigne(), messageItem.getCodeSens(),
                    messageItem.getCodeArret(), messageItem.getMessage());

            result = RSAUtils.encryptBase64(concatHashCode, privateKey);
            return result;
        }

    }
}