FileDocCategorySizeDatePackage
WMAFramework.javaAPI DocWireless Messaging API10441Mon Nov 10 21:03:44 GMT 2003wmafw

WMAFramework.java

/*
 *  WMAFramework.java
 *
 *  Author: C. Enrique Ortiz, October 2003
 *
 *  Companion source code to "Advanced Messaging Coding with JSR 120".
 *
 *  Based on original work by C. Enrique Ortiz.
 *
 *  COPYRIGHT All rights reserved Sony Ericsson Mobile Communications AB 2003.
 *  The software is the copyrighted work of Sony Ericsson Mobile Communications AB.
 *  The use of the software is subject to the terms of the end-user license
 *  agreement which accompanies or is included with the software. The software is
 *  provided "as is" and Sony Ericsson specifically disclaim any warranty or
 *  condition whatsoever regarding merchantability or fitness for a specific
 *  purpose, title or non-infringement. No warranty of any kind is made in
 *  relation to the condition, suitability, availability, accuracy, reliability,
 *  merchantability and/or non-infringement of the software provided herein.
 */

package wmafw;

import javax.microedition.lcdui.*;
import javax.microedition.io.Connector;
import javax.wireless.messaging.*;
import java.util.Vector;

/**
 * Implements a WMA-based short messaging framework.
 */
public class WMAFramework implements CommandListener, Runnable, IncomingMessageListener
{
    /************/
    /* General  */
    /************/
    /** Singleton */
    private static WMAFramework instance;
    /** Default Server Port Number */
    private static int DEFAULT_PORT = 5000;
    /** MessageHandler */
    private static NewMessageHandler messageHandler;
    /** Command for thread processing */
    private Command thCmd;
    /** New Message Listener */
    private IncomingMessageListener incomingMessageListener;
    /** WMA Message Connection */
    private MessageConnection mc;

    /**************/
    /* UI related */
    /**************/

    /** LCDUI Display context */
    protected Display display;
    /** Message inbox screen */
    private MessageInboxScreen messageInboxScreen;
    /** Message summary screen */
    private MessageDetailsScreen messageDetailsScreen;
    /** New message screen */
    private NewMessageScreen newMessageScreen;
    /** Return (to caller application) screen */
    private Displayable backScreen;

    /**********************/
    /* Message Containers */
    /**********************/
    private Vector inbox = new Vector();

    /****************************************************/
    /**************** Private Methods *******************/
    /****************************************************/

    /**
     * Constructor.
     * @param d is the display context.
     */
    private WMAFramework(Display d) {
        display = d;

        if (messageInboxScreen == null)
            messageInboxScreen = new MessageInboxScreen(display, this);

        if (messageDetailsScreen == null)
            messageDetailsScreen = new MessageDetailsScreen(display, this);

        if (newMessageScreen == null)
            newMessageScreen = new NewMessageScreen(display, this);
    }

    /**
     * Alerts the user of segmentation error.
     */
    private void alertSegmentationError() {
        // Alert the user...
    }

    /***************************************************/
    /**************** Public Methods *******************/
    /***************************************************/

    /**
     * Returns the singleton instance of the WMAFramework.
     * @param d is the LCDUI Display context.
     * @return the singleton instance of WMAFramework.
     */
    public static WMAFramework getInstance(Display d) {
        if (instance == null) instance = new WMAFramework(d);
        return instance;
    }

    /**
     * Creates a server message connection
     */
    public void createServerConnection() {
        String url;
        if (mc == null) {
            try {

                String p = System.getProperty("WMAFW-ServerPort");
                if (p == null)
                    url = "sms://:"+DEFAULT_PORT;
                else
                    url = "sms://:"+p.trim();

                mc = (MessageConnection) Connector.open(url);
                messageHandler = new NewMessageHandler(mc);
                messageHandler.setIncomingMessageListener(this);
                messageHandler.start();
            } catch (Exception e) {
                System.out.println("createMessageConnection Exception: " + e);
            }
        }
    }

    /**
     * Stops the WMA Framework
     */
    public void stopFramework() {
        instance = null;
        messageInboxScreen = null;
        messageDetailsScreen = null;
        newMessageScreen = null;
        messageHandler.stop();
        messageHandler = null;
        try {
            mc.setMessageListener(null);
            if (mc != null) {
                mc.close();
                mc = null;
            }
        } catch (Exception e) {
            System.out.println("stopFramework Exception: " + e);
        }
    }

    /**
     * Makes the WMAFramework Inbox Screen visible.
     * @param backScreen is the Displayable to return to.
     */
    public void showInbox(Displayable backScreen) {
        this.backScreen = backScreen;
        messageInboxScreen.showScreen(inbox);
    }

    /**
     * Sets the WMAFramework incoming message nofitication listener.
     * @param listener is the NotificationListener to set.
     */
    public void setIncomingMessageListener(IncomingMessageListener listener) {
        incomingMessageListener = listener;
    }

    /**
     *  Command/button listener.
     *  @param c the LCDUI Command to process
     *  @param d the Displayable source of the Command
     */
    public void commandAction(Command c, Displayable d) {
        Thread th = new Thread(this);
        thCmd = c;
        th.start();
    }

    /**
     * Runnable entry point. Processes UI commands, providing all
     * navigation at the application level. Note that navigation at the
     * WMAFramework level is provided by the WMAFramework.
     */
    public void run () {
        if (thCmd == MessageInboxScreen.VIEW) {
            try {
                int i = messageInboxScreen.getMenuSelection();
                if (i != -1) {
                    ShortMessage sm = (ShortMessage) inbox.elementAt(i);
                    messageDetailsScreen.showScreen(sm.from, sm.text);
                }
            } catch (Exception e) {
            }
        } else if (thCmd == MessageInboxScreen.BACK) {
            display.setCurrent(backScreen);

        } else if (thCmd == MessageInboxScreen.RESET) {
            inbox.removeAllElements();
            messageInboxScreen.setInbox(inbox);
        } else if (thCmd == MessageInboxScreen.NEW) {
            newMessageScreen.showScreen("", display.getCurrent());

        } else if (thCmd == MessageDetailsScreen.BACK) {
            messageInboxScreen.showScreen(inbox);

        } else if (thCmd == MessageDetailsScreen.REPLY) {
            newMessageScreen.showScreen(messageDetailsScreen.getFrom(), display.getCurrent());

        } else if (thCmd == NewMessageScreen.BACK) {
            display.setCurrent(newMessageScreen.getBackScreen());

        } else if (thCmd == NewMessageScreen.SEND) {
            sendTextMessage(newMessageScreen.getFieldTo(),newMessageScreen.getFieldMessage());
            display.setCurrent(newMessageScreen.getBackScreen());
        }
    }

    /**
     * Returns the active SMSC used by WMA Framework.
     * @return the active SMSC.
     */
    public String getSMSC() {
        return System.getProperty("wireless.messaging.sms.smsc");
    }

    /**
     * Sends a text message
     * @param address is the receipient's address.
     * @param message is the message to send.
     */
    public void sendTextMessage(String address, String message) {
        if (address.startsWith("sms") == false) {
            address = "sms://"+address;
        }
        try {
            TextMessage tmsg = (TextMessage)mc.newMessage(MessageConnection.TEXT_MESSAGE);
            if (address != null) tmsg.setAddress(address);
            tmsg.setPayloadText(message);
            // Make sure the message can be sent before trying...
            int segcount = mc.numberOfSegments(tmsg);
            if (segcount == 0) {
                //  Message is too long for the underlying protocol...
                alertSegmentationError();
            } else
                //  Send the message.
                mc.send(tmsg);
        } catch(Exception e) {
            //  Handle the exception...
            System.out.println("Exception during sendTextMessage " + e);
        }
    }

    /**
     * Sends a binary message
     * @param address is the receipient's address.
     * @param message is the message to send.
     */
    public void sendBinaryMessage(String address, byte[] message) {
        // To be implemented...
    }

    /****************************************************************/
    /* onTextMessage and onBinaryMessage are the WMA Framework's    */
    /*  incoming message notification callbacks. The framework uses */
    /*  this methods to know when new messages are received.        */
    /****************************************************************/

    /**
     * Notification Listener entry point
     * @param from is the message sender.
     * @param message is the received text message.
     */
    public void onTextMessage(String from, String message) {
        //  1. create, queue, persist message
        ShortMessage sm = new ShortMessage(from, message, null);
        inbox.addElement(sm);
        messageInboxScreen.setInbox(inbox);
        //  2. notify application
        incomingMessageListener.onTextMessage(from, message);
    }

    /**
     * Notification Listener entry point
     * @param from is the message sender.
     * @param message is the received binary message.
     */
    public void onBinaryMessage(String from, byte[] message) {
        //  1. create, queue, persist message
        ShortMessage sm = new ShortMessage(from, null, message);
        inbox.addElement(sm);
        //  2. notify application
        incomingMessageListener.onBinaryMessage(from, message);
    }
}