connectioncontroller.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 622 行 · 第 1/2 页
JAVA
622 行
logError("failed to remove " + handlers[i] + ": " + ioex); } } } /** * Disposes a connection controller. * * <p> * Cancels all the reservations and callbacks. * </p> * * <p> * The only thing one MUST do with disposed * <code>ConnectionController</code> is to garbage-collect it. * </p> */ public synchronized void dispose() { for (Iterator it = reservations.getAllReservations().iterator(); it.hasNext(); ) { final ReservationHandler rh = (ReservationHandler) it.next(); rh.cancel(); } reservations.clear(); } /** * Noop permission checker for startup connection reservation. * * IMPL_NOTE: hopefully will go away when we'll get rid of * reservationDescriptorFactory */ private final AccessControlContext noopAccessControlContext = new AccessControlContextAdapter() { public void checkPermissionImpl( String name, String resource, String extraValue) {} }; /** * Reads and reserves connections in persistent store. */ private void reserveConnectionsFromStore() { /* * IMPL_NOTE: currently connection info is stored as plain data. * However, as reservation descriptors should be serializable * for jump, it might be a good idea to store descriptors * directly and thus get rid of reservation factory in * ConnectionController altogether. */ store.listConnections(new Store.ConnectionsConsumer() { public void consume( final int suiteId, final ConnectionInfo [] connections) { for (int i = 0; i < connections.length; i++) { final ConnectionInfo info = connections[i]; try { registerConnection(suiteId, info.midlet, reservationDescriptorFactory.getDescriptor( info.connection, info.filter, noopAccessControlContext)); } catch (ConnectionNotFoundException cnfe) { logError("failed to register " + info + ": " + cnfe); } catch (IOException ioex) { logError("failed to register " + info + ": " + ioex); } } } }); } /** * Reservation listening handler. * * <p> * IMPL_NOTE: invariant is: one instance of a handler per registration * and thus default Object <code>equals</code> and <code>hashCode</code> * should be enough * </p> * * <p> * TODO: think if common code with AlarmRegistry.AlarmTask can be factored * </p> */ final class ReservationHandler implements DataAvailableListener { /** Reservation's app. */ private final MIDPApp midpApp; /** Connection name. */ private final String connectionName; /** Connection filter. */ private final String filter; /** Connection reservation. */ private final ConnectionReservation connectionReservation; /** Cancelation status. */ private boolean cancelled = false; /** * Creates a handler and reserves the connection. * * @param midletSuiteID <code>MIDlet</code> suite ID of reservation * * @param midlet <code>MIDlet</code> suite ID of reservation. * (cannot be <code>null</code>) * * @param reservationDescriptor reservation descriptor * (cannot be <code>null</code>) * * @throws IOException if reservation fails */ ReservationHandler( final int midletSuiteID, final String midlet, final ReservationDescriptor reservationDescriptor) throws IOException { this.midpApp = new MIDPApp(midletSuiteID, midlet); this.connectionName = reservationDescriptor.getConnectionName(); this.filter = reservationDescriptor.getFilter(); this.connectionReservation = reservationDescriptor.reserve(midletSuiteID, midlet, this); } /** * Gets <code>MIDlet</code> suite ID. * * @return <code>MIDlet</code> suite ID */ int getSuiteId() { return midpApp.midletSuiteID; } /** * Gets <code>MIDlet</code> class name. * * @return <code>MIDlet</code> class name */ String getMidlet() { return midpApp.midlet; } /** * Gets connection name. * * @return connection name */ String getConnectionName() { return connectionName; } /** * Gets connection filter. * * @return connection filter */ String getFilter() { return filter; } /** * Cancels reservation. */ void cancel() { cancelled = true; connectionReservation.cancel(); } /** * See {@link ConnectionReservation#hasAvailableData}. * * @return <code>true</code> iff reservation has available data */ boolean hasAvailableData() { return connectionReservation.hasAvailableData(); } /** {@inheritDoc} */ public void dataAvailable() { synchronized (ConnectionController.this) { if (cancelled) { return; } try { lifecycleAdapter.launchMidlet(midpApp.midletSuiteID, midpApp.midlet); } catch (Exception ex) { /* IMPL_NOTE: need to handle _all_ the exceptions. */ /* * TBD: uncomment when logging can be disabled * (not to interfer with unittests) * logError( * "Failed to launch \"" + midpApp.midlet + "\"" + * " (suite ID: " + midpApp.midletSuiteID + "): " + * ex); */ } } } } /** Internal structure that manages needed mappings. */ static final class Reservations { /** Mappings from connection to reservations. */ private final HashMap connection2data = new HashMap(); /** Mappings from suite id to set of reservations. */ private final HashMap suiteId2data = new HashMap(); /** * Adds a reservation into reservations. * * @param reservationHandler reservation to add */ void add(final ReservationHandler reservationHandler) { connection2data.put( reservationHandler.getConnectionName(), reservationHandler); final Set data = getData(reservationHandler.getSuiteId()); if (data != null) { data.add(reservationHandler); } else { final Set d = new HashSet(); d.add(reservationHandler); suiteId2data.put(new Integer(reservationHandler.getSuiteId()), d); } } /** * Removes a reservation from reservations. * * @param reservationHandler reservation to remove */ void remove(final ReservationHandler reservationHandler) { connection2data.remove(reservationHandler.getConnectionName()); getData(reservationHandler.getSuiteId()).remove(reservationHandler); } /** * Queries the reservations by the connection. * * @param connectionName name of connection to query by * (cannot be <code>null</code>) * * @return reservation (<code>null</code> if absent) */ ReservationHandler queryByConnectionName(final String connectionName) { return (ReservationHandler) connection2data.get(connectionName); } /** * Queries the reservations by the suite id. * * @param midletSuiteID <code>MIDlet</code> suite ID to query by * @return collection of <code>ReservationHandler</code>s * (cannot be <code>null</code>) */ Collection queryBySuiteID(final int midletSuiteID) { final Set data = getData(midletSuiteID); return (data == null) ? new HashSet() : data; } /** * Gets all the reservations. * * @return collection of reservations */ Collection getAllReservations() { return connection2data.values(); } /** * Clears all the reservations. */ void clear() { connection2data.clear(); suiteId2data.clear(); } /** * Gets reservation set by suite id. * * @param midletSuiteID <code>MIDlet</code> suite ID * * @return set of reservations or <code>null</code> if absent */ private Set getData(final int midletSuiteID) { return (Set) suiteId2data.get(new Integer(midletSuiteID)); } } /** * Logs error message. * * <p> * TBD: common logging * </p> * * @param message message to log */ private static void logError(final String message) { System.err.println( "ERROR [" + ConnectionController.class.getName() + "]: " + message); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?