<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-348  評論-598  文章-0  trackbacks-0
    OtaNotifier.java

    /*
     *
     *
     * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
     * 
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License version
     * 2 only, as published by the Free Software Foundation.
     * 
     * This program is distributed in the hope that it will be useful, but
     * WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     * General Public License version 2 for more details (a copy is
     * included at /legal/license.txt).
     * 
     * You should have received a copy of the GNU General Public License
     * version 2 along with this work; if not, write to the Free Software
     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
     * 02110-1301 USA
     * 
     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
     * Clara, CA 95054 or visit www.sun.com if you need additional
     * information or have any questions.
     
    */

    package com.sun.midp.installer;

    import java.io.IOException;
    import java.io.OutputStream;

    import javax.microedition.io.Connector;
    import javax.microedition.io.HttpConnection;

    import com.sun.midp.configurator.Constants;

    import com.sun.midp.io.Base64;

    import com.sun.midp.io.j2me.http.Protocol;

    import com.sun.midp.midlet.MIDletSuite;

    import com.sun.midp.midlet.MIDletStateHandler;

    import com.sun.midp.midletsuite.MIDletSuiteStorage;

    import com.sun.midp.security.Permissions;
    import com.sun.midp.security.SecurityToken;

    /**
     * This class handles sending installation and deletion notifications as
     * specified by the OTA section of the MIDP 2.0 specification.
     * The delete notifications are only sent when an install notification is
     * sent. The installer will call this class to send the initial install
     * notification, if the notification fails and is a success notification,
     * the notification will be queued, so that the next time a MIDlet from the
     * suite is run, that suite's notification will be retried. The MIDlet
     * state handler will call this class to process install notification retries.
     
    */
    public final class OtaNotifier {
        
    /** Retry delay. */
        
    static final int RETRY_DELAY = 3000// 3 seconds

        
    /** MIDlet property for the install notify URL. */
        
    public static final String NOTIFY_PROP = "MIDlet-Install-Notify";

        
    /** Success message for the suite provider. */
        
    public static final String SUCCESS_MSG = "900 Success";

        
    /** Error message for the suite provider. */
        
    public static final String INSUFFICIENT_MEM_MSG =
            
    "901 Insufficient Memory";

        
    /** Error message for the suite provider. */
        
    public static final String USER_CANCELLED_MSG = "902 User Cancelled";

        
    /** Error message for the suite provider. */
        
    public static final String JAR_SIZE_MISMATCH_MSG = "904 JAR size mismatch";

        
    /** Error message for the suite provider. */
        
    public static final String ATTRIBUTE_MISMATCH_MSG =
            
    "905 Attribute Mismatch";

        
    /** Error message for the suite provider. */
        
    public static final String INVALID_JAD_MSG = "906 Invalid Descriptor";

        
    /** Error message for the suite provider. */
        
    public static final String INVALID_JAR_MSG = "907 Invalid JAR";

        
    /** Error message for the suite provider. */
        
    public static final String INCOMPATIBLE_MSG =
            
    "908 Incompatible Configuration or Profile";

        
    /** Error message for authentication failure. */
        
    public static final String AUTHENTICATION_FAILURE_MSG =
            
    "909 Application authentication failure";

        
    /** Error message for authorization failure. */
        
    public static final String AUTHORIZATION_FAILURE_MSG =
            
    "910 Application authorization failure";

        
    /** Error message for push registration failure. */
        
    public static final String PUSH_REG_FAILURE_MSG =
            
    "911 Push registration failure";

        
    /** Error message for push registration failure. */
        
    public static final String DELETE_NOTIFICATION_MSG =
            
    "912 Deletion Notification";

        
    /** Message to send when a content handler install fails. */
        
    public static final String CONTENT_HANDLER_CONFLICT =
            
    "938 Content handler conflicts with other handlers";

        
    /** Message to send when a content handler install fails. */
        
    public static final String INVALID_CONTENT_HANDLER =
            
    "939 Content handler install failed";

        
    /**
         * Posts a status message back to the provider's URL in JAD.
         * This method will also retry ALL pending delete notifications.
         *
         * 
    @param message status message to post
         * 
    @param suite MIDlet suite object
         * 
    @param proxyUsername if not null, it will be put in the post
         * 
    @param proxyPassword if not null, it will be put in the post
         
    */
        
    public static void postInstallMsgBackToProvider(String message,
                MIDletSuite suite, String proxyUsername, String proxyPassword) {
            String url;
            MIDletSuite callingMidletSuite 
    =
                MIDletStateHandler.getMidletStateHandler().getMIDletSuite();

            
    if (callingMidletSuite == null) {
                
    throw new IllegalStateException("This method can't be called " +
                    
    "before a suite is started.");
            }

            callingMidletSuite.checkIfPermissionAllowed(Permissions.AMS);

            
    // Now, send out install notifications
            url = suite.getProperty(NOTIFY_PROP);
            
    try {
                postMsgBackToProvider(message, url, proxyUsername, proxyPassword);
            } 
    catch (Throwable t) {
                
    if (message == SUCCESS_MSG) {
                    
    // Only queue successful install notifications for retry
                    addInstallNotification(suite.getID(), url);
                }
            }
        }

        
    /**
         * Retry the pending install status message for this suite only.
         * This method will also retry ALL pending delete notifications,
         * if the install notification was retried.
         *
         * 
    @param token security token of the caller
         * 
    @param suite MIDlet suite object
         
    */
        
    public static void retryInstallNotification(SecurityToken token,
                MIDletSuite suite) {
            
    /*
             * Delay any processing so that startup time is not effected.
             
    */
            
    new Thread(new InstallRetryHandler(token, suite)).start();
        }

        
    /**
         * Retry the pending install status message for this suite only.
         * This method will also retry ALL pending delete notifications,
         * if the install notification was retried.
         *
         * 
    @param token security token of the caller
         * 
    @param suite MIDlet suite object
         
    */
        
    static void retryInstallNotificationInternal(SecurityToken token,
                MIDletSuite suite) {
            PendingNotification notification 
    = new PendingNotification();

            token.checkIfPermissionAllowed(Permissions.AMS);

            
    // Now, send out install notifications
            if (suite.getProperty(NOTIFY_PROP) == null) {
                
    return;
            }

            
    if (!getInstallNotificationForRetry(suite.getID(), notification)) {
                
    return;
            }

            
    try {
                Protocol httpConnection 
    = new Protocol();

                httpConnection.openPrim(token, notification.url);
                postMsgBackToProvider(SUCCESS_MSG, httpConnection, 
    nullnull);
                removeInstallNotification(notification.suiteId);
            } 
    catch (Throwable t) {
                
    if (notification.retries >=
                    Constants.MAX_INSTALL_DELETE_NOTIFICATION_RETRIES) {
                    removeInstallNotification(notification.suiteId);
                }
            }

            
    try {
                
    // Send out delete notifications that have been queued, first
                postQueuedDeleteMsgsBackToProvider(nullnull);
            } 
    catch (Throwable t) {
                
    // ignore
            }
        }

        
    /**
         * Posts all queued delete notification messages
         *
         * 
    @param proxyUsername if not null, it will be put in the post
         * 
    @param proxyPassword if not null, it will be put in the post
         
    */
        
    public static void postQueuedDeleteMsgsBackToProvider(
                String proxyUsername, String proxyPassword) {
            PendingNotification[] deleteNotifyList;

            deleteNotifyList 
    = getDeleteNotifications();

            
    for (int i = 0; i < deleteNotifyList.length; i++) {
                
    try {
                    postMsgBackToProvider(DELETE_NOTIFICATION_MSG,
                                          deleteNotifyList[i].url,
                                          proxyUsername, proxyPassword);
                    removeDeleteNotification(deleteNotifyList[i].suiteId);
                } 
    catch (Throwable t) {
                    
    if (deleteNotifyList[i].retries >=
                            Constants.MAX_INSTALL_DELETE_NOTIFICATION_RETRIES) {
                        removeDeleteNotification(deleteNotifyList[i].suiteId);
                    }
                }
            }
        }

        
    /**
         * Posts a status message back to the provider's URL in JAD.
         *
         * 
    @param message status message to post
         * 
    @param url target http url for the status message
         * 
    @param proxyUsername if not null, it will be put in the post
         * 
    @param proxyPassword if not null, it will be put in the post
         *
         * 
    @exception IOException is thrown if any error prevents the
         *            notification from being successful
         
    */
        
    private static void postMsgBackToProvider(String message, String url,
                String proxyUsername, String proxyPassword) 
    throws IOException {
            HttpConnection transaction;

            
    if (url == null) {
                
    return;
            }

            transaction 
    = (HttpConnection)Connector.open(url, Connector.WRITE);

            postMsgBackToProvider(message, transaction, proxyUsername,
                                  proxyPassword);
        }

        
    /**
         * Posts a status message back to the provider's URL in JAD.
         *
         * 
    @param message status message to post
         * 
    @param transaction http connection to use for posting the status message
         * 
    @param proxyUsername if not null, it will be put in the post
         * 
    @param proxyPassword if not null, it will be put in the post
         *
         * 
    @exception IOException is thrown if any error prevents the
         *            notification from being successful
         
    */
        
    private static void postMsgBackToProvider(String message,
                HttpConnection transaction,
                String proxyUsername, String proxyPassword) 
    throws IOException {
            OutputStream out;

            
    try {
                transaction.setRequestMethod(HttpConnection.POST);

                
    if (proxyUsername != null && proxyPassword != null) {
                    transaction.setRequestProperty(
    "Proxy-Authorization",
                        formatAuthCredentials(proxyUsername, proxyPassword));
                }

                out 
    = transaction.openOutputStream();

                
    try {
                    
    int responseCode;

                    out.write(message.getBytes());
                    responseCode 
    = transaction.getResponseCode();
                    
    if (responseCode != HttpConnection.HTTP_OK) {
                        
    throw new IOException("Failed to notify " +
                            transaction.getURL() 
    +
                            
    " HTTP response code: " + responseCode);
                    }
                } 
    finally {
                    out.close();
                }
            } 
    finally {
                transaction.close();
            }
        }

        
    /**
         * Formats the username and password for HTTP basic authentication
         * according RFC 2617.
         *
         * 
    @param username for HTTP authentication
         * 
    @param password for HTTP authentication
         *
         * 
    @return properly formated basic authentication credential
         
    */
        
    private static String formatAuthCredentials(String username,
                                                    String password) {
            
    byte[] data = new byte[username.length() + password.length() + 1];
            
    int j = 0;

            
    for (int i = 0; i < username.length(); i++, j++) {
                data[j] 
    = (byte)username.charAt(i);
            }

            data[j] 
    = (byte)':';
            j
    ++;

            
    for (int i = 0; i < password.length(); i++, j++) {
                data[j] 
    = (byte)password.charAt(i);
            }

            
    return "Basic " + Base64.encode(data, 0, data.length);
        }

        
    /**
         * Retrieves the queued delete notification list. Each element
         * in the array is a URL to send a delete notification to.
         *
         * 
    @return the delete notification list
         
    */
        
    private static synchronized PendingNotification[]
                getDeleteNotifications() {
            PendingNotification[] array 
    =
                
    new PendingNotification[getNumberOfDeleteNotifications()];

            
    if (array.length > 0) {
                
    for (int i = 0; i < array.length; i++) {
                    array[i] 
    = new PendingNotification();
                }

                fillDeleteNotificationListForRetry(array);
            }

            
    return array;
        }

        
    /**
         * Retrieves the number of URLs queued delete in the notification list.
         *
         * 
    @return the number of URLs in the delete notification list
         
    */
        
    private static native int getNumberOfDeleteNotifications();

        
    /**
         * Retrieves the queued delete notification list from storage and
         * increments the retry count of every member of the list.
         *
         * 
    @param list empty delete notification list to fill
         
    */
        
    private static native void fillDeleteNotificationListForRetry(
            PendingNotification[] list);

        
    /**
         * Removes the element from the delete notification list.
         *
         * 
    @param suiteId suite ID of the notification
         
    */
        
    private static native void removeDeleteNotification(int suiteId);

        
    /**
         * Adds an element to the install notification list.
         *
         * 
    @param suiteId suite the notification belongs to
         * 
    @param url url to send the notification to
         
    */
        
    private static native void addInstallNotification(int suiteId,
                                                          String url);

        
    /**
         * Retrieves the URL of suite's install notification from storage and
         * increments the retry count of element.
         *
         * 
    @param suiteId suite ID of the notification
         * 
    @param dest where to put the notification
         *
         * 
    @return true if the notification is found
         
    */
        
    private static native boolean getInstallNotificationForRetry(
            
    int suiteId, PendingNotification dest);

        
    /**
         * Removes the element from the install notification list.
         *
         * 
    @param suiteId suite ID of the notification
         
    */
        
    private static native void removeInstallNotification(int suiteId);
    }

    /** Executes install reties in the background. */
    final class InstallRetryHandler implements Runnable {
        
    /** Security token of the caller. */
        
    private SecurityToken token;

        
    /** MIDlet suite to retry. */
        
    private MIDletSuite suite;

        
    /**
         * Construct a InstallRetryHandler.
         *
         * 
    @param theToken security token of the caller
         * 
    @param theSuite MIDlet suite object
         
    */
        InstallRetryHandler(SecurityToken theToken, MIDletSuite theSuite) {
            token 
    = theToken;
            suite 
    = theSuite;
        }

        
    /** Retries after a short delay. */
        
    public void run() {
            
    try {
                Thread.sleep(OtaNotifier.RETRY_DELAY);
            } 
    catch (InterruptedException ie) {
                
    // ignore
            }

            OtaNotifier.retryInstallNotificationInternal(token, suite);
        }
    }
    /** Pending install or delete notification */
    final class PendingNotification {
        
    /** Number of times the record has been retried. */
        
    int retries;

        
    /** Suite this notification is for. */
        
    int suiteId;

        
    /** URL to post the notification to. */
        String url;

        
    /**
         * Returns a debug string.
         *
         * 
    @return value of each field in a string
         
    */
        
    public String toString() {
            
    return "PendingNotification(suite ID = " + suiteId + ", retries = " +
                retries 
    + ", URL = " + url + ")";
        }
    }


    ---------------------------------------------------------
    專注移動開發

    Android, Windows Mobile, iPhone, J2ME, BlackBerry, Symbian
    posted on 2010-05-10 16:33 TiGERTiAN 閱讀(526) 評論(0)  編輯  收藏 所屬分類: JavaJ2ME
    主站蜘蛛池模板: 免费人妻精品一区二区三区| 美女内射无套日韩免费播放| 国产亚洲色视频在线| 免费人成激情视频在线观看冫| 亚洲婷婷在线视频| 亚洲国产精品毛片av不卡在线 | 中国videos性高清免费| 亚洲系列国产精品制服丝袜第| 免费萌白酱国产一区二区| 久久青草91免费观看| 美女视频黄视大全视频免费的| 亚洲AV无码第一区二区三区| 在线观看人成视频免费| 久久er国产精品免费观看2| 亚洲精品无码少妇30P| 亚洲av无码精品网站| 免费在线一级毛片| 国产精品久久免费| 成在线人免费无码高潮喷水| 亚洲精品天堂成人片AV在线播放 | 亚洲一区二区三区在线观看精品中文| 黄+色+性+人免费| 十八禁在线观看视频播放免费| 亚洲欧美日韩中文高清www777| 亚洲国产成人久久精品动漫| 亚洲AV伊人久久青青草原| 一二三四在线观看免费高清中文在线观看 | 国产成人免费视频| 日本黄页网址在线看免费不卡| 亚洲一区在线视频| 亚洲国产一区二区a毛片| 久久久久亚洲AV综合波多野结衣| 无码高潮少妇毛多水多水免费| 久久精品免费观看国产| jizz在线免费播放| 国产成人高清亚洲一区久久| 在线aⅴ亚洲中文字幕| 亚洲美女视频一区二区三区| 久久亚洲国产欧洲精品一| 亚洲人成影院在线观看| 波多野结衣中文一区二区免费|