⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scanmanager.java

📁 一个小公司要求给写的很简单的任务管理系统。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
         * Whether it's been cancelled by stop()         **/        volatile boolean cancelled=false;        /**         * create a new SessionTask.         **/        SessionTask(long scheduleNext) {            delayBeforeNext = scheduleNext;            taskid = taskcount++;        }        /**         * When run() begins, the state is switched to RUNNING.         * When run() ends then:         *      If the task is repeated, the state will be switched         *      to SCHEDULED (because a new task was scheduled).         *      Otherwise the state will be switched to either         *      STOPPED (if it was stopped before it could complete)         *      or COMPLETED (if it completed gracefully)         * This method is used to switch to the desired state and         * send the appropriate notifications.         * When entering the method, we check whether the state is         * STOPPED. If so, we return false - and the SessionTask will         * stop. Otherwise, we switch the state to the desired value.         **/        private boolean notifyStateChange(ScanState newState,String condition) {            synchronized (ScanManager.this) {                if (state == STOPPED || state == CLOSED) return false;                switchState(newState,condition);            }            sendQueuedNotifications();            return true;        }        // Cancels this task.        public boolean cancel() {            cancelled=true;            return super.cancel();        }        /**         * Invoke all directories scanners in sequence. At each         * step, checks to see whether the task should stop.         **/        private boolean execute() {            final String tag = "Scheduled session["+taskid+"]";            try {                if (cancelled) {                    LOG.finer(tag+" cancelled: done");                    return false;                }                if (!notifyStateChange(RUNNING,"scan-running")) {                    LOG.finer(tag+" stopped: done");                    return false;                }                scanAllDirectories();            } catch (Exception x) {                if (LOG.isLoggable(Level.FINEST)) {                    LOG.log(Level.FINEST,                            tag+" failed to scan: "+x,x);                } else if (LOG.isLoggable(Level.FINE)) {                    LOG.fine(tag+" failed to scan: "+x);                }            }            return true;        }        /**         * Schedule an identical task for next iteration.         **/        private boolean scheduleNext() {            final String tag = "Scheduled session["+taskid+"]";            // We need now to reschedule a new task for after 'delayBeforeNext' ms.            try {                LOG.finer(tag+": scheduling next session for "+ delayBeforeNext + "ms");                if (cancelled || !notifyStateChange(SCHEDULED,"scan-scheduled")) {                    LOG.finer(tag+" stopped: do not reschedule");                    return false;                }                final SessionTask nextTask = new SessionTask(delayBeforeNext);                if (!scheduleSession(nextTask,delayBeforeNext)) return false;                LOG.finer(tag+": next session successfully scheduled");            } catch (Exception x) {                if (LOG.isLoggable(Level.FINEST)) {                    LOG.log(Level.FINEST,tag+                            " failed to schedule next session: "+x,x);                } else if (LOG.isLoggable(Level.FINE)) {                    LOG.fine(tag+" failed to schedule next session: "+x);                }            }            return true;        }        /**         * The run method:         * executes scanning logic, the schedule next iteration if needed.         **/        public void run() {            final String tag = "Scheduled session["+taskid+"]";            LOG.entering(SessionTask.class.getName(),"run");            LOG.finer(tag+" starting...");            try {                if (execute()==false) return;                LOG.finer(tag+" terminating - state is "+state+                    ((delayBeforeNext >0)?(" next session is due in "+delayBeforeNext+" ms."):                        " no additional session scheduled"));                // if delayBeforeNext <= 0 we are done, either because the session was                // stopped or because it successfully completed.                if (delayBeforeNext <= 0) {                    if (!notifyStateChange(COMPLETED,"scan-done"))                        LOG.finer(tag+" stopped: done");                    else                        LOG.finer(tag+" completed: done");                    return;                }                // we need to reschedule a new session for 'delayBeforeNext' ms.                scheduleNext();            } finally {                tasklist.remove(this);                LOG.finer(tag+" finished...");                LOG.exiting(SessionTask.class.getName(),"run");            }        }    }    // ---------------------------------------------------------------    // ---------------------------------------------------------------    // ---------------------------------------------------------------    // MBean Notification support    // The methods below are imported from {@link NotificationEmitter}    // ---------------------------------------------------------------    /**     * Delegates the implementation of this method to the wrapped      * {@code NotificationBroadcasterSupport} object.     **/    public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws IllegalArgumentException {        broadcaster.addNotificationListener(listener, filter, handback);    }    /**     * We emit an {@code AttributeChangeNotification} when the {@code State}     * attribute changes.     **/    public MBeanNotificationInfo[] getNotificationInfo() {        return new MBeanNotificationInfo[] {            new MBeanNotificationInfo(new String[] {                AttributeChangeNotification.ATTRIBUTE_CHANGE},                AttributeChangeNotification.class.getName(),                "Emitted when the State attribute changes")            };    }    /**     * Delegates the implementation of this method to the wrapped      * {@code NotificationBroadcasterSupport} object.     **/    public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {        broadcaster.removeNotificationListener(listener);    }    /**     * Delegates the implementation of this method to the wrapped      * {@code NotificationBroadcasterSupport} object.     **/    public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException {        broadcaster.removeNotificationListener(listener, filter, handback);    }    /**     * Returns and increment the sequence number used for     * notifications. We use the same sequence number throughout the      * application - this is why this method is only package protected.     * @return A unique sequence number for the next notification.     */    static synchronized long getNextSeqNumber() {        return seqNumber++;    }    // ---------------------------------------------------------------    // End of MBean Notification support    // ---------------------------------------------------------------    // ---------------------------------------------------------------    // MBeanRegistration support    // The methods below are imported from {@link MBeanRegistration}    // ---------------------------------------------------------------    /**     * Allows the MBean to perform any operations it needs before being     * registered in the MBean server. If the name of the MBean is not     * specified, the MBean can provide a name for its registration. If     * any exception is raised, the MBean will not be registered in the     * MBean server.     * <p>In this implementation, we check that the provided name is     * either {@code null} or equals to {@link #SCAN_MANAGER_NAME}. If it     * isn't then we throw an IllegalArgumentException, otherwise we return     * {@link #SCAN_MANAGER_NAME}.</p>     * <p>This ensures that there will be a single instance of ScanManager     * registered in a given MBeanServer, and that it will always be     * registered with the singleton's {@link #SCAN_MANAGER_NAME}.</p>     * <p>We do not need to check whether an MBean by that name is     *    already registered because the MBeanServer will perform     *    this check just after having called preRegister().</p>     * @param server The MBean server in which the MBean will be registered.     * @param name The object name of the MBean. This name is null if the     * name parameter to one of the createMBean or registerMBean methods in     * the MBeanServer interface is null. In that case, this method must     * return a non-null ObjectName for the new MBean.     * @return The name under which the MBean is to be registered. This value     * must not be null. If the name parameter is not null, it will usually     * but not necessarily be the returned value.     * @throws Exception This exception will be caught by the MBean server and     * re-thrown as an MBeanRegistrationException.     */    public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {        if (name != null) {            if (!SCAN_MANAGER_NAME.equals(name))                throw new IllegalArgumentException(String.valueOf(name));        }        mbeanServer = server;        return SCAN_MANAGER_NAME;    }    // Returns the default configuration filename    static String getDefaultConfigurationFileName() {        // This is a file calles 'jmx-scandir.xml' located        // in the user directory.        final String user = System.getProperty("user.home");        final String defconf = user+File.separator+"jmx-scandir.xml";        return defconf;    }    /**     * Allows the MBean to perform any operations needed after having     * been registered in the MBean server or after the registration has     * failed.     * <p>     * If registration was not successful, the method returns immediately.     * <p>     * If registration is successful, register the {@link ResultLogManager}     * and default {@link ScanDirConfigMXBean}. If registering these     * MBean fails, the {@code ScanManager} state will be switched to      * {@link #close CLOSED}, and postRegister ends there.     * </p>     * <p>Otherwise the {@code ScanManager} will ask the      * {@link ScanDirConfigMXBean} to load its configuration.      * If it succeeds, the configuration will be {@link      * #applyConfiguration applied}. Otherwise, the method simply returns,     * assuming that the user will later create/update a configuration and     * apply it.     * @param registrationDone Indicates whether or not the MBean has been     * successfully registered in the MBean server. The value false means     * that the registration has failed.     */    public void postRegister(Boolean registrationDone) {        if (!registrationDone) return;        Exception test=null;        try {            mbeanServer.registerMBean(log,                    ResultLogManager.RESULT_LOG_MANAGER_NAME);            final String defconf = getDefaultConfigurationFileName();            final String conf = System.getProperty("scandir.config.file",defconf);            final String confname = ScanDirConfig.guessConfigName(conf,defconf);            final ObjectName defaultProfileName =                    makeMBeanName(ScanDirConfigMXBean.class,confname);            if (!mbeanServer.isRegistered(defaultProfileName))                mbeanServer.registerMBean(new ScanDirConfig(conf),                        defaultProfileName);            config = JMX.newMXBeanProxy(mbeanServer,defaultProfileName,                    ScanDirConfigMXBean.class,true);            configmap.put(defaultProfileName,config);        } catch (Exception x) {            LOG.config("Failed to populate MBeanServer: "+x);            close();            return;        }        try {            config.load();        } catch (Exception x) {            LOG.finest("No config to load: "+x);            test = x;        }        if (test == null) {            try {                applyConfiguration(config.getConfiguration());            } catch (Exception x) {                if (LOG.isLoggable(Level.FINEST))                    LOG.log(Level.FINEST,"Failed to apply config: "+x,x);                LOG.config("Failed to apply config: "+x);            }        }    }    // Unregisters all created DirectoryScanners    private void unregisterScanners() throws JMException {        unregisterMBeans(scanmap);    }    // Unregisters all created ScanDirConfigs    private void unregisterConfigs() throws JMException {        unregisterMBeans(configmap);    }    // Unregisters all MBeans named by the given map    private void unregisterMBeans(Map<ObjectName,?> map) throws JMException {        for (ObjectName key : map.keySet()) {            if (mbeanServer.isRegistered(key))                mbeanServer.unregisterMBean(key);            map.remove(key);        }    }    // Unregisters the ResultLogManager.    private void unregisterResultLogManager() throws JMException {        final ObjectName name = ResultLogManager.RESULT_LOG_MANAGER_NAME;        if (mbeanServer.isRegistered(name)) {            mbeanServer.unregisterMBean(name);        }    }    /**     * Allows the MBean to perform any operations it needs before being     * unregistered by the MBean server.     * This implementation also unregisters all the MXBeans     * that were created by this object.     * @throws IllegalStateException if the lock can't be acquire, or if      *         the MBean's state doesn't allow the MBean to be unregistered     *         (e.g. because it's scheduled or running).     * @throws Exception This exception will be caught by the MBean server and     * re-thrown as an MBeanRegistrationException.     */    public void preDeregister() throws Exception {        try {            close();            if (!sequencer.tryAcquire())                throw new IllegalStateException("can't acquire lock");            try {                unregisterScanners();                unregisterConfigs();                unregisterResultLogManager();            } finally {                sequencer.release();            }        } catch (Exception x) {            LOG.log(Level.FINEST,"Failed to unregister: "+x,x);            throw x;        }    }    /**     * Allows the MBean to perform any operations needed after having been     * unregistered in the MBean server.     * Cancels the internal timer - if any.     */    public synchronized void postDeregister() {        if (timer != null) {            try {                timer.cancel();            } catch (Exception x) {                if (LOG.isLoggable(Level.FINEST))                    LOG.log(Level.FINEST,"Failed to cancel timer",x);                else if (LOG.isLoggable(Level.FINE))                    LOG.fine("Failed to cancel timer: "+x);            } finally {                timer = null;            }        }   }    // ---------------------------------------------------------------    // End of MBeanRegistration support    // ---------------------------------------------------------------}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -