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 + -
显示快捷键?