se.rebootit.android.tagbiljetter.DataParser.java Source code

Java tutorial

Introduction

Here is the source code for se.rebootit.android.tagbiljetter.DataParser.java

Source

/**
 * This file is licensed under the GNU General Public License Version 3
 * For more information, please visit http://www.gnu.org/licenses/gpl.txt
 */

package se.rebootit.android.tagbiljetter;

import java.io.*;
import java.util.*;
import java.util.regex.*;

import javax.xml.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

import org.json.*;

import android.app.*;
import android.content.*;
import android.content.res.*;
import android.content.SharedPreferences.*;
import android.database.*;
import android.net.*;
import android.util.*;

import se.rebootit.android.tagbiljetter.models.*;

public class DataParser {
    Context context = Biljetter.getContext();
    SharedPreferences sharedPreferences = Biljetter.getSharedPreferences();

    ArrayList<TransportCompany> lstCompanies = new ArrayList<TransportCompany>();
    HashSet<FavoriteItem> lstFavorites = new HashSet<FavoriteItem>();

    DataBaseHelper dbHelper = Biljetter.getDataBaseHelper();

    static HashMap<Integer, TransportCompany> mapCompanies = new HashMap<Integer, TransportCompany>();

    /**
     * Scan the phone inbox and look for tickets that we can import
     * @param clearCache   Clear the cache and scan the WHOLE inbox
     */
    public void scanForTickets(boolean clearCache) {
        if (clearCache) {
            Editor e = sharedPreferences.edit();
            e.putLong("lastmessage", 0);
            e.commit();
        }

        Cursor cursor = context.getContentResolver().query(Uri.parse("content://sms/inbox"),
                new String[] { "_id", "thread_id", "address", "person", "date", "body", "type" }, null, null, null);

        int messageCount = cursor.getCount();
        int messageScanned = 0;
        long lastmessage = sharedPreferences.getLong("lastmessage", 0);
        long lastmessagetime = 0;

        if (messageCount > 0) {
            while (cursor.moveToNext()) {
                long messagetime = cursor.getLong(cursor.getColumnIndex("date"));

                if (lastmessagetime == 0) {
                    lastmessagetime = messagetime;
                }

                if (lastmessage >= messagetime) {
                    break;
                }

                String phonenumber = cursor.getString(cursor.getColumnIndex("address"));
                String message = cursor.getString(cursor.getColumnIndex("body"));

                TransportCompany transportCompany = parseMessage(phonenumber, messagetime, message);
                if (transportCompany != null) {
                    int provider = transportCompany.getId();
                    long tickettime;
                    if (transportCompany instanceof TransportCompany_SJ) {
                        tickettime = transportCompany.getTicketTimestamp(message, messagetime);
                    } else {
                        tickettime = transportCompany.getTicketTimestamp(message);
                    }

                    dbHelper.insertTicket(phonenumber, messagetime, message, provider, tickettime);
                }

                messageScanned++;
            }

            Editor e = sharedPreferences.edit();
            e.putLong("lastmessage", lastmessagetime);
            e.commit();
        }
    }

    /**
     * Returns the TransportCompany
     * @param companyid      The companys id number
     */
    public static TransportCompany getCompany(int companyid) {
        try {
            return mapCompanies.get(companyid);
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * Returns the company name
     * @param companyid      The companys id number
     */
    public static String getCompanyName(int companyid) {
        try {
            return mapCompanies.get(companyid).getName();
        } catch (Exception e) {
        }
        return "";
    }

    /**
     * Parse the message and check if it's a valid ticket
     * @param phonenumber   From what number did the sms arrive from?
     * @param timestamp      Timestamp arrived
     * @param message      The message
     */
    public TransportCompany parseMessage(String phonenumber, long timestamp, String message) {
        for (TransportCompany transportCompany : lstCompanies) {
            if (phonenumber.startsWith(transportCompany.getPhoneNumber())) {
                String expr = transportCompany.getTicketFormat();

                Pattern pattern = Pattern.compile(expr,
                        Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE);
                Matcher matcher = pattern.matcher(message);

                if (matcher.matches()) {
                    return transportCompany;
                }
            }
        }

        return null;
    }

    /**
     * Return the list of loaded companies
     */
    @SuppressWarnings("unchecked")
    public ArrayList<TransportCompany> getCompanies() {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        DefaultHandler handler = new TransportCompanyHandler();
        AssetManager assetManager = context.getAssets();
        try {
            InputStream inputStream = assetManager.open("TransportCompanies.xml");
            SAXParser parser = factory.newSAXParser();
            parser.parse(inputStream, handler);
        } catch (Exception e) {
            e.printStackTrace();
        }

        this.lstCompanies.clear();
        this.lstCompanies.addAll((ArrayList) ((TransportCompanyHandler) handler).getCompanies());

        for (TransportCompany transportCompany : this.lstCompanies) {
            mapCompanies.put(transportCompany.getId(), transportCompany);
        }

        Collections.sort(this.lstCompanies, new Comparator<TransportCompany>() {
            public int compare(TransportCompany p1, TransportCompany p2) {
                return p1.getName().compareTo(p2.getName());
            }
        });

        return this.lstCompanies;
    }

    private class TransportCompanyHandler extends DefaultHandler {
        private final ArrayList<TransportCompany> companies = new ArrayList<TransportCompany>();
        private TransportCompany currentCompany;
        private StringBuilder builder;

        public ArrayList<TransportCompany> getCompanies() {
            return this.companies;
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            super.characters(ch, start, length);
            builder.append(ch, start, length);
        }

        @Override
        public void endElement(String uri, String localName, String name) throws SAXException {
            super.endElement(uri, localName, name);
            if (this.currentCompany != null) {
                if (localName.equalsIgnoreCase("company")) {
                    this.companies.add(this.currentCompany);
                }
                builder.setLength(0);
            }
        }

        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
            builder = new StringBuilder();
        }

        @Override
        public void startElement(String uri, String localName, String name, Attributes attributes)
                throws SAXException {
            super.startElement(uri, localName, name, attributes);

            if (localName.equalsIgnoreCase("company")) {
                try {
                    String type = attributes.getValue("type");
                    this.currentCompany = (TransportCompany) Class.forName(type).newInstance();
                } catch (Exception e) {
                    this.currentCompany = new DefaultTransportCompany();
                }
                this.currentCompany.setId(Integer.parseInt(attributes.getValue("id")));
                this.currentCompany.setName(attributes.getValue("name"));
                this.currentCompany.setPhoneNumber(attributes.getValue("phonenumber"));
                this.currentCompany.setLogo(attributes.getValue("logo"));
                this.currentCompany.setEmail(attributes.getValue("email"));
                if (attributes.getValue("textcolor") != null) {
                    this.currentCompany.setTextColor(attributes.getValue("textcolor"));
                }
            } else if (localName.equalsIgnoreCase("area")) {
                String areaCode = attributes.getValue("code");
                String areaName = attributes.getValue("name");
                String areaDescription = attributes.getValue("description");
                TransportArea area = new TransportArea(areaCode, areaName, areaDescription);
                this.currentCompany.addTransportArea(area);
            } else if (localName.equalsIgnoreCase("type")) {
                String typeCode = attributes.getValue("code");
                String typeName = attributes.getValue("name");
                String typeDescription = attributes.getValue("description");
                TicketType type = new TicketType(typeCode, typeName, typeDescription);
                this.currentCompany.addTicketType(type);
            } else if (localName.equalsIgnoreCase("ticket")) {
                String ticketFormat = attributes.getValue("format");
                this.currentCompany.setTicketFormat(ticketFormat);
            }
        }
    }

    /**
     * Write a message to the inbox database
     * @param address   From what phone number
     * @param timestamp   Time of arrival
     * @param body      Body of the message
     * @param read      Is the message read or not?
     */
    public boolean writeSMStoDatabase(String address, long timestamp, String body, int read) {
        ContentValues values = new ContentValues();
        values.put("address", address);
        values.put("date", timestamp);
        values.put("read", read);
        values.put("status", 1);
        values.put("type", 1);
        values.put("seen", read);
        values.put("body", body);

        ContentResolver contentResolver = Biljetter.getContext().getContentResolver();
        contentResolver.insert(Uri.parse("content://sms"), values);

        // Check if the message was saved correctly
        Cursor cursor = contentResolver.query(Uri.parse("content://sms/inbox"),
                new String[] { "_id", "thread_id", "address", "person", "date", "body", "type" }, null, null, null);
        while (cursor.moveToNext()) {
            long msgTimestamp = cursor.getLong(cursor.getColumnIndex("date"));
            String msgAddress = cursor.getString(cursor.getColumnIndex("address"));
            String msgBody = cursor.getString(cursor.getColumnIndex("body"));

            // It's in there! :D
            if (timestamp == msgTimestamp && address.equals(msgAddress) && body.equals(msgBody)) {
                return true;
            }

            // No need to scan the whole inbox.
            if (timestamp >= msgTimestamp) {
                break;
            }
        }

        // It was not...
        return false;
    }

    public static CharSequence readAsset(String asset, Activity activity) {
        BufferedReader in = null;

        try {
            in = new BufferedReader(new InputStreamReader(activity.getAssets().open(asset)));

            String line;
            StringBuilder buffer = new StringBuilder();

            while ((line = in.readLine()) != null) {
                buffer.append(line).append('\n');
            }

            return buffer;
        } catch (IOException e) {
            return "";
        } finally {
            try {
                in.close();
            } catch (Exception e) {
            }
        }
    }

    @SuppressWarnings("unchecked")
    public ArrayList<FavoriteItem> getFavorites() {
        if (this.lstFavorites.size() == 0) {
            try {
                FileInputStream fis = context.openFileInput("favorites");
                ObjectInputStream is = new ObjectInputStream(fis);
                this.lstFavorites = new HashSet<FavoriteItem>((ArrayList<FavoriteItem>) is.readObject());
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        ArrayList<FavoriteItem> list = new ArrayList<FavoriteItem>(this.lstFavorites);
        Collections.sort(list);
        return list;
    }

    public void addFavorite(FavoriteItem item) {
        if (!this.lstFavorites.contains(item)) {
            this.lstFavorites.add(item);
            saveFavorites();

        }
    }

    public void removeFavorite(FavoriteItem item) {
        this.lstFavorites.remove(item);
        saveFavorites();
    }

    public void saveFavorites() {
        try {
            FileOutputStream fos = context.openFileOutput("favorites", Context.MODE_PRIVATE);
            ObjectOutputStream os = new ObjectOutputStream(fos);
            os.writeObject(new ArrayList<FavoriteItem>(this.lstFavorites));
            os.close();
        } catch (Exception e) {

        }
    }
}