IncomingEventForm.java

/**
 * Copyright (c) 2012 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners.
 * See LICENSE.TXT for license information.
 */

package com.nokia.example;

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

import javax.microedition.lcdui.*;
import javax.microedition.pim.*;
import javax.wireless.messaging.*;

// Forms displayed when a message is received
class IncomingEventForm extends Form implements CommandListener {
    private Command acceptCommand, exitCommand, backCommand;
    private TextField number, duration, topic;
    private DateField dateTime;
    private final EventSharingMIDlet parent;
    private Event event;

    IncomingEventForm(EventSharingMIDlet parent, BinaryMessage msg) {
        super("Event Received");
        this.parent = parent;

        backCommand = new Command("Back", Command.BACK, 2);
        exitCommand = new Command("Exit", Command.EXIT, 2);

        addCommand(backCommand);
        addCommand(exitCommand);

        setCommandListener(this);
        parent.enqueueOperation(new LoadEvent(msg));
    }

    public void commandAction(Command cmd, Displayable displayable) {
        if (cmd == acceptCommand) {
            // insert the event in a different thread
            parent.enqueueOperation(new InsertEvent());
        } else if (cmd == exitCommand) {
            parent.notifyDestroyed();
        } else if (cmd == backCommand) {
            parent.showMain();
        }
    }

    // finds a name based on the number in all contact lists
    private String findName(String number) {
        String[] allLists = PIM.getInstance().listPIMLists(PIM.CONTACT_LIST);
        if (allLists.length > 0) {
            String results[] = new String[allLists.length];
            for (int i = 0; i < allLists.length; i++) {
                results[i] = findNameInList(number, allLists[i]);
            }
            // if there is more than one, only the first is returned
            for (int i = 0; i < allLists.length; i++) {
                if (results[i] != null) {
                    return results[i];
                }
            }
        }
        return null;
    }

    // finds a name based on the number in a particular contact list
    // if for some reason it cannot be found, return null
    private String findNameInList(String number, String list) {
        ContactList contactList = null;
        try {
            contactList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_ONLY, list);
            if (contactList.isSupportedField(Contact.TEL) && contactList.isSupportedField(Contact.FORMATTED_NAME)) {
                Contact pattern = contactList.createContact();
                pattern.addString(Contact.TEL, PIMItem.ATTR_NONE, number);
                Enumeration matching = contactList.items(pattern);
                if (matching.hasMoreElements()) {
                    // will only return the first match
                    Contact ci = (Contact) matching.nextElement();
                    // FORMATTED_NAME is mandatory
                    return ci.getString(Contact.FORMATTED_NAME, 0);
                }
            }
        } catch (PIMException e) {
                // just ignore and return null;
        } catch (SecurityException e) {
                // just ignore and return null;
        } finally {
            if (contactList != null) {
                try {
                    contactList.close();
                } catch (PIMException e) {
                    // ignore, nothing can be done here
                }
            }
        }
        return null;
    }

    private class InsertEvent implements Operation {
        public void execute() {
            EventList eventList = null;
            try {
                PIM pim = PIM.getInstance();
                String listNames[] = pim.listPIMLists(PIM.EVENT_LIST);
                if (listNames.length > 0) {
                    eventList = (EventList) pim.openPIMList(PIM.EVENT_LIST, PIM.READ_WRITE, listNames[0]);
                    // Check that the fields are supported
                    if (eventList.isSupportedField(Event.SUMMARY) && eventList.isSupportedField(Event.START)
                        && eventList.isSupportedField(Event.END)) {
                            // event cannot be null at this stage
                            eventList.importEvent(event).commit();
                            parent.showMessage("Event inserted in the local database");
                    }
                } else {
                    parent.showMessage("No Event list found");
                }
            } catch (PIMException e) {
                parent.showMessage(e.getMessage(), IncomingEventForm.this);
            } catch (SecurityException e) {
                parent.showMessage(e.getMessage(), IncomingEventForm.this);
            } finally {
                if (eventList != null) {
                    try {
                        eventList.close();
                    } catch (PIMException e) {
                        // nothing to do here, just ignore
                    }
                }
            }
        }
    }

    // This operations reads an event from a TextMessage
    private class LoadEvent implements Operation {
        private final BinaryMessage msg;

        LoadEvent(BinaryMessage msg) {
            this.msg = msg;
        }

        public void execute() {
            PIMItem items[] = null;
            try {
                items = PIM.getInstance().fromSerialFormat(new ByteArrayInputStream(msg.getPayloadData()), "UTF-8");
            } catch (PIMException e) {
                parent.showMessage(e.getMessage(), IncomingEventForm.this);
            } catch (UnsupportedEncodingException e) {
                // should not happen since UTF-8 is mandatory
            }
            if (items != null && items.length > 0) {
                // let's assume that only one event
                // was contained in the message
                event = (Event) items[0];
                // Sanity check
                int summaryCount = event.countValues(Event.SUMMARY);
                int startCount = event.countValues(Event.START);
                int endCount = event.countValues(Event.END);
                if (summaryCount > 0 && startCount > 0 && endCount > 0) {
                    topic = new TextField("topic", event.getString(Event.SUMMARY, 0), 24, TextField.ANY);
                    String source = msg.getAddress();
                    // assume the message starts with sms:// and has a port number
                    String phoneNumber = source.substring(6, source.lastIndexOf(':'));
                    String sourceName = findName(phoneNumber);

                    if (sourceName != null) {
                        number = new TextField("From", sourceName, 20, TextField.ANY | TextField.UNEDITABLE);
                    } else {
                        number = new TextField("From", phoneNumber, 20, TextField.PHONENUMBER | TextField.UNEDITABLE);
                    }
                    long startDate = event.getDate(Event.START, 0);
                    long length = event.getDate(Event.END, 0) - startDate;
                    // get the length in minutes
                    length /= 60000;
                    dateTime = new DateField("on", DateField.DATE_TIME, TimeZone.getDefault());
                    dateTime.setDate(new Date(startDate));
                    duration = new TextField("duration (min)", "" + length, 24, TextField.ANY);

                    append(number);
                    append(topic);
                    append(dateTime);
                    append(duration);

                    acceptCommand = new Command("Accept", Command.OK, 1);
                    addCommand(acceptCommand);
                } else {
                    append(new StringItem("", "Incoming event was incomplete"));
                }
            } else {
                event = null;
                acceptCommand = null;
                append(new StringItem("", "Error during message decoding"));
            }
        }
    }
}