001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package javax.wireless.messaging;
028:
029: /**
030: * The <code>MessageListener</code> interface provides
031: * a mechanism for the application to be notified
032: * of incoming messages.
033: *
034: * <p>When an incoming message arrives, the <code>notifyIncomingMessage()</code>
035: * method is called. The application MUST retrieve the
036: * message using the <code>receive()</code> method of the
037: * <code>MessageConnection</code>. <code>MessageListener</code> should not call
038: * <code>receive()</code> directly. Instead, it can start a new thread which will
039: * receive the message or call another
040: * method of the application (which is outside of the
041: * listener) that will call <code>receive()</code>. For an example of how to use
042: * MessageListener, see <a href="#example">A Sample MessageListener
043: * Implementation</a>.
044: * </p>
045: * <p>The listener mechanism allows applications to receive
046: * incoming messages without needing to have a thread blocked
047: * in the <code>receive()</code> method call.
048: * </p>
049: * <p>If multiple messages arrive very closely together in time,
050: * the implementation has the option of calling this listener from multiple
051: * threads in parallel. Applications MUST be prepared to handle
052: * this and implement any necessary synchronization as part
053: * of the application code, while obeying the requirements
054: * set for the listener method.
055: * </p>
056: * <a name="example"></a>
057: * <h2>A Sample MessageListener Implementation</h2>
058: * <p>The following sample code illustrates how lightweight and
059: * resource-friendly
060: * a <code>MessageListener</code> can be. In the sample, a separate thread is
061: * spawned to handle message reading.
062: * The MIDlet life cycle is respected by releasing connections and signalling
063: * threads to terminate when the MIDlet is paused or destroyed.</p>
064: * <pre>
065: * // Sample message listener program.
066: * import java.io.IOException;
067: * import javax.microedition.midlet.*;
068: * import javax.microedition.io.*;
069: * import javax.wireless.messaging.*;
070: * public class Example extends MIDlet implements MessageListener {
071: * MessageConnection messconn;
072: * boolean done;
073: * Reader reader;
074: * // Initial tests setup and execution.
075: * public void startApp() {
076: * try {
077: * // Get our receiving port connection.
078: * messconn = (MessageConnection)
079: * Connector.open("sms://:6222");
080: * // Register a listener for inbound messages.
081: * messconn.setMessageListener(this);
082: * // Start a message-reading thread.
083: * done = false;
084: * reader = new Reader();
085: * new Thread(reader).start();
086: * } catch (IOException e) {
087: * // Handle startup errors
088: * }
089: * }
090: * // Asynchronous callback for inbound message.
091: * public void notifyIncomingMessage(MessageConnection conn) {
092: * if (conn == messconn) {
093: * reader.handleMessage();
094: * }
095: * }
096: * // Required MIDlet method - release the connection and
097: * // signal the reader thread to terminate.
098: * public void pauseApp() {
099: * done = true;
100: * try {
101: * messconn.close();
102: * } catch (IOException e) {
103: * // Handle errors
104: * }
105: * }
106: * // Required MIDlet method - shutdown.
107: * // @param unconditional forced shutdown flag
108: * public void destroyApp(boolean unconditional) {
109: * done = true;
110: * try {
111: * messconn.setMessageListener(null);
112: * messconn.close();
113: * } catch (IOException e) {
114: * // Handle shutdown errors.
115: * }
116: * }
117: * // Isolate blocking I/O on a separate thread, so callback
118: * // can return immediately.
119: * class Reader implements Runnable {
120: * private int pendingMessages = 0;
121: *
122: * // The run method performs the actual message reading.
123: * public void run() {
124: * while (!done) {
125: * synchronized(this) {
126: * if (pendingMessages == 0) {
127: * try {
128: * wait();
129: * } catch (Exception e) {
130: * // Handle interruption
131: * }
132: * }
133: * pendingMessages--;
134: * }
135: *
136: * // The benefit of the MessageListener is here.
137: * // This thread could via similar triggers be
138: * // handling other kind of events as well in
139: * // addition to just receiving the messages.
140: *
141: * try {
142: * Message mess = messconn.receive();
143: * } catch (IOException ioe) {
144: * // Handle reading errors
145: * }
146: * }
147: * }
148: *
149: * public synchronized void handleMessage() {
150: * pendingMessages++;
151: * notify();
152: * }
153: *
154: * }
155: * }
156: * </pre>
157: *<p> </p>
158: */
159:
160: public interface MessageListener {
161:
162: /**
163: * Called by the platform when an incoming
164: * message arrives to a <code>MessageConnection</code>
165: * where the application has registered this listener
166: * object.
167: *
168: * <p>This method is called once for each incoming
169: * message to the <code>MessageConnection</code>.
170: * </p>
171: * <p><strong>NOTE</strong>: The implementation of this method MUST
172: * return quickly and MUST NOT perform any extensive
173: * operations. The application SHOULD NOT receive and
174: * handle the message during this method call. Instead, it
175: * should act only as a trigger to start the activity
176: * in the application's own thread.
177: * </p>
178: * @param conn the <code>MessageConnection</code> where the incoming
179: * message has arrived
180: */
181: public void notifyIncomingMessage(MessageConnection conn);
182:
183: }
|