Package blackberry.push

Source Code of blackberry.push.PushListener2$MessageProcessor

/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package blackberry.push;

import java.util.Enumeration;
import java.util.Vector;

import net.rim.device.api.io.http.PushInputStream;
import net.rim.device.api.script.ScriptableFunction;
import blackberry.common.push.PushDaemon.SimChangeData;
import blackberry.common.push.PushDaemon.StatusChangeData;
import blackberry.common.push.PushData;
import blackberry.common.push.PushPersistentStore;
import blackberry.push.data.PushDataObject;

/**
*
* The push listener is used to handle pushes opened through openBESPushListener or openBISPushLitener calls.
*
*/
public class PushListener2 {
   
    private boolean _stop;
    private ScriptableFunction _pushCallback;
    private ScriptableFunction _registerCallback;
    private ScriptableFunction _simChangeCallback;
    private Object _callBackLock;
    private Vector _messageQueue;

    /**
     * Constructor
     *
     * @param port
     *            The port to listen on
     * @param queue
     *            The queue to store the push message
     *
     * @param pushCallback
     *            The ScriptableFunction that is invoked when a new push has been received.
     */
    private PushListener2( int port, Vector queue, ScriptableFunction pushCallback ) {
        _messageQueue = queue;
        _pushCallback = pushCallback;
        _callBackLock = new Object();
        _stop = false;
        PushPersistentStore.setLastKnownPort(port); // Keep track of some info between device restarts
    }

    /**
     * Constructor
     *
     * @param port
     *            The port to listen on
     * @param queue
     *            The message queue
     * @param pushCallback
     *            The ScriptableFunction that is invoked when a new push has been received.
     * @param simChangeCallback
     *            The ScriptableFunction that is invoked on a SIM card change (since it has implications on the receiving of
     *            pushes).
     */
    public PushListener2( int port, Vector queue, ScriptableFunction pushCallback, ScriptableFunction simChangeCallback ) {
        this( port, queue, pushCallback );
        _simChangeCallback = simChangeCallback;
        _callBackLock = new Object();
        PushPersistentStore.setLastKnownType(PushService.BES_PUSH); // Keep track of some info between device restarts
    }

    /**
     * Constructor
     *
     * @param port
     *            The port to listen on
     * @param pushCallback
     *            The ScriptableFunction that is invoked when a new push has been received.
     * @param registerCallback
     *            The ScriptableFunction that is invoked when the result of the registration performed during the opening of the
     *            push listener is received.
     * @param simChangeCallback
     *            The ScriptableFunction that is invoked on a SIM card change (since it has implications on the receiving of
     *            pushes).
     */
    public PushListener2( int port, Vector queue, ScriptableFunction pushCallback, ScriptableFunction registerCallback,
            ScriptableFunction simChangeCallback ) {
        this( port, queue, pushCallback, simChangeCallback );
        _registerCallback = registerCallback;
        PushPersistentStore.setLastKnownType(PushService.BIS_PUSH); // Keep track of some info between device restarts
    }

    /**
     * Updates this listener's callbacks to a new ones. Also, if the listener was previously suspended - it will resume.
     *
     * @param pushCallback
     *            the new push callback
     * @param registerCallback
     *            The new register callback
     * @param simChangeCallback
     *            The new SIM change callback
     */
    public void updateCallback( ScriptableFunction pushCallback, ScriptableFunction registerCallback,
            ScriptableFunction simChangeCallback ) {
        synchronized( _callBackLock ) {
            _pushCallback = pushCallback;
            _registerCallback = registerCallback;
            _simChangeCallback = simChangeCallback;
        }
        _stop = false;
        synchronized( _messageQueue ) {
            _messageQueue.notify();
        }
    }

    /**
     * Stops this listener - all connections are closed, all threads are finished. The push listener cannot be restarted once it
     * is stopped - a new instance, listening on the same port, must be created.
     */
    public synchronized void stop() {
        _stop = true;

        // wake the message processor
        synchronized( _messageQueue ) {
            _messageQueue.notify();
        }
    }

    /**
     * Starts the message processing thread.
     */
    public void start() {
        MessageProcessor messageProcessor = new MessageProcessor();
        messageProcessor.start();
    }
   
    /**
     * Private class that creates a thread to process push messages already received by listener thread.
     */
    private final class MessageProcessor extends Thread {
        public void run() {

            while( !_stop ) {

                // check for messages
                synchronized( _messageQueue ) {
                    if( _pushCallback == null || _messageQueue.size() == 0 ) {
                        try {
                            _messageQueue.wait();
                        } catch( Exception e ) {
                            // ignore - check loop
                        }
                    }
                    if( _pushCallback != null && _messageQueue.size() > 0 ) {
                        // process message - one at a time
                        Object message = _messageQueue.elementAt( 0 );
                        processMessage( message );
                        _messageQueue.removeElementAt( 0 );
                    }
                }
            }

            // clean-up any messages that were not processed
            synchronized( _messageQueue ) {
                Enumeration messagesList = _messageQueue.elements();
                PushData message;
                while( messagesList.hasMoreElements() ) {
                    message = (PushData) messagesList.nextElement();
                    message.discard();
                }
                _messageQueue.removeAllElements();
            }
        }

        private void processMessage( Object message ) {
           
            if( message instanceof PushData ) {
                processPushData( (PushData) message );
            } else if( message instanceof SimChangeData ) {
                processSimChange();
            } else if( message instanceof StatusChangeData ) {
                processStatusChange( ( (StatusChangeData) message ).getStatus() );
            }
        }

        /**
         * Processes a created blackberry.push.PushData message
         *
         * @param message
         *            PushData message.
         */
        private void processPushData( PushData message ) {
            // Create PushDataObject Scriptable Object
            PushDataObject pushDataScriptable = new PushDataObject( message );

            try {
                // Invoke callback method
                Object result = null;
                synchronized( _callBackLock ) {
                    result = _pushCallback.invoke( null, new Object[] { pushDataScriptable } );
                }

                // Accept/Decline push message based on return from callback
                if( result instanceof Integer ) {
                    int callbackReply = ( (Integer) result ).intValue();
                    switch( callbackReply ) {
                        case PushDataObject.ACCEPT:
                            message.accept();
                            break;
                        case PushDataObject.DECLINE_USERDCR:
                            message.decline( PushInputStream.DECLINE_REASON_USERDCR );
                            break;
                        case PushDataObject.DECLINE_USERPND:
                            message.decline( PushInputStream.DECLINE_REASON_USERPND );
                            break;
                        case PushDataObject.DECLINE_USERREQ:
                            message.decline( PushInputStream.DECLINE_REASON_USERREQ );
                            break;
                        case PushDataObject.DECLINE_USERRFS:
                            message.decline( PushInputStream.DECLINE_REASON_USERRFS );
                            break;
                        case PushDataObject.DECLINE_USERDCU:
                        default:
                            // should not get here
                            message.decline( PushInputStream.DECLINE_REASON_USERDCU );
                            break;
                    }
                } else {
                    // By default, we'll decline the message
                    message.decline( PushInputStream.DECLINE_REASON_USERDCU );
                }
                message.discard();
            } catch( Exception e ) {
                // do thing
            }
        }

        private void processStatusChange( int result ) {
            if( _registerCallback != null ) {
                Object[] args = new Object[ 1 ];
                args[ 0 ] = new Integer( result );
                try {
                    _registerCallback.invoke( null, args );
                } catch( Exception e ) {
                    // do nothing
                }
            }
        }

        private void processSimChange() {
            try {
                _simChangeCallback.invoke( null, null );
            } catch( Exception e ) {
                // do nothing
            }
        }
    }
}
TOP

Related Classes of blackberry.push.PushListener2$MessageProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.