📄 pushregistryimpl.java
字号:
/* * @(#)PushRegistryImpl.java 1.67 02/10/14 @(#) * * Copyright (c) 2002 Sun Microsystems, Inc. All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. */package com.sun.midp.io.j2me.push;import java.lang.ClassNotFoundException;import com.sun.midp.io.Util;import com.sun.midp.io.HttpUrl;import com.sun.midp.midletsuite.Installer;import com.sun.midp.midlet.Scheduler;import com.sun.midp.midlet.MIDletSuite;import java.io.InterruptedIOException;import java.io.IOException;import javax.microedition.midlet.MIDlet;import javax.microedition.io.Connector;import javax.microedition.io.ConnectionNotFoundException;import com.sun.midp.security.SecurityToken;import com.sun.midp.security.Permissions;import com.sun.midp.security.ImplicitlyTrustedClass;import java.util.Date;import java.util.Timer;import java.util.TimerTask;/** * Inbound push connection watcher. */public class PushRegistryImpl implements Runnable, ImplicitlyTrustedClass { /** This class has a different security domain than the MIDlet suite */ private static SecurityToken classSecurityToken; /** * Flag to control when push launching is permitted. * This flag is set to false by the AMS when installing or removing * MIDlets, when an interruption could compromise the integrity of * the operation. */ private static boolean pushEnabled = true; /** * Run the polling loop to check for inbound connections. */ public void run() { long fd = -1; int ret = 0; while (true) { try { if (pushEnabled && (fd = poll0(System.currentTimeMillis())) != -1) { if (fd != -1) { byte[] registryEntry = new byte[512]; if ((ret = getMIDlet0(fd, registryEntry, 512)) == 0) { String name = Util.toJavaString(registryEntry); launchEntry(name); } else { // NYI - can't find entry after successful poll } } } Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } } /** * Parse the registration entry and launch the associtated * <code>MIDlet</code>. * @param name registration string for connection and * <code>MIDlet</code> to be launched */ protected void launchEntry(String name) { String conn; String midlet; String filter; String storage; /* * Parse the comma separated values - * " connection, midlet, filter, storagename" * " midlet, wakeup, storagename" */ int comma1 = name.indexOf(',', 0); int comma2 = name.indexOf(',', comma1 + 1); int comma3 = name.indexOf(',', comma2 + 1); if (comma3 == -1) { /* Alarm was triggered */ conn = null; midlet = name.substring(0, comma1).trim(); storage = name.substring(comma2+1).trim(); } else { conn = name.substring(0, comma1).trim(); midlet = name.substring(comma1+1, comma2).trim(); filter = name.substring(comma2+1, comma3).trim(); storage = name.substring(comma3+1).trim(); } try { boolean okToInterrupt = true; /* * Check to see if the MIDlet is already scheduled. */ Installer installer = Installer.getInstaller(classSecurityToken); Scheduler scheduler = Scheduler.getScheduler(); MIDletSuite current = scheduler.getMIDletSuite(); String root = null; if (current != null) { root = current.getStorageName(); } if ((root != null) && root.equals(storage)) { /* * The storage name matches the current running * MIDlet do not start it. */ if (scheduler.isScheduled(midlet)) { return; } if (!current.permissionToInterrupt(conn)) { // user does not want the interruption if (conn != null) { checkInConnectionInternal(classSecurityToken, conn); } return; } current.saveSettings(); } else { MIDletSuite next = installer.getMIDletSuite(storage); if (next == null) { return; } okToInterrupt = next.permissionToInterrupt(conn); next.saveSettings(); if (!okToInterrupt) { // user does not want the interruption if (conn != null) { checkInConnectionInternal(classSecurityToken, conn); } return; } } /* * Inform the Installer about the MIDlet to run next. * Need to restart the VM to load the next suite. */ installer.execute(storage, midlet); /* * Shutdown all running applications. * NYI, ask the user before doing a forced take down. */ Scheduler.getScheduler().shutdown(); } catch (Exception e) { // Could not launch requested push entry if (conn != null) { checkInConnectionInternal(classSecurityToken, conn); } e.printStackTrace(); } } /** * Register a dynamic connection with the * application management software. Once registered, * the dynamic connection acts just like a * connection preallocated from the descriptor file. * The internal implementation includes the storage name * that uniquely identifies the <code>MIDlet</code>. * * @param connection generic connection <em>protocol</em>, <em>host</em> * and <em>port number</em> * (optional parameters may be included * separated with semi-colons (;)) * @param midlet class name of the <code>MIDlet</code> to be launched, * when new external data is available * @param filter a connection URL string indicating which senders * are allowed to cause the MIDlet to be launched * @exception IllegalArgumentException if the connection string is not * valid * @exception ConnectionNotFoundException if the runtime system does not * support push delivery for the requested * connection protocol * @exception IOException if the connection is already * registered or if there are insufficient resources * to handle the registration request * @exception ClassNotFoundException if the <code>MIDlet</code> class * name can not be found in the current * <code>MIDlet</code> suite * @exception SecurityException if the <code>MIDlet</code> does not * have permission to register a connection * @see #unregisterConnection */ public static void registerConnection(String connection, String midlet, String filter) throws ClassNotFoundException, IOException { Scheduler scheduler = Scheduler.getScheduler(); MIDletSuite midletSuite = scheduler.getMIDletSuite(); /* This method should only be called by scheduled MIDlets. */ if (midletSuite == null) { throw new IllegalStateException("Not in a MIDlet context"); } /* Verify the MIDlet is in the current classpath. */ if (midlet == null || midlet.length() == 0) { throw new ClassNotFoundException("MIDlet missing"); } Class cl = Class.forName(midlet); Class m = Class.forName("javax.microedition.midlet.MIDlet"); if (!m.isAssignableFrom(cl)) { throw new ClassNotFoundException("Not a MIDlet"); } /* Perform the rest of the checks in the internal registry. */ registerConnectionInternal(classSecurityToken, midletSuite, connection, midlet, filter, false); } /** * Check the registration arguments. * @param connection generic connection <em>protocol</em>, <em>host</em> * and <em>port number</em> * (optional parameters may be included * separated with semi-colons (;)) * @param midlet class name of the <code>MIDlet</code> to be launched, * when new external data is available * @param filter a connection URL string indicating which senders * are allowed to cause the MIDlet to be launched * @exception IllegalArgumentException if the connection string is not * valid * @exception ClassNotFoundException if the <code>MIDlet</code> class * name can not be found in the current * <code>MIDlet</code> suite */ static void checkRegistration(String connection, String midlet, String filter) throws ClassNotFoundException { /* Verify the MIDlet is in the current classpath. */ if (midlet == null || midlet.length() == 0) { throw new ClassNotFoundException("MIDlet missing"); } /* Verify that the connection requested is valid. */ if (connection == null || connection.length() == 0) { throw new IllegalArgumentException("Connection missing"); } /* Verify that the filter requested is valid. */ if (filter == null || filter.length() == 0) { throw new IllegalArgumentException("Filter missing"); } int len = filter.length(); for (int i = 0; i < len; i++) { char c = filter.charAt(i); if (!(c == '?' || c == '*' || c == '.' || ('0' <= c && c <= '9'))) { throw new IllegalArgumentException("Filter invalid"); } } } /** * Register a dynamic connection with the * application management software. Once registered, * the dynamic connection acts just like a * connection preallocated from the descriptor file. * The internal implementation includes the storage name * that uniquely identifies the <code>MIDlet</code>. * This method bypasses the class loader specific checks * needed by the <code>Installer</code>. * * @param token security token of the calling class * @param midletSuite MIDlet suite for the suite registering, * the suite only has to implement isRegistered, * checkForPermission, and getStorageName. * @param connection generic connection <em>protocol</em>, <em>host</em> * and <em>port number</em> * (optional parameters may be included * separated with semi-colons (;)) * @param midlet class name of the <code>MIDlet</code> to be launched, * when new external data is available * @param filter a connection URL string indicating which senders * are allowed to cause the MIDlet to be launched * @param bypassChecks if true, bypass the permission checks, * used by the installer when redo old connections during an * aborted update * * @exception IllegalArgumentException if the connection string is not * valid * @exception ConnectionNotFoundException if the runtime system does not * support push delivery for the requested * connection protocol * @exception IOException if the connection is already * registered or if there are insufficient resources * to handle the registration request * @exception ClassNotFoundException if the <code>MIDlet</code> class * name can not be found in the current * <code>MIDlet</code> suite * @exception SecurityException if the <code>MIDlet</code> does not * have permission to register a connection * * @see #unregisterConnection */ public static void registerConnectionInternal(SecurityToken token, MIDletSuite midletSuite, String connection, String midlet, String filter, boolean bypassChecks) throws ClassNotFoundException, IOException { HttpUrl url; String storageName; token.checkIfPermissionAllowed(Permissions.MIDP); if (!bypassChecks) { try { midletSuite.checkForPermission(Permissions.PUSH, null); /* Check the registration arguments. */ checkRegistration(connection, midlet, filter); /* Check if an appropriate MIDlet-<n> record exists. */ if (!midletSuite.isRegistered(midlet)) { throw new ClassNotFoundException("No MIDLet-<n> registration"); } /* * Only socket and datagram connections are supported by * the MIDP 2.0 reference implementation. */ url = new HttpUrl(connection); // Server connections do not have a host if (url.host != null) { throw new ConnectionNotFoundException( "Connection not supported"); } /* * Attempt to open the connection to perform security check * int the context of the current MIDlet suite. */ if (connection.startsWith("socket://")) { if (url.port == -1) { new IllegalArgumentException("Port missing"); } midletSuite.checkForPermission(Permissions.TCP_SERVER, connection); } else if (connection.startsWith("datagram://")) { /* * Check the suite permission for the connection * and close the connection immediately. */ midletSuite.checkForPermission(Permissions.UDP_SERVER, connection); } else { throw new ConnectionNotFoundException( "Connection not supported"); } } catch (InterruptedException ie) { throw new InterruptedIOException( "Interrupted while trying to ask the user permission"); } } storageName = midletSuite.getStorageName(); byte[] asciiRegistration = Util.toCString(connection + "," + midlet + "," + filter + "," + storageName); if (add0(asciiRegistration) == -1) { throw new IOException("Connection already registered"); } } /** * Remove a dynamic connection registration. * * @param connection generic connection <em>protocol</em>, * <em>host</em> and <em>port number</em> * @exception SecurityException if the connection was * not registered by the current <code>MIDlet</code> * suite * @return <code>true</code> if the unregistration was successful, * <code>false</code> the connection was not registered.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -