From: uguu Date: Sat, 19 May 2007 20:33:57 +0000 (+0000) Subject: コメントを記入しました。 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=be2399a8d55d3be1bf8f3a42f743f0d460ee2c83;p=deployer%2Frepo.git コメントを記入しました。 git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/deployer@3 bdfc86a3-8c30-0410-b963-dc9a622ac1c7 --- diff --git a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/Deployer.java b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/Deployer.java index 6b9e679..542ffe4 100644 --- a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/Deployer.java +++ b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/Deployer.java @@ -13,6 +13,16 @@ import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +/** + *

+ * ファイルを監視し、アーカイブ・ファイルが配置されたときに作業ディレクトリに展開し、イベントを通知します。 + *

+ *

+ * {@link #monitor()}メソッドの呼び出しでファイルを一回監視することが出来ます。ファイルを定期的に監視する場合、定期的に{@link #monitor()}メソッドを呼び出してください。 + *

+ * + * @author uguu + */ public class Deployer { private List listenerList = new ArrayList(); @@ -25,6 +35,23 @@ public class Deployer { private FileMonitor fileMonitor; + /** + *

+ * インスタンスを初期化します。 + *

+ * + * @param deployDirectory + * アーカイブ・ファイルの格納ディレクトリ。ここにアーカイブ・ファイルを配置すると、{@link Deployer}クラスが認識し、作業ディレクトリに展開します。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。
+ * ディレクトリではない場合、{@link IllegalArgumentException}例外をスローします。 + * @param filePattern + * アーカイブ・ファイルであると認識するファイルのパターン。絶対パスと比較されます。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + * @param workDirectory + * 作業ディレクトリ。アーカイブ・ファイルはここに展開されます。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。
+ * ディレクトリではない場合、{@link IllegalArgumentException}例外をスローします。 + */ public Deployer(File deployDirectory, Pattern filePattern, File workDirectory) { if (deployDirectory == null) { throw new IllegalArgumentException("deployDirectory is null."); @@ -51,6 +78,18 @@ public class Deployer { this.fileMonitor.addListener(new FileMonitorListenerImpl()); } + /** + *

+ * アーカイブ・ファイルの配置、配置解除のイベントが通知されるリスナーを追加します。 + *

+ *

+ * このメソッドはスレッドセーフです。 + *

+ * + * @param listener + * イベントが通知されるリスナー。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + */ public void addListener(DeployerListener listener) { if (listener == null) { throw new IllegalArgumentException("listener is null."); @@ -60,12 +99,31 @@ public class Deployer { } } + /** + *

+ * 登録されているリスナーを削除します。 + *

+ *

+ * このメソッドはスレッドセーフです。 + *

+ * + * @param listener + * 削除するリスナー。 + */ public void removeListener(DeployerListener listener) { synchronized (this.listenerList) { this.listenerList.remove(listener); } } + /** + *

+ * アーカイブ・ファイルを監視し、配置、配置解除を行い、リスナーにイベントを通知します。 + *

+ * + * @throws IOException + * 入出力エラーが発生した場合。 + */ public void monitor() throws IOException { this.fileMonitor.monitor(); } @@ -139,6 +197,12 @@ public class Deployer { while ((zipEntry = zipIn.getNextEntry()) != null) { if (!zipEntry.isDirectory()) { File f = new File(destDir, zipEntry.getName().replace('/', File.separatorChar)); + // イベントを通知します。 + synchronized (this.listenerList) { + for (DeployerListener l : this.listenerList) { + l.deployFile(this, file, destDir, f); + } + } if (!f.createNewFile()) { throw new IOException("ファイル\"" + f.getAbsolutePath() + "\"の作成に失敗しました。"); } @@ -153,12 +217,6 @@ public class Deployer { } finally { fileOut.close(); } - // イベントを通知します。 - synchronized (this.listenerList) { - for (DeployerListener l : this.listenerList) { - l.deployFile(this, file, destDir, f); - } - } } else { File dir = new File(destDir, zipEntry.getName().replace('/', File.separatorChar)); if (!dir.mkdirs()) { diff --git a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerClassLoader.java b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerClassLoader.java index 2028915..839549b 100644 --- a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerClassLoader.java +++ b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerClassLoader.java @@ -10,10 +10,24 @@ import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; -import java.util.Vector; +import java.util.NoSuchElementException; import java.util.jar.JarEntry; import java.util.jar.JarFile; +/** + *

+ * アーカイブ・ファイル配置後のクラスやリソースを利用するクラスローダーです。 + *

+ *

+ * アーカイブ・ファイルにはクラス・ファイル、リソース、jarファイルを含めることが出来、コンストラクタでディレクトリを指定することでクラスローダーの管理下に置くことができます。例えば、classes/からクラス・ファイル、lib/からjarファイルを検索するように初期化することが出来ます。 + *

+ *

+ * ホット・デプロイを前提としているので、クラスローダーが読み込んだリソースなどを破棄する{@link #dispose()}メソッドが用意されています。例えば{@link Deployer}クラスと連携する場合、{@link DeployerListener#undeployEnd(Deployer, File)}メソッドの呼び出しでこのクラスローダーを破棄することが出来ます。 + * TODO: dispose()メソッドは実装されていません。一度管理下に置いたリソースを破棄する方法が分からないためです。 + *

+ * + * @author uguu + */ public class DeployerClassLoader extends ClassLoader { private List listenerList = new ArrayList(); @@ -24,17 +38,67 @@ public class DeployerClassLoader extends ClassLoader { private String jarDirectory; - public DeployerClassLoader(File deployDirectory, String classDirectory, String jarDirectory, ClassLoader parent) throws IOException { + /** + *

+ * {@link DeployerClassLoader}インスタンスを初期化します。 + *

+ * + * @param deployDirectory + * アーカイブ・ファイルを配置したディレクトリ。このディレクトリ以下からクラス・ファイル、リソース、jarファイルなどを検索します。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。
+ * ディレクトリではない場合、{@link IllegalArgumentException}例外をスローします。 + * @param classDirectory + * クラス・ファイルを検索するディレクトリの名前。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + * @param jarDirectory + * jarファイルを検索するディレクトリの名前。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + * @param parent + * 親クラスローダー。 + */ + public DeployerClassLoader(File deployDirectory, String classDirectory, String jarDirectory, ClassLoader parent) { super(parent); this.initialize(deployDirectory, classDirectory, jarDirectory); } - public DeployerClassLoader(File deployDirectory, String classDirectory, String jarDirectory) throws IOException { + /** + *

+ * {@link DeployerClassLoader}インスタンスを初期化します。 + *

+ * + * @param deployDirectory + * アーカイブ・ファイルを配置したディレクトリ。このディレクトリ以下からクラス・ファイル、リソース、jarファイルなどを検索します。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。
+ * ディレクトリではない場合、{@link IllegalArgumentException}例外をスローします。 + * @param classDirectory + * クラス・ファイルを検索するディレクトリの名前。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + * @param jarDirectory + * jarファイルを検索するディレクトリの名前。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + */ + public DeployerClassLoader(File deployDirectory, String classDirectory, String jarDirectory) { super(); this.initialize(deployDirectory, classDirectory, jarDirectory); } - private void initialize(File deployDirectory, String classDirectory, String jarDirectory) throws IOException { + /** + *

+ * クラスローダーを初期化します。 + *

+ * + * @param deployDirectory + * アーカイブ・ファイルを配置したディレクトリ。このディレクトリ以下からクラス・ファイル、リソース、jarファイルなどを検索します。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。
+ * ディレクトリではない場合、{@link IllegalArgumentException}例外をスローします。 + * @param classDirectory + * クラス・ファイルを検索するディレクトリの名前。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + * @param jarDirectory + * jarファイルを検索するディレクトリの名前。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + */ + private void initialize(File deployDirectory, String classDirectory, String jarDirectory) { if (deployDirectory == null) { throw new IllegalArgumentException("deployDirectory is null."); } @@ -53,6 +117,18 @@ public class DeployerClassLoader extends ClassLoader { this.jarDirectory = jarDirectory; } + /** + *

+ * クラスローダーがクラスを操作したときのイベントを受け取るリスナーを追加します。 + *

+ *

+ * このメソッドはスレッドセーフです。 + *

+ * + * @param listener + * イベントが通知されるリスナー。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + */ public void addListener(DeployerClassLoaderListener listener) { if (listener == null) { throw new IllegalArgumentException("listener is null."); @@ -62,19 +138,49 @@ public class DeployerClassLoader extends ClassLoader { } } + /** + *

+ * 既に登録されているリスナーを削除します。 + *

+ *

+ * このメソッドはスレッドセーフです。 + *

+ * + * @param listener + * 削除するリスナー。 + */ public void removeListener(DeployerClassLoaderListener listener) { synchronized (this.listenerList) { this.listenerList.remove(listener); } } + /** + *

+ * クラスローダーが保持している全てのリソースを破棄します。 + *

+ * TODO: メソッドは機能しません。 + */ public void dispose() { // TODO 定義済みクラスをうまく解放する方法を考える。 } + /** + *

+ * クラスを検索します。 + *

+ *

+ * このメソッドは、クラスがまだ読み込まれていないときに呼び出されます。呼び出されると、クラス・ディレクトリやjarファイルからクラスを検索し、見つかった場合、クラスとして定義します({@link #defineClass(String, byte[], int, int)}メソッドを呼び出します)。クラスが見つからなかった場合、{@link ClassNotFoundException}例外をスローします。 + *

+ * + * @param name + * 検索するクラスのFQN。 + * @return 見つかったクラス。 + * @throws ClassNotFoundException + * クラスが見つからなかった場合。 + */ @Override protected Class findClass(String name) throws ClassNotFoundException { -// String resName = "/" + name.replace('.', '/') + ".class"; String resName = name.replace('.', '/') + ".class"; URL url = this.findResource(resName); if (url == null) { @@ -113,105 +219,229 @@ public class DeployerClassLoader extends ClassLoader { } } + /** + *

+ * リソースを検索します。 + *

+ *

+ * まずクラス・ディレクトリから、次にjarディレクトリからファイルを検索します。そして、最初に見つかったファイルのURLを返します。 + *

+ *

+ * このメソッドは{@link #findResources(String)}メソッドを呼び出し、その最初のURLを返します。このとき、{@link #findResources(String)}メソッドが{@link IOException}例外をスローする可能性があります。{@link IOException}例外がスローされた場合、nullを返します。 + *

+ * + * @param name + * リソース名。 + * @return リソースのURL。 + */ @Override protected URL findResource(String name) { - URL url; - // クラス ディレクトリから探す。 + Enumeration resources; try { - url = this.findResourceForClassDirectory(new File(this.deployDirectory, this.classDirectory), name); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - if (url != null) { - return url; + resources = this.findResources(name); + } catch (IOException e) { + return null; } - // jarディレクトリから探す。 - List jarFileList = this.getJarFileList(new File(this.deployDirectory, this.jarDirectory)); - for (File jarFile : jarFileList) { - try { - url = this.findResourceForJarFile(jarFile, name); - } catch (IOException e) { - throw new RuntimeException(e); - } - if (url != null) { - return url; - } + if (resources.hasMoreElements()) { + return resources.nextElement(); + } else { + return null; } - return null; } + /** + *

+ * リソースを検索します。 + *

+ *

+ * まずクラス・ディレクトリから、次にjarディレクトリからファイルを検索します。そして、見つかった全てのファイルのURLを列挙します。例えば、"foo/bar/boo.txt"がfoo.jarとbar.jarから見つかった場合、これらのURLが列挙されます。 + *

+ * + * @param name + * リソース名。 + * @return リソースのURLの列挙。 + * @throws IOException + * 入出力エラーが発生した場合。 + */ @Override protected Enumeration findResources(String name) throws IOException { - Vector urlVector = new Vector(); - URL url; - // クラス ディレクトリから探す。 - try { - url = this.findResourceForClassDirectory(new File(this.deployDirectory, this.classDirectory), name); - } catch (MalformedURLException e) { - throw new RuntimeException(e); + File classDir = new File(this.deployDirectory, this.classDirectory); + if (!classDir.exists()) { + classDir = null; } - if (url != null) { - urlVector.add(url); + File jarDir = new File(this.deployDirectory, this.jarDirectory); + if (!jarDir.exists()) { + jarDir = null; + } + return new ResourceEnumeration(classDir, jarDir, name); + } + + /** + *

+ * リソースを列挙します。 + *

+ * + * @author uguu + */ + private class ResourceEnumeration implements Enumeration { + + private String resourceName; + + private File classDir; + + private List jarFileList; + + private int currentIndex = -1; + + /** + *

+ * インスタンスを初期化します。 + *

+ * + * @param classDirectory + * クラス・ファイルを検索するディレクトリ。
+ * このパスが存在し、かつディレクトリではない場合、{@link IllegalArgumentException}例外をスローします。 + * @param jarDirectory + * jarファイルを検索するディレクトリ。
+ * このパスが存在し、かつディレクトリではない場合、{@link IllegalArgumentException}例外をスローします。 + * @param resourceName + * 列挙するリソースの名前。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + */ + public ResourceEnumeration(File classDirectory, File jarDirectory, String resourceName) { + if (classDirectory != null && !classDirectory.isDirectory()) { + throw new IllegalArgumentException("classDirectory is not directory."); + } + if (jarDirectory != null && !jarDirectory.isDirectory()) { + throw new IllegalArgumentException("jarDirectory is not directory."); + } + if (resourceName == null) { + throw new IllegalArgumentException("resourceName is null."); + } + + this.classDir = classDirectory; + this.resourceName = resourceName; + + this.jarFileList = this.getJarFileList(jarDirectory); } - // jarディレクトリから探す。 - List jarFileList = this.getJarFileList(new File(this.deployDirectory, this.jarDirectory)); - for (File jarFile : jarFileList) { + + /** + *

+ * 列挙中に次の要素が存在するかどうかを返します。 + *

+ * + * @return 次の要素が存在する場合はtrue、存在しない場合はfalse。 + */ + public boolean hasMoreElements() { try { - url = this.findResourceForJarFile(jarFile, name); + URL url = this.nextElement(false); + return (url != null); } catch (IOException e) { throw new RuntimeException(e); } - if (url != null) { - urlVector.add(url); - } } - return urlVector.elements(); - } - private URL findResourceForClassDirectory(File classDir, String resourceName) throws MalformedURLException { - String resName = resourceName.replace('/', File.separatorChar); - File resFile = new File(classDir, resName); - if (resFile.exists()) { - URL url = new URL("file:/" + resFile.getAbsolutePath().replace(File.separatorChar, '/')); - return url; - } else { - return null; + /** + *

+ * 列挙中の次の要素を返します。 + *

+ * + * @return 列挙中の次の要素。
+ * 次の要素が存在しない場合は{@link NoSuchElementException}例外をスローします。 + */ + public URL nextElement() { + try { + URL url = this.nextElement(true); + if (url != null) { + return url; + } else { + throw new NoSuchElementException(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } } - } - private List getJarFileList(File jarDir) { - List jarFileList = new ArrayList(); + private URL nextElement(boolean updateIndex) throws IOException { + int curIdx = this.currentIndex; - File[] files = jarDir.listFiles(); - if (files == null) { - return new ArrayList(); - } - for (File file : files) { - if (file.isFile()) { - if (file.getName().endsWith(".jar")) { - jarFileList.add(file); + while (true) { + if (curIdx == this.jarFileList.size()) { + return null; } - } else { - jarFileList.addAll(this.getJarFileList(file)); + if (curIdx == -1) { + URL url = this.findResourceForClassDirectory(this.classDir, this.resourceName); + if (url != null) { + if (updateIndex) { + this.currentIndex = curIdx; + } + return url; + } + } else { + File jarFile = this.jarFileList.get(curIdx); + URL url = this.findResourceForJarFile(jarFile, this.resourceName); + if (url != null) { + if (updateIndex) { + this.currentIndex = curIdx; + } + return url; + } + } + curIdx++; } } - return jarFileList; - } + private List getJarFileList(File dir) { + List jarFileList = new ArrayList(); - private URL findResourceForJarFile(File jarFile, String resourceName) throws IOException { - JarFile jar = new JarFile(jarFile); - try { - JarEntry entry = jar.getJarEntry(resourceName); - if (entry != null) { - URL url = new URL("jar:file:/" + jarFile.getAbsolutePath().replace(File.separatorChar, '/') + "!/" + entry.getName()); + if (dir != null) { + File[] files = dir.listFiles(); + if (files == null) { + return new ArrayList(); + } + for (File file : files) { + if (file.isFile()) { + if (file.getName().endsWith(".jar")) { + jarFileList.add(file); + } + } else { + jarFileList.addAll(this.getJarFileList(file)); + } + } + } + + return jarFileList; + } + + private URL findResourceForClassDirectory(File classDir, String resourceName) throws MalformedURLException { + if (classDir != null) { + return null; + } + String resName = resourceName.replace('/', File.separatorChar); + File resFile = new File(classDir, resName); + if (resFile.exists()) { + URL url = new URL("file:/" + resFile.getAbsolutePath().replace(File.separatorChar, '/')); return url; } else { return null; } - } finally { - jar.close(); } + + private URL findResourceForJarFile(File jarFile, String resourceName) throws IOException { + JarFile jar = new JarFile(jarFile); + try { + JarEntry entry = jar.getJarEntry(resourceName); + if (entry != null) { + URL url = new URL("jar:file:/" + jarFile.getAbsolutePath().replace(File.separatorChar, '/') + "!/" + entry.getName()); + return url; + } else { + return null; + } + } finally { + jar.close(); + } + } + } } diff --git a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerClassLoaderListener.java b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerClassLoaderListener.java index 61468ed..db3e811 100644 --- a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerClassLoaderListener.java +++ b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerClassLoaderListener.java @@ -3,8 +3,25 @@ package jp.gr.java_conf.uguu.deployer; import java.net.URL; +/** + *

+ * {@link DeployerClassLoader}クラスによるクラス操作のイベントを受け取るリスナーです。 + *

+ * + * @author uguu + */ public interface DeployerClassLoaderListener { + /** + *

+ * クラスが検索されたときに呼び出されます。 + *

+ * + * @param clazz + * 検索したクラス。 + * @param url + * クラスの実態が存在するURL。 + */ void findClass(Class clazz, URL url); } diff --git a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerListener.java b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerListener.java index 8e4d207..cfbf3a1 100644 --- a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerListener.java +++ b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/DeployerListener.java @@ -3,16 +3,79 @@ package jp.gr.java_conf.uguu.deployer; import java.io.File; +/** + *

+ * {@link Deployer}クラスによるファイル配置のイベントを受け取るリスナーです。 + *

+ * + * @author uguu + */ public interface DeployerListener { + /** + *

+ * アーカイブ・ファイルの配置を開始するときに呼び出されます。 + *

+ * + * @param deployer + * イベントの通知元の{@link Deployer}インスタンス。 + * @param file + * 配置するアーカイブ・ファイル。 + */ void deployStart(Deployer deployer, File file); + /** + *

+ * アーカイブ・ファイルから抽出したファイルを配置するときに呼び出されます。 + *

+ * + * @param deployer + * イベントの通知元の{@link Deployer}インスタンス。 + * @param file + * 配置するアーカイブ・ファイル。 + * @param destDirectory + * 配置先のルート・ディレクトリ。 + * @param deployFile + * 配置するファイル。 + */ void deployFile(Deployer deployer, File file, File destDirectory, File deployFile); + /** + *

+ * アーカイブ・ファイルの配置が終了したときに呼び出されます。 + *

+ * + * @param deployer + * イベントの通知元の{@link Deployer}インスタンス。 + * @param file + * 配置したアーカイブ・ファイル。 + * @param destDirectory + * 配置先のルート・ディレクトリ。 + */ void deployEnd(Deployer deployer, File file, File destDirectory); + /** + *

+ * アーカイブ・ファイルの配置の解除を開始するときに呼び出されます。 + *

+ * + * @param deployer + * イベントの通知元の{@link Deployer}インスタンス。 + * @param file + * 配置解除するアーカイブ・ファイル。 + * @param destDirectory + * 配置先のルート・ディレクトリ。 + */ void undeployStart(Deployer deployer, File file, File destDirectory); + /** + * アーカイブ・ファイルの配置の解除が終了したときに呼び出されます。 + * + * @param deployer + * イベントの通知元の{@link Deployer}インスタンス。 + * @param file + * 配置解除したアーカイブ・ファイル。 + */ void undeployEnd(Deployer deployer, File file); } diff --git a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/FileMonitor.java b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/FileMonitor.java index b260704..94dcf62 100644 --- a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/FileMonitor.java +++ b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/FileMonitor.java @@ -9,6 +9,16 @@ import java.util.List; import java.util.Map; import java.util.regex.Pattern; +/** + *

+ * ファイルの作成、更新、削除を監視し、イベントを通知します。 + *

+ *

+ * {@link #monitor()}メソッドの呼び出しでファイルを一回監視することが出来ます。ファイルを定期的に監視する場合、定期的に{@link #monitor()}メソッドを呼び出してください。 + *

+ * + * @author uguu + */ public class FileMonitor { private List listenerList = new ArrayList(); @@ -19,6 +29,19 @@ public class FileMonitor { private Map monitoringFileMap = new HashMap(); + /** + *

+ * 指定したディレクトリの指定したパターンに合致するファイルを監視する{@link FileMonitor}インスタンスを初期化します。 + *

+ * + * @param baseDirectory + * 監視するディレクトリ。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。
+ * ディレクトリを表していない場合、{@link IllegalArgumentException}例外をスローします。 + * @param filePattern + * 監視するファイルのパターンを表す正規表現。絶対パスと比較されます。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + */ public FileMonitor(File baseDirectory, Pattern filePattern) { if (baseDirectory == null) { throw new IllegalArgumentException("baseDirectory is null."); @@ -33,10 +56,34 @@ public class FileMonitor { this.filePattern = filePattern; } + /** + *

+ * 指定したディレクトリの全てのファイルを監視する{@link FileMonitor}インスタンスを初期化します。 + *

+ *

+ * このコンストラクタ呼び出しは、以下のコードと等価です。 + *

+ *
new FileMonitor(baseDirectory, Pattern.compile(".*")) + *
+ * + * @param baseDirectory + */ public FileMonitor(File baseDirectory) { this(baseDirectory, Pattern.compile(".*")); } + /** + *

+ * ファイルの作成、更新、削除を認識したときにイベントが通知されるリスナーを追加します。 + *

+ *

+ * このメソッドはスレッドセーフです。 + *

+ * + * @param listener + * イベントが通知されるリスナー。
+ * nullの場合、{@link IllegalArgumentException}例外をスローします。 + */ public void addListener(FileMonitorListener listener) { if (listener == null) { throw new IllegalArgumentException("listener is null."); @@ -46,6 +93,17 @@ public class FileMonitor { } } + /** + *

+ * 登録されているリスナーを削除します。 + *

+ *

+ * このメソッドはスレッドセーフです。 + *

+ * + * @param listener + * 削除するリスナー。 + */ public void removeListener(FileMonitorListener listener) { synchronized (this.listenerList) { this.listenerList.remove(listener); @@ -58,6 +116,14 @@ public class FileMonitor { } } + /** + *

+ * ファイルの作成、更新、削除を監視し、リスナーにイベントを通知します。 + *

+ * + * @throws IOException + * 入出力エラーが発生した場合。 + */ public void monitor() throws IOException { this.checkCreateOrUpdate(this.baseDirectory); this.checkDelete(); diff --git a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/FileMonitorListener.java b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/FileMonitorListener.java index ca6028d..6e58cff 100644 --- a/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/FileMonitorListener.java +++ b/deployer/trunk/src/main/java/jp/gr/java_conf/uguu/deployer/FileMonitorListener.java @@ -3,12 +3,49 @@ package jp.gr.java_conf.uguu.deployer; import java.io.File; +/** + *

+ * {@link FileMonitor}クラスによるファイル監視のイベントを受け取るリスナーです。 + *

+ * + * @author uguu + */ public interface FileMonitorListener { + /** + *

+ * ファイルが作成されたときに呼び出されます。 + *

+ * + * @param monitor + * イベントの通知元の{@link FileMonitor}インスタンス。 + * @param file + * 作成されたファイル。 + */ void create(FileMonitor monitor, File file); + /** + *

+ * ファイルが更新されたときに呼び出されます。 + *

+ * + * @param monitor + * イベントの通知元の{@link FileMonitor}インスタンス。 + * @param file + * 更新されたファイル。 + */ void update(FileMonitor monitor, File file); + /** + *

+ * ファイルが削除されたときに呼び出されます。 + *

+ * + * @param monitor + * イベントの通知元の{@link FileMonitor}インスタンス。 + * @param file + * 削除されたファイル。 + */ void delete(FileMonitor monitor, File file); }