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}