001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018// Contributors: Mathias Bogaert 019 020package org.apache.log4j.helpers; 021 022import java.io.File; 023 024/** 025 Check every now and then that a certain file has not changed. If it 026 has, then call the {@link #doOnChange} method. 027 028 029 @author Ceki Gülcü 030 @since version 0.9.1 */ 031public abstract class FileWatchdog extends Thread { 032 033 /** 034 The default delay between every file modification check, set to 60 035 seconds. */ 036 static final public long DEFAULT_DELAY = 60000; 037 /** 038 The name of the file to observe for changes. 039 */ 040 protected String filename; 041 042 /** 043 The delay to observe between every check. By default set {@link 044 #DEFAULT_DELAY}. */ 045 protected long delay = DEFAULT_DELAY; 046 047 File file; 048 long lastModif = 0; 049 boolean warnedAlready = false; 050 boolean interrupted = false; 051 052 protected 053 FileWatchdog(String filename) { 054 super("FileWatchdog"); 055 this.filename = filename; 056 file = new File(filename); 057 setDaemon(true); 058 checkAndConfigure(); 059 } 060 061 /** 062 Set the delay to observe between each check of the file changes. 063 */ 064 public 065 void setDelay(long delay) { 066 this.delay = delay; 067 } 068 069 abstract 070 protected 071 void doOnChange(); 072 073 protected 074 void checkAndConfigure() { 075 boolean fileExists; 076 try { 077 fileExists = file.exists(); 078 } catch(SecurityException e) { 079 LogLog.warn("Was not allowed to read check file existance, file:["+ 080 filename+"]."); 081 interrupted = true; // there is no point in continuing 082 return; 083 } 084 085 if(fileExists) { 086 long l = file.lastModified(); // this can also throw a SecurityException 087 if(l > lastModif) { // however, if we reached this point this 088 lastModif = l; // is very unlikely. 089 doOnChange(); 090 warnedAlready = false; 091 } 092 } else { 093 if(!warnedAlready) { 094 LogLog.debug("["+filename+"] does not exist."); 095 warnedAlready = true; 096 } 097 } 098 } 099 100 public 101 void run() { 102 while(!interrupted) { 103 try { 104 Thread.sleep(delay); 105 } catch(InterruptedException e) { 106 // no interruption expected 107 } 108 checkAndConfigure(); 109 } 110 } 111}