001/*
002 * Copyright 2012-2015 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.devtools.classpath;
018
019import java.net.URL;
020
021import org.springframework.beans.BeansException;
022import org.springframework.beans.factory.DisposableBean;
023import org.springframework.beans.factory.InitializingBean;
024import org.springframework.boot.devtools.filewatch.FileSystemWatcher;
025import org.springframework.boot.devtools.filewatch.FileSystemWatcherFactory;
026import org.springframework.context.ApplicationContext;
027import org.springframework.context.ApplicationContextAware;
028import org.springframework.util.Assert;
029
030/**
031 * Encapsulates a {@link FileSystemWatcher} to watch the local classpath folders for
032 * changes.
033 *
034 * @author Phillip Webb
035 * @since 1.3.0
036 * @see ClassPathFileChangeListener
037 */
038public class ClassPathFileSystemWatcher
039                implements InitializingBean, DisposableBean, ApplicationContextAware {
040
041        private final FileSystemWatcher fileSystemWatcher;
042
043        private ClassPathRestartStrategy restartStrategy;
044
045        private ApplicationContext applicationContext;
046
047        private boolean stopWatcherOnRestart;
048
049        /**
050         * Create a new {@link ClassPathFileSystemWatcher} instance.
051         * @param fileSystemWatcherFactory a factory to create the underlying
052         * {@link FileSystemWatcher} used to monitor the local file system
053         * @param restartStrategy the classpath restart strategy
054         * @param urls the URLs to watch
055         */
056        public ClassPathFileSystemWatcher(FileSystemWatcherFactory fileSystemWatcherFactory,
057                        ClassPathRestartStrategy restartStrategy, URL[] urls) {
058                Assert.notNull(fileSystemWatcherFactory,
059                                "FileSystemWatcherFactory must not be null");
060                Assert.notNull(urls, "Urls must not be null");
061                this.fileSystemWatcher = fileSystemWatcherFactory.getFileSystemWatcher();
062                this.restartStrategy = restartStrategy;
063                this.fileSystemWatcher.addSourceFolders(new ClassPathFolders(urls));
064        }
065
066        /**
067         * Set if the {@link FileSystemWatcher} should be stopped when a full restart occurs.
068         * @param stopWatcherOnRestart if the watcher should be stopped when a restart occurs
069         */
070        public void setStopWatcherOnRestart(boolean stopWatcherOnRestart) {
071                this.stopWatcherOnRestart = stopWatcherOnRestart;
072        }
073
074        @Override
075        public void setApplicationContext(ApplicationContext applicationContext)
076                        throws BeansException {
077                this.applicationContext = applicationContext;
078        }
079
080        @Override
081        public void afterPropertiesSet() throws Exception {
082                if (this.restartStrategy != null) {
083                        FileSystemWatcher watcherToStop = null;
084                        if (this.stopWatcherOnRestart) {
085                                watcherToStop = this.fileSystemWatcher;
086                        }
087                        this.fileSystemWatcher.addListener(new ClassPathFileChangeListener(
088                                        this.applicationContext, this.restartStrategy, watcherToStop));
089                }
090                this.fileSystemWatcher.start();
091        }
092
093        @Override
094        public void destroy() throws Exception {
095                this.fileSystemWatcher.stop();
096        }
097
098}