OSDN Git Service

made a copy
authoruguu <uguu@bdfc86a3-8c30-0410-b963-dc9a622ac1c7>
Tue, 29 May 2007 13:16:35 +0000 (13:16 +0000)
committeruguu <uguu@bdfc86a3-8c30-0410-b963-dc9a622ac1c7>
Tue, 29 May 2007 13:16:35 +0000 (13:16 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/deployer@14 bdfc86a3-8c30-0410-b963-dc9a622ac1c7

30 files changed:
deployer/tags/1.0.0/.checkstyle [new file with mode: 0644]
deployer/tags/1.0.0/.classpath [new file with mode: 0644]
deployer/tags/1.0.0/.project [new file with mode: 0644]
deployer/tags/1.0.0/LICENSE.txt [new file with mode: 0644]
deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.jar [new file with mode: 0644]
deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.tar.gz [new file with mode: 0644]
deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.zip [new file with mode: 0644]
deployer/tags/1.0.0/pom.xml [new file with mode: 0644]
deployer/tags/1.0.0/src/main/assembly/dist.xml [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/ClassLoaderUnloadFailException.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/ClassLoaderUnloadedException.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/Consts.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/Deployer.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DeployerClassLoader.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DeployerListener.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DirectoryCreateFailException.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DirectoryDeleteFailException.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileCreateFailException.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileDeleteFailException.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileMonitor.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileMonitorFailException.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileMonitorListener.java [new file with mode: 0644]
deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/package.html [new file with mode: 0644]
deployer/tags/1.0.0/src/site/changes.xml [new file with mode: 0644]
deployer/tags/1.0.0/src/site/site.xml [new file with mode: 0644]
deployer/tags/1.0.0/src/site/xdoc/archive.xml [new file with mode: 0644]
deployer/tags/1.0.0/src/site/xdoc/coding.xml [new file with mode: 0644]
deployer/tags/1.0.0/src/site/xdoc/hotdeploy.xml [new file with mode: 0644]
deployer/tags/1.0.0/src/site/xdoc/index.xml [new file with mode: 0644]
deployer/tags/1.0.0/uguu.checkstyle.xml [new file with mode: 0644]

diff --git a/deployer/tags/1.0.0/.checkstyle b/deployer/tags/1.0.0/.checkstyle
new file mode 100644 (file)
index 0000000..fe04391
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<fileset-config file-format-version="1.2.0" simple-config="true">\r
+    <local-check-config name="Uguu Checks" location="G:\work\work-eclipse\deployer\uguu.checkstyle.xml" type="external" description="">\r
+        <additional-data name="protect-config-file" value="false"/>\r
+    </local-check-config>\r
+    <fileset name="all" enabled="true" check-config-name="Uguu Checks" local="true">\r
+        <file-match-pattern match-pattern="." include-pattern="true"/>\r
+    </fileset>\r
+</fileset-config>\r
diff --git a/deployer/tags/1.0.0/.classpath b/deployer/tags/1.0.0/.classpath
new file mode 100644 (file)
index 0000000..1e6d54b
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="src" path="src/main/java"/>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/deployer/tags/1.0.0/.project b/deployer/tags/1.0.0/.project
new file mode 100644 (file)
index 0000000..1923e01
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>deployer</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>com.atlassw.tools.eclipse.checkstyle.CheckstyleBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+               <nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/deployer/tags/1.0.0/LICENSE.txt b/deployer/tags/1.0.0/LICENSE.txt
new file mode 100644 (file)
index 0000000..f281d8f
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without prior written permission. For written
+ *       permission, please contact clarkware@clarkware.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
\ No newline at end of file
diff --git a/deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.jar b/deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.jar
new file mode 100644 (file)
index 0000000..0efa5a5
Binary files /dev/null and b/deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.jar differ
diff --git a/deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.tar.gz b/deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.tar.gz
new file mode 100644 (file)
index 0000000..3e2604a
Binary files /dev/null and b/deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.tar.gz differ
diff --git a/deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.zip b/deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.zip
new file mode 100644 (file)
index 0000000..3d4936d
Binary files /dev/null and b/deployer/tags/1.0.0/dist/1.0.0/deployer-1.0.0.zip differ
diff --git a/deployer/tags/1.0.0/pom.xml b/deployer/tags/1.0.0/pom.xml
new file mode 100644 (file)
index 0000000..6d9087a
--- /dev/null
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="Shift_JIS"?>\r
+<project>\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <groupId>jp.sourceforge.deployer</groupId>\r
+    <artifactId>deployer</artifactId>\r
+    <name>\83f\83v\83\8d\83C\83\84\81[</name>\r
+    <version>1.0.0</version>\r
+    <description>\83z\83b\83\83f\83v\83\8d\83C\8b@\94\\82ð\8e\9d\82Â\83R\83\93\83|\81[\83l\83\93\83g\82ð\92ñ\8b\9f\82µ\82Ü\82·\81B\83f\83v\83\8d\83C\83\84\81[\82Í\81A\93Á\92è\83f\83B\83\8c\83N\83g\83\8a\82É\83t\83@\83C\83\8b\82ª\94z\92u\82³\82ê\82½\82Æ\82«\81A\82»\82ê\82ð\8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\82É\93W\8aJ\82µ\81A\93Æ\8e©\83N\83\89\83X\83\8d\81[\83_\81[\82ð\8d\\92z\82µ\81A\83A\83v\83\8a\83P\81[\83V\83\87\83\93\82É\83C\83x\83\93\83g\82ð\92Ê\92m\82µ\82Ü\82·\81B</description>\r
+    <url>http://deployer.sourceforge.jp/</url>\r
+    <inceptionYear>2007</inceptionYear>\r
+    <developers>\r
+        <developer>\r
+            <id>uguu</id>\r
+            <name>uguu</name>\r
+            <email>uguu@users.sourceforge.jp</email>\r
+            <organization />\r
+            <roles>\r
+                <role>Developer</role>\r
+            </roles>\r
+        </developer>\r
+    </developers>\r
+    <licenses>\r
+        <license>\r
+            <name>BSD License</name>\r
+            <url>LICENSE.txt</url>\r
+        </license>\r
+    </licenses>\r
+    <scm>\r
+        <connection>scm:svn:http://svn.sourceforge.jp/svnroot/deployer/</connection>\r
+        <url>http://svn.sourceforge.jp/svnroot/deployer/</url>\r
+    </scm>\r
+    <organization>\r
+        <name>uguu</name>\r
+    </organization>\r
+    <build>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-compiler-plugin</artifactId>\r
+                <configuration>\r
+                    <source>1.5</source>\r
+                    <target>1.5</target>\r
+                </configuration>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-site-plugin</artifactId>\r
+                <configuration>\r
+                    <locales>ja</locales>\r
+                    <inputEncoding>Shift_JIS</inputEncoding>\r
+                    <outputEncoding>Shift_JIS</outputEncoding>\r
+                </configuration>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-assembly-plugin</artifactId>\r
+                <configuration>\r
+                    <descriptors>\r
+                        <descriptor>src/main/assembly/dist.xml</descriptor>\r
+                    </descriptors>\r
+                </configuration>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+    <reporting>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-surefire-report-plugin</artifactId>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-javadoc-plugin</artifactId>\r
+                <configuration>\r
+                    <source>1.5</source>\r
+                    <encoding>UTF-8</encoding>\r
+                    <charset>Shift_JIS</charset>\r
+                    <docencoding>Shift_JIS</docencoding>\r
+                    <links>\r
+                        <link>http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/</link>\r
+                    </links>\r
+                </configuration>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-changelog-plugin</artifactId>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-changes-plugin</artifactId>\r
+                <configuration>\r
+                    <xmlPath>${basedir}/src/site/changes.xml</xmlPath>\r
+                </configuration>\r
+                <reportSets>\r
+                    <reportSet>\r
+                        <reports>\r
+                            <report>changes-report</report>\r
+                        </reports>\r
+                    </reportSet>\r
+                </reportSets>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-checkstyle-plugin</artifactId>\r
+                <configuration>\r
+                    <configLocation>uguu.checkstyle.xml</configLocation>\r
+                    <propertyExpansion>basedir=./</propertyExpansion>\r
+                </configuration>\r
+            </plugin>\r
+        </plugins>\r
+    </reporting>\r
+</project>\r
diff --git a/deployer/tags/1.0.0/src/main/assembly/dist.xml b/deployer/tags/1.0.0/src/main/assembly/dist.xml
new file mode 100644 (file)
index 0000000..e503831
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="Shift_JIS"?>\r
+<assembly>\r
+    <formats>\r
+        <format>zip</format>\r
+        <format>tar.gz</format>\r
+    </formats>\r
+    <fileSets>\r
+        <fileSet>\r
+            <directory>src</directory>\r
+            <outputDirectory>src</outputDirectory>\r
+        </fileSet>\r
+        <fileSet>\r
+            <directory>target/site</directory>\r
+            <outputDirectory>docs</outputDirectory>\r
+        </fileSet>\r
+        <fileSet>\r
+            <directory>target</directory>\r
+            <outputDirectory>bin</outputDirectory>\r
+            <includes>\r
+                <include>*.jar</include>\r
+            </includes>\r
+        </fileSet>\r
+        <fileSet>\r
+            <includes>\r
+                <include>LICENSE.txt</include>\r
+                <include>pom.xml</include>\r
+                <include>uguu.checkstyle.xml</include>\r
+            </includes>\r
+        </fileSet>\r
+    </fileSets>\r
+    <dependencySets>\r
+        <dependencySet>\r
+            <unpack>false</unpack>\r
+            <outputDirectory>lib</outputDirectory>\r
+        </dependencySet>\r
+    </dependencySets>\r
+</assembly>\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/ClassLoaderUnloadFailException.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/ClassLoaderUnloadFailException.java
new file mode 100644 (file)
index 0000000..6ec89f3
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+/**\r
+ * <p>\r
+ * クラスローダーを破棄しようとしましたが、タイムアウト時間内に破棄できず失敗したことを表す例外です。クラスローダーからロードされたクラス、クラスのインスタンスなどが解放されていない可能性が高いです。クラスローダーの破棄は、このクラスローダーに属する全てのクラス、インスタンスを破棄してから行ってください。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public class ClassLoaderUnloadFailException extends RuntimeException {\r
+\r
+    /**\r
+     * <p>\r
+     * インスタンスを初期化します。\r
+     * </p>\r
+     */\r
+    public ClassLoaderUnloadFailException() {\r
+        super("クラスローダーの破棄に失敗しました。");\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/ClassLoaderUnloadedException.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/ClassLoaderUnloadedException.java
new file mode 100644 (file)
index 0000000..d3b9a21
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+/**\r
+ * <p>\r
+ * クラスローダーが既に破棄されていることを表す例外です。クラスローダーが破棄されているにもかかわらず、何らかの操作を行おうとしたときにスローされます。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public class ClassLoaderUnloadedException extends RuntimeException {\r
+\r
+    /**\r
+     * <p>\r
+     * インスタンスを初期化します。\r
+     * </p>\r
+     */\r
+    public ClassLoaderUnloadedException() {\r
+        super("クラスローダーは既に破棄されています。");\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/Consts.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/Consts.java
new file mode 100644 (file)
index 0000000..d67c692
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+/**\r
+ * <p>\r
+ * 定数を定義します。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public final class Consts {\r
+\r
+    /**\r
+     * <p>\r
+     * {@link Thread#sleep(long)}メソッドに指定する単位時間です。\r
+     * </p>\r
+     */\r
+    public static final int SLEEP_UNIT_TIME = 1000;\r
+\r
+    /**\r
+     * <p>\r
+     * 入出力処理で使用するバッファの長さです。\r
+     * </p>\r
+     */\r
+    public static final int BUFFER_LENGTH   = 1024;\r
+\r
+    /**\r
+     * <p>\r
+     * インスタンス化を禁止します。\r
+     * </p>\r
+     */\r
+    private Consts() {\r
+        throw new UnsupportedOperationException();\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/Deployer.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/Deployer.java
new file mode 100644 (file)
index 0000000..03e768a
--- /dev/null
@@ -0,0 +1,445 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.nio.channels.FileLock;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.regex.Pattern;\r
+import java.util.zip.ZipEntry;\r
+import java.util.zip.ZipInputStream;\r
+\r
+/**\r
+ * <p>\r
+ * ファイルを監視し、アーカイブ・ファイルが配置されたときに作業ディレクトリに展開し、イベントを通知します。\r
+ * </p>\r
+ * <p>\r
+ * {@link #monitor()}メソッドの呼び出しでファイルを一回監視することが出来ます。ファイルを定期的に監視する場合、定期的に{@link #monitor()}メソッドを呼び出してください。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public final class Deployer {\r
+\r
+    /**\r
+     * <p>\r
+     * リスナーのリスト。\r
+     * </p>\r
+     */\r
+    private List<DeployerListener> _listenerList = new ArrayList<DeployerListener>();\r
+\r
+    /**\r
+     * <p>\r
+     * 配置ディレクトリ。\r
+     * </p>\r
+     */\r
+    private File                   _deployDirectory;\r
+\r
+    /**\r
+     * <p>\r
+     * アーカイブ・ファイルであると認識するファイルのパターン。\r
+     * </p>\r
+     */\r
+    private Pattern                _filePattern;\r
+\r
+    /**\r
+     * <p>\r
+     * 作業ディレクトリ。\r
+     * </p>\r
+     */\r
+    private File                   _workDirectory;\r
+\r
+    /**\r
+     * <p>\r
+     * ファイル監視。\r
+     * </p>\r
+     */\r
+    private FileMonitor            _fileMonitor;\r
+\r
+    /**\r
+     * <p>\r
+     * インスタンスを初期化します。\r
+     * </p>\r
+     * \r
+     * @param deployDirectory\r
+     *            配置ディレクトリ。ここにアーカイブ・ファイルを配置すると、{@link Deployer}クラスが認識し、作業ディレクトリに展開します。<br>\r
+     *            nullの場合、{@link IllegalArgumentException}例外をスローします。<br>\r
+     *            ディレクトリではない場合、{@link IllegalArgumentException}例外をスローします。\r
+     * @param filePattern\r
+     *            アーカイブ・ファイルであると認識するファイルのパターン。絶対パスと比較されます。<br>\r
+     *            nullの場合、{@link IllegalArgumentException}例外をスローします。\r
+     * @param workDirectory\r
+     *            作業ディレクトリ。アーカイブ・ファイルはここに展開されます。<br>\r
+     *            nullの場合、{@link IllegalArgumentException}例外をスローします。<br>\r
+     *            ディレクトリではない場合、{@link IllegalArgumentException}例外をスローします。\r
+     */\r
+    public Deployer(File deployDirectory, Pattern filePattern, File workDirectory) {\r
+        if (deployDirectory == null) {\r
+            throw new IllegalArgumentException("deployDirectory is null.");\r
+        }\r
+        if (!deployDirectory.isDirectory()) {\r
+            throw new IllegalArgumentException("deployDirectory is not directory.");\r
+        }\r
+        if (filePattern == null) {\r
+            throw new IllegalArgumentException("filePattern is null.");\r
+        }\r
+        if (workDirectory == null) {\r
+            throw new IllegalArgumentException("workDirectory is null.");\r
+        }\r
+        if (!workDirectory.isDirectory()) {\r
+            throw new IllegalArgumentException("workDirectory is not directory.");\r
+        }\r
+\r
+        this._deployDirectory = deployDirectory;\r
+        this._filePattern = filePattern;\r
+        this._workDirectory = workDirectory;\r
+\r
+        // ディレクトリの監視を開始する。\r
+        this._fileMonitor = new FileMonitor(this._deployDirectory, this._filePattern);\r
+        this._fileMonitor.addListener(new FileMonitorListenerImpl());\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * アーカイブ・ファイルの配置、配置解除のイベントが通知されるリスナーを追加します。\r
+     * </p>\r
+     * <p>\r
+     * このメソッドはスレッドセーフです。\r
+     * </p>\r
+     * \r
+     * @param listener\r
+     *            イベントが通知されるリスナー。<br>\r
+     *            nullの場合、{@link IllegalArgumentException}例外をスローします。\r
+     */\r
+    public void addListener(DeployerListener listener) {\r
+        if (listener == null) {\r
+            throw new IllegalArgumentException("listener is null.");\r
+        }\r
+        synchronized (this._listenerList) {\r
+            this._listenerList.add(listener);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 登録されているリスナーを削除します。\r
+     * </p>\r
+     * <p>\r
+     * このメソッドはスレッドセーフです。\r
+     * </p>\r
+     * \r
+     * @param listener\r
+     *            削除するリスナー。\r
+     */\r
+    public void removeListener(DeployerListener listener) {\r
+        synchronized (this._listenerList) {\r
+            this._listenerList.remove(listener);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * アーカイブ・ファイルを監視し、配置、配置解除を行い、リスナーにイベントを通知します。\r
+     * </p>\r
+     * \r
+     * @throws FileMonitorFailException\r
+     *             ファイルの監視に失敗した場合。\r
+     */\r
+    public void monitor() throws FileMonitorFailException {\r
+        this._fileMonitor.monitor();\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * デプロイします。\r
+     * </p>\r
+     * \r
+     * @param file\r
+     *            アーカイブ・ファイル。\r
+     * @throws IOException\r
+     *             入出力に失敗した場合。\r
+     */\r
+    private void deploy(File file) throws IOException {\r
+        // イベントを通知する。\r
+        synchronized (this._listenerList) {\r
+            for (DeployerListener l : this._listenerList) {\r
+                l.deployStart(this, file);\r
+            }\r
+        }\r
+        // デプロイ先のディレクトリを削除する。\r
+        File destDir = this.getDestDirectory(file, this._deployDirectory, this._workDirectory);\r
+        if (destDir.exists()) {\r
+            this.delete(destDir);\r
+            this.deleteWithParent(destDir.getParentFile());\r
+        }\r
+        // デプロイ先のディレクトリを作成する。\r
+        if (!destDir.mkdirs()) {\r
+            throw new DirectoryCreateFailException(destDir);\r
+        }\r
+        // デプロイ先に展開する。\r
+        this.decompress(file, destDir);\r
+        // イベントを通知する。\r
+        synchronized (this._listenerList) {\r
+            for (DeployerListener l : this._listenerList) {\r
+                l.deployEnd(this, file, destDir);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * アンデプロイします。\r
+     * </p>\r
+     * \r
+     * @param file\r
+     *            アーカイブ・ファイル。\r
+     * @throws IOException\r
+     *             入出力に失敗した場合。\r
+     */\r
+    private void undeploy(File file) throws IOException {\r
+        File destDir = this.getDestDirectory(file, this._deployDirectory, this._workDirectory);\r
+        // イベントを通知する。\r
+        synchronized (this._listenerList) {\r
+            for (DeployerListener l : this._listenerList) {\r
+                l.undeployStart(this, file, destDir);\r
+            }\r
+        }\r
+        // デプロイ先のディレクトリを削除する。\r
+        this.delete(destDir);\r
+        this.deleteWithParent(destDir.getParentFile());\r
+        // イベントを通知する。\r
+        synchronized (this._listenerList) {\r
+            for (DeployerListener l : this._listenerList) {\r
+                l.undeployEnd(this, file);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * アーカイブ・ファイルを展開します。\r
+     * </p>\r
+     * \r
+     * @param file\r
+     *            展開するアーカイブ・ファイル。\r
+     * @param destDir\r
+     *            展開先ディレクトリ。\r
+     * @throws IOException\r
+     *             入出力に失敗した場合。\r
+     */\r
+    private void decompress(File file, File destDir) throws IOException {\r
+        FileInputStream fileIn = null;\r
+        while (fileIn == null) {\r
+            try {\r
+                fileIn = new FileInputStream(file);\r
+            } catch (FileNotFoundException e) {\r
+                fileIn = null;\r
+                try {\r
+                    Thread.sleep(Consts.SLEEP_UNIT_TIME);\r
+                } catch (InterruptedException e1) {\r
+                    e1.printStackTrace();\r
+                }\r
+            }\r
+        }\r
+        try {\r
+            ZipInputStream zipIn = new ZipInputStream(fileIn);\r
+            try {\r
+                FileLock lock = fileIn.getChannel().lock(0, Long.MAX_VALUE, true);\r
+                try {\r
+                    ZipEntry zipEntry;\r
+                    while ((zipEntry = zipIn.getNextEntry()) != null) {\r
+                        if (!zipEntry.isDirectory()) {\r
+                            File f = new File(destDir, zipEntry.getName().replace('/', File.separatorChar));\r
+                            // イベントを通知します。\r
+                            synchronized (this._listenerList) {\r
+                                for (DeployerListener l : this._listenerList) {\r
+                                    l.deployFile(this, file, destDir, f);\r
+                                }\r
+                            }\r
+                            if (!f.createNewFile()) {\r
+                                throw new FileCreateFailException(f);\r
+                            }\r
+                            // ファイルを展開します。\r
+                            FileOutputStream fileOut = new FileOutputStream(f);\r
+                            try {\r
+                                byte[] buf = new byte[Consts.BUFFER_LENGTH];\r
+                                int len;\r
+                                while ((len = zipIn.read(buf)) != -1) {\r
+                                    fileOut.write(buf, 0, len);\r
+                                }\r
+                            } finally {\r
+                                fileOut.close();\r
+                            }\r
+                        } else {\r
+                            File dir = new File(destDir, zipEntry.getName().replace('/', File.separatorChar));\r
+                            if (!dir.mkdirs()) {\r
+                                throw new DirectoryCreateFailException(dir);\r
+                            }\r
+                        }\r
+                    }\r
+                } finally {\r
+                    lock.release();\r
+                }\r
+            } finally {\r
+                zipIn.close();\r
+            }\r
+        } finally {\r
+            fileIn.close();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ディレクトリを完全に削除します。\r
+     * </p>\r
+     * \r
+     * @param dir\r
+     *            削除するディレクトリ。\r
+     * @throws IOException\r
+     *             削除に失敗した場合。\r
+     */\r
+    private void delete(File dir) throws IOException {\r
+        for (File f : dir.listFiles()) {\r
+            if (!f.isDirectory()) {\r
+                if (!f.delete()) {\r
+                    throw new FileDeleteFailException(f);\r
+                }\r
+            } else {\r
+                this.delete(f);\r
+            }\r
+        }\r
+        if (!dir.delete()) {\r
+            throw new DirectoryDeleteFailException(dir);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 親ディレクトリが空であるならば、作業ディレクトリまで遡って削除します。\r
+     * </p>\r
+     * \r
+     * @param dir\r
+     *            削除するディレクトリ。\r
+     * @throws IOException\r
+     *             削除に失敗した場合。\r
+     */\r
+    private void deleteWithParent(File dir) throws IOException {\r
+        if (this._workDirectory.getAbsolutePath().equals(dir.getAbsolutePath())) {\r
+            return;\r
+        }\r
+        if (dir.listFiles().length > 0) {\r
+            return;\r
+        }\r
+        File parentDir = dir.getParentFile();\r
+        if (!dir.delete()) {\r
+            throw new IOException("ディレクトリ\"" + dir.getAbsolutePath() + "\"の削除に失敗しました。");\r
+        }\r
+        this.deleteWithParent(parentDir);\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * アーカイブ・ファイルの展開先ディレクトリを算出します。アーカイブ・ファイルの展開先は配置ディレクトリからの相対パスであるため、少し操作が必要になります。\r
+     * </p>\r
+     * \r
+     * @param archiveFile\r
+     *            展開するアーカイブ・ファイル。\r
+     * @param deployDirectory\r
+     *            配置ディレクトリ。\r
+     * @param workDirectory\r
+     *            作業ディレクトリ。\r
+     * @return アーカイブ・ファイルの展開先ディレクトリ。\r
+     */\r
+    private File getDestDirectory(File archiveFile, File deployDirectory, File workDirectory) {\r
+        String name = archiveFile.getAbsolutePath().substring(deployDirectory.getAbsolutePath().length());\r
+        File dir = new File(workDirectory, name);\r
+        return dir;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 配置ディレクトリを監視します。\r
+     * </p>\r
+     */\r
+    private class FileMonitorListenerImpl implements FileMonitorListener {\r
+\r
+        /**\r
+         * <p>\r
+         * インスタンスを初期化します。\r
+         * </p>\r
+         */\r
+        public FileMonitorListenerImpl() {\r
+        }\r
+\r
+        /**\r
+         * {@inheritDoc}\r
+         */\r
+        public void create(FileMonitor monitor, File file) {\r
+            try {\r
+                Deployer.this.deploy(file);\r
+            } catch (IOException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+\r
+        /**\r
+         * {@inheritDoc}\r
+         */\r
+        public void delete(FileMonitor monitor, File file) {\r
+            try {\r
+                Deployer.this.undeploy(file);\r
+            } catch (IOException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+\r
+        /**\r
+         * {@inheritDoc}\r
+         */\r
+        public void update(FileMonitor monitor, File file) {\r
+            try {\r
+                Deployer.this.undeploy(file);\r
+                Deployer.this.deploy(file);\r
+            } catch (IOException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DeployerClassLoader.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DeployerClassLoader.java
new file mode 100644 (file)
index 0000000..30a318f
--- /dev/null
@@ -0,0 +1,410 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.lang.ref.WeakReference;\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+import java.net.URLClassLoader;\r
+import java.util.ArrayList;\r
+import java.util.Enumeration;\r
+import java.util.List;\r
+\r
+/**\r
+ * <p>\r
+ * アーカイブ・ファイル配置後のクラスやリソースを読み込むクラスローダーです。\r
+ * </p>\r
+ * <p>\r
+ * アーカイブ・ファイルにはクラス・ファイル、リソース、jarファイルを含めることが出来、コンストラクタでディレクトリを指定することでクラスローダーの管理下に置くことができます。例えば、classes/からクラス・ファイル、lib/からjarファイルを検索するように初期化することが出来ます。ディレクトリは複数指定することが出来ます。\r
+ * </p>\r
+ * <p>\r
+ * 内部的には{@link URLClassLoader}クラスを使用しています。コンストラクタで指定された検索対象ディレクトリ、及びjarディレクトリに含まれるjarファイルは、{@link URLClassLoader}クラスにURLで渡されます。{@link #dispose()}メソッドが呼び出されると、{@link URLClassLoader}インスタンスは破棄され、強制的にガベージコレクタを動かすことで完全に破棄します(破棄しようとします。クラスローダーが読み込んだクラス内でリソースリークが発生している場合、破棄は失敗し、ブロックしてしまいます)。\r
+ * </p>\r
+ * <p>\r
+ * ホット・デプロイを前提としているので、クラスローダーが読み込んだリソースなどを破棄する{@link #dispose()}メソッドが用意されています。例えば{@link Deployer}クラスと連携する場合、{@link DeployerListener#undeployEnd(Deployer, File)}メソッドの呼び出しでこのクラスローダーを破棄することが出来ます。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public final class DeployerClassLoader extends ClassLoader {\r
+\r
+    /**\r
+     * 内部クラスローダの弱参照。参照の有効性を調べることで、クラスローダの破棄が成功したかどうかを判定するために使用しています。\r
+     */\r
+    private WeakReference<InternalURLClassLoader> wrCL;\r
+\r
+    /**\r
+     * 内部クラスローダ。クラスローダの実際の処理は、この内部クラスローダが行っています。\r
+     */\r
+    private InternalURLClassLoader                cl;\r
+\r
+    /**\r
+     * <p>\r
+     * {@link DeployerClassLoader}インスタンスを初期化します。\r
+     * </p>\r
+     * \r
+     * @param fileDirectories\r
+     *            クラス・ファイル、リソースなどを検索するディレクトリ。複数指定することが出来ます(例えば、classes/、conf/のように)。<br>\r
+     *            nullの場合は無視します。配列中のnullも無視します。\r
+     * @param jarDirectories\r
+     *            jarファイルを検索するディレクトリ。このディレクトリ以下に存在するjarファイルを読み込みます。<br>\r
+     *            nullの場合は無視します。配列中のnullも無視します。\r
+     * @param parent\r
+     *            親クラスローダー。\r
+     * @throws MalformedURLException\r
+     *             指定されたディレクトリの形式が不正である場合。\r
+     */\r
+    public DeployerClassLoader(File[] fileDirectories, File[] jarDirectories, ClassLoader parent) throws MalformedURLException {\r
+        super();\r
+\r
+        /*\r
+         * クラスローダの検索パスとして追加するURLを収集します。\r
+         */\r
+        List<URL> urlList = new ArrayList<URL>();\r
+\r
+        // クラス・ファイル、リソースなどを検索するディレクトリのパスを追加します。\r
+        if (fileDirectories != null) {\r
+            for (File f : fileDirectories) {\r
+                if (f != null) {\r
+                    urlList.add(f.toURL());\r
+                }\r
+            }\r
+        }\r
+\r
+        // jarファイルのパスを追加します。\r
+        if (jarDirectories != null) {\r
+            for (File f : jarDirectories) {\r
+                if (f != null) {\r
+                    urlList.addAll(this.getJarFileList(f));\r
+                }\r
+            }\r
+        }\r
+\r
+        /*\r
+         * 内部クラスローダを初期化します。\r
+         */\r
+        if (parent == null) {\r
+            this.cl = new InternalURLClassLoader(urlList.toArray(new URL[0]));\r
+        } else {\r
+            this.cl = new InternalURLClassLoader(urlList.toArray(new URL[0]), parent);\r
+        }\r
+        // 内部クラスローダの破棄を確認するため、弱参照を保持します。\r
+        this.wrCL = new WeakReference<InternalURLClassLoader>(this.cl);\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * {@link DeployerClassLoader}インスタンスを初期化します。\r
+     * </p>\r
+     * \r
+     * @param fileDirectories\r
+     *            クラス・ファイル、リソースなどを検索するディレクトリ。複数指定することが出来ます(例えば、classes/、conf/のように)。<br>\r
+     *            nullの場合は無視します。配列中のnullも無視します。\r
+     * @param jarDirectories\r
+     *            jarファイルを検索するディレクトリ。このディレクトリ以下に存在するjarファイルを読み込みます。<br>\r
+     *            nullの場合は無視します。配列中のnullも無視します。\r
+     * @throws MalformedURLException\r
+     *             指定されたディレクトリの形式が不正である場合。\r
+     */\r
+    public DeployerClassLoader(File[] fileDirectories, File[] jarDirectories) throws MalformedURLException {\r
+        this(fileDirectories, jarDirectories, null);\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 指定されたディレクトリ以下のjarファイルを検索し、そのURLをリストとして返します。\r
+     * </p>\r
+     * \r
+     * @param dir\r
+     *            検索するディレクトリ。<br>\r
+     *            nullの場合は空のリストを返します。\r
+     * @return 検索結果のURLのリスト。\r
+     * @throws MalformedURLException\r
+     *             URLの形式が不正である場合。\r
+     */\r
+    private List<URL> getJarFileList(File dir) throws MalformedURLException {\r
+        List<URL> urlList = new ArrayList<URL>();\r
+\r
+        if (dir == null) {\r
+            return urlList;\r
+        }\r
+\r
+        File[] files = dir.listFiles();\r
+        if (files == null) {\r
+            return urlList;\r
+        }\r
+\r
+        for (File f : files) {\r
+            if (f.isFile() && f.getName().toLowerCase().endsWith(".jar")) {\r
+                urlList.add(f.toURL());\r
+            } else if (f.isDirectory()) {\r
+                urlList.addAll(this.getJarFileList(f));\r
+            }\r
+        }\r
+\r
+        return urlList;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * クラスローダーを破棄します。これにより、クラスローダーは使用不可状態になり、クラスローダーに属していたクラスは解放されます。\r
+     * </p>\r
+     * <p>\r
+     * このメソッド呼び出しはタイムアウトしません。すなわち、以下のコードと等価です。\r
+     * </p>\r
+     * \r
+     * <pre>\r
+     * cl.dispose(0);\r
+     * </pre>\r
+     */\r
+    public void dispose() {\r
+        this.dispose(0);\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * クラスローダーを破棄します。これにより、クラスローダーは使用不可状態になり、クラスローダーに属していたクラスは解放されます。\r
+     * </p>\r
+     * <p>\r
+     * メソッド呼び出しの結果、クラスローダーはすぐに使用不可状態になりますが、属しているクラスの解放はすぐには行われない可能性があります。これは、クラスローダーのリソースの解放を強制ガベージコレクタに頼っているためです。このため、タイムアウト時間を指定することが出来ます。タイムアウト時間は破棄を試みますが、それでも破棄出来ない場合は{@link ClassLoaderUnloadFailException}例外をスローします。この場合、クラスローダーは使用不可状態になっていますが、クラスは破棄されていません。完全に破棄するために、このメソッド呼び出しを何度も試みることが出来ます。\r
+     * </p>\r
+     * \r
+     * @param timeout\r
+     *            破棄を試みるタイムアウト時間。0以下の場合、タイムアウトしない。\r
+     */\r
+    public void dispose(int timeout) {\r
+        this.cl = null;\r
+\r
+        // タイムアウト時間が経過するまで、破棄を試みます。\r
+        long t = System.currentTimeMillis();\r
+        while (((System.currentTimeMillis() - t) < timeout) || timeout <= 0) {\r
+            // 内部クラスローダを破棄するため、強制的にガベージコレクションを試みます。\r
+            System.gc();\r
+\r
+            // 内部クラスローダへの弱参照がnullになっている場合、破棄されたことを表します。\r
+            // 従って、処理を抜けます。\r
+            if (this.wrCL.get() == null) {\r
+                break;\r
+            }\r
+\r
+            // 処理の間隔をあけるため、単位時間の間、処理を中断します。\r
+            try {\r
+                Thread.sleep(Consts.SLEEP_UNIT_TIME);\r
+            } catch (InterruptedException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+\r
+        // 弱参照がnullではない場合、タイムアウトしたことを表します。\r
+        // 従って、例外をスローします。\r
+        if (this.wrCL.get() != null) {\r
+            throw new ClassLoaderUnloadFailException();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    protected Package definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) {\r
+        if (this.cl == null) {\r
+            throw new ClassLoaderUnloadedException();\r
+        }\r
+        return this.cl.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    protected Class<?> findClass(String name) throws ClassNotFoundException {\r
+        if (this.cl == null) {\r
+            throw new ClassLoaderUnloadedException();\r
+        }\r
+        return this.cl.findClass(name);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    protected String findLibrary(String libname) {\r
+        if (this.cl == null) {\r
+            throw new ClassLoaderUnloadedException();\r
+        }\r
+        return this.cl.findLibrary(libname);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    protected URL findResource(String name) {\r
+        if (this.cl == null) {\r
+            throw new ClassLoaderUnloadedException();\r
+        }\r
+        return this.cl.findResource(name);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    protected Enumeration<URL> findResources(String name) throws IOException {\r
+        if (this.cl == null) {\r
+            throw new ClassLoaderUnloadedException();\r
+        }\r
+        return this.cl.findResources(name);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    protected Package getPackage(String name) {\r
+        if (this.cl == null) {\r
+            throw new ClassLoaderUnloadedException();\r
+        }\r
+        return this.cl.getPackage(name);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    protected Package[] getPackages() {\r
+        if (this.cl == null) {\r
+            throw new ClassLoaderUnloadedException();\r
+        }\r
+        return this.cl.getPackages();\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {\r
+        if (this.cl == null) {\r
+            throw new ClassLoaderUnloadedException();\r
+        }\r
+        return this.cl.loadClass(name, resolve);\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 内部クラスローダ。必要なメソッドのアクセス修飾子をpublicに変更するために定義します。\r
+     * </p>\r
+     * \r
+     * @author uguu\r
+     */\r
+    private class InternalURLClassLoader extends URLClassLoader {\r
+\r
+        /**\r
+         * <p>\r
+         * インスタンスを初期化します。\r
+         * </p>\r
+         * \r
+         * @param urls\r
+         *            検索パスに含めるURLの配列。\r
+         */\r
+        public InternalURLClassLoader(URL[] urls) {\r
+            super(urls);\r
+        }\r
+\r
+        /**\r
+         * <p>\r
+         * インスタンスを初期化します。\r
+         * </p>\r
+         * \r
+         * @param urls\r
+         *            検索パスに含めるURLの配列。\r
+         * @param parent\r
+         *            親クラスローダー。\r
+         */\r
+        public InternalURLClassLoader(URL[] urls, ClassLoader parent) {\r
+            super(urls, parent);\r
+        }\r
+\r
+        /**\r
+         * {@inheritDoc}\r
+         */\r
+        @Override\r
+        public Package definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) {\r
+            return super.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);\r
+        }\r
+\r
+        /**\r
+         * {@inheritDoc}\r
+         */\r
+        @Override\r
+        public Class<?> findClass(String name) throws ClassNotFoundException {\r
+            return super.findClass(name);\r
+        }\r
+\r
+        /**\r
+         * {@inheritDoc}\r
+         */\r
+        @Override\r
+        public String findLibrary(String libname) {\r
+            return super.findLibrary(libname);\r
+        }\r
+\r
+        /**\r
+         * {@inheritDoc}\r
+         */\r
+        @Override\r
+        public Package getPackage(String name) {\r
+            return super.getPackage(name);\r
+        }\r
+\r
+        /**\r
+         * {@inheritDoc}\r
+         */\r
+        @Override\r
+        public Package[] getPackages() {\r
+            return super.getPackages();\r
+        }\r
+\r
+        /**\r
+         * {@inheritDoc}\r
+         */\r
+        @Override\r
+        public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {\r
+            return super.loadClass(name, resolve);\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DeployerListener.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DeployerListener.java
new file mode 100644 (file)
index 0000000..94fdf69
--- /dev/null
@@ -0,0 +1,112 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+import java.io.File;\r
+\r
+/**\r
+ * <p>\r
+ * {@link Deployer}クラスによるファイル配置のイベントを受け取るリスナーです。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public interface DeployerListener {\r
+\r
+    /**\r
+     * <p>\r
+     * アーカイブ・ファイルの配置を開始するときに呼び出されます。\r
+     * </p>\r
+     * \r
+     * @param deployer\r
+     *            イベントの通知元の{@link Deployer}インスタンス。\r
+     * @param file\r
+     *            配置するアーカイブ・ファイル。\r
+     */\r
+    void deployStart(Deployer deployer, File file);\r
+\r
+    /**\r
+     * <p>\r
+     * アーカイブ・ファイルから抽出したファイルを配置するときに呼び出されます。\r
+     * </p>\r
+     * \r
+     * @param deployer\r
+     *            イベントの通知元の{@link Deployer}インスタンス。\r
+     * @param file\r
+     *            配置するアーカイブ・ファイル。\r
+     * @param destDirectory\r
+     *            配置先のルート・ディレクトリ。\r
+     * @param deployFile\r
+     *            配置するファイル。\r
+     */\r
+    void deployFile(Deployer deployer, File file, File destDirectory, File deployFile);\r
+\r
+    /**\r
+     * <p>\r
+     * アーカイブ・ファイルの配置が終了したときに呼び出されます。\r
+     * </p>\r
+     * \r
+     * @param deployer\r
+     *            イベントの通知元の{@link Deployer}インスタンス。\r
+     * @param file\r
+     *            配置したアーカイブ・ファイル。\r
+     * @param destDirectory\r
+     *            配置先のルート・ディレクトリ。\r
+     */\r
+    void deployEnd(Deployer deployer, File file, File destDirectory);\r
+\r
+    /**\r
+     * <p>\r
+     * アーカイブ・ファイルの配置の解除を開始するときに呼び出されます。\r
+     * </p>\r
+     * \r
+     * @param deployer\r
+     *            イベントの通知元の{@link Deployer}インスタンス。\r
+     * @param file\r
+     *            配置解除するアーカイブ・ファイル。\r
+     * @param destDirectory\r
+     *            配置先のルート・ディレクトリ。\r
+     */\r
+    void undeployStart(Deployer deployer, File file, File destDirectory);\r
+\r
+    /**\r
+     * アーカイブ・ファイルの配置の解除が終了したときに呼び出されます。\r
+     * \r
+     * @param deployer\r
+     *            イベントの通知元の{@link Deployer}インスタンス。\r
+     * @param file\r
+     *            配置解除したアーカイブ・ファイル。\r
+     */\r
+    void undeployEnd(Deployer deployer, File file);\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DirectoryCreateFailException.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DirectoryCreateFailException.java
new file mode 100644 (file)
index 0000000..e9ccbf2
--- /dev/null
@@ -0,0 +1,59 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+\r
+/**\r
+ * <p>\r
+ * ディレクトリの作成に失敗したことを表す例外です。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public class DirectoryCreateFailException extends IOException {\r
+\r
+    /**\r
+     * <p>\r
+     * インスタンスを初期化します。\r
+     * </p>\r
+     * \r
+     * @param dir\r
+     *            作成に失敗したディレクトリ。\r
+     */\r
+    public DirectoryCreateFailException(File dir) {\r
+        super("ディレクトリ\"" + dir.getAbsolutePath() + "\"の作成に失敗しました。");\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DirectoryDeleteFailException.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/DirectoryDeleteFailException.java
new file mode 100644 (file)
index 0000000..9aec705
--- /dev/null
@@ -0,0 +1,59 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+\r
+/**\r
+ * <p>\r
+ * ディレクトリの削除に失敗したことを表す例外です。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public class DirectoryDeleteFailException extends IOException {\r
+\r
+    /**\r
+     * <p>\r
+     * インスタンスを初期化します。\r
+     * </p>\r
+     * \r
+     * @param dir\r
+     *            削除に失敗したディレクトリ。\r
+     */\r
+    public DirectoryDeleteFailException(File dir) {\r
+        super("ディレクトリ\"" + dir.getAbsolutePath() + "\"の削除に失敗しました。");\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileCreateFailException.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileCreateFailException.java
new file mode 100644 (file)
index 0000000..61bdd28
--- /dev/null
@@ -0,0 +1,59 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+\r
+/**\r
+ * <p>\r
+ * ファイルの作成に失敗したことを表す例外です。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public class FileCreateFailException extends IOException {\r
+\r
+    /**\r
+     * <p>\r
+     * インスタンスを初期化します。\r
+     * </p>\r
+     * \r
+     * @param file\r
+     *            作成に失敗したファイル。\r
+     */\r
+    public FileCreateFailException(File file) {\r
+        super("ファイル\"" + file.getAbsolutePath() + "\"の作成に失敗しました。");\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileDeleteFailException.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileDeleteFailException.java
new file mode 100644 (file)
index 0000000..fb9791d
--- /dev/null
@@ -0,0 +1,59 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+\r
+/**\r
+ * <p>\r
+ * ファイルの削除に失敗したことを表す例外です。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public class FileDeleteFailException extends IOException {\r
+\r
+    /**\r
+     * <p>\r
+     * インスタンスを初期化します。\r
+     * </p>\r
+     * \r
+     * @param file\r
+     *            削除に失敗したファイル。\r
+     */\r
+    public FileDeleteFailException(File file) {\r
+        super("ファイル\"" + file.getAbsolutePath() + "\"の削除に失敗しました。");\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileMonitor.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileMonitor.java
new file mode 100644 (file)
index 0000000..59ca9c2
--- /dev/null
@@ -0,0 +1,592 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.IOException;\r
+import java.security.MessageDigest;\r
+import java.security.NoSuchAlgorithmException;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.regex.Pattern;\r
+\r
+/**\r
+ * <p>\r
+ * ファイルの作成、更新、削除を監視し、イベントを通知します。\r
+ * </p>\r
+ * <p>\r
+ * {@link #monitor()}メソッドの呼び出しでファイルを一回監視することが出来ます。ファイルを定期的に監視する場合、定期的に{@link #monitor()}メソッドを呼び出してください。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public final class FileMonitor {\r
+\r
+    /**\r
+     * <p>\r
+     * リスナーのリスト。\r
+     * </p>\r
+     */\r
+    private List<FileMonitorListener>       _listenerList      = new ArrayList<FileMonitorListener>();\r
+\r
+    /**\r
+     * <p>\r
+     * 監視する基底ディレクトリ。\r
+     * </p>\r
+     */\r
+    private File                            _baseDirectory;\r
+\r
+    /**\r
+     * <p>\r
+     * 監視するファイルの正規表現パターン。\r
+     * </p>\r
+     */\r
+    private Pattern                         _filePattern;\r
+\r
+    /**\r
+     * <p>\r
+     * 監視中ファイルの情報。\r
+     * </p>\r
+     */\r
+    private Map<String, MonitoringFileInfo> _monitoringFileMap = new HashMap<String, MonitoringFileInfo>();\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルの長さを比較するか。\r
+     * </p>\r
+     */\r
+    private boolean                         _checkLength       = true;\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルの最終更新日時を比較するか。\r
+     * </p>\r
+     */\r
+    private boolean                         _checkLastModified = true;\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルの内容を確認するか。\r
+     * </p>\r
+     */\r
+    private boolean                         _checkContent;\r
+\r
+    /**\r
+     * <p>\r
+     * ハッシュ・アルゴリズム。\r
+     * </p>\r
+     */\r
+    private String                          _hashAlgorithm     = "MD5";\r
+\r
+    /**\r
+     * <p>\r
+     * 指定したディレクトリの指定したパターンに合致するファイルを監視する{@link FileMonitor}インスタンスを初期化します。\r
+     * </p>\r
+     * \r
+     * @param baseDirectory\r
+     *            監視するディレクトリ。<br>\r
+     *            nullの場合、{@link IllegalArgumentException}例外をスローします。<br>\r
+     *            ディレクトリを表していない場合、{@link IllegalArgumentException}例外をスローします。\r
+     * @param filePattern\r
+     *            監視するファイルのパターンを表す正規表現。絶対パスと比較されます。<br>\r
+     *            nullの場合、{@link IllegalArgumentException}例外をスローします。\r
+     */\r
+    public FileMonitor(File baseDirectory, Pattern filePattern) {\r
+        if (baseDirectory == null) {\r
+            throw new IllegalArgumentException("baseDirectory is null.");\r
+        }\r
+        if (!baseDirectory.isDirectory()) {\r
+            throw new IllegalArgumentException("baseDirectory is not directory.");\r
+        }\r
+        if (filePattern == null) {\r
+            throw new IllegalArgumentException("filePattern is null.");\r
+        }\r
+        this._baseDirectory = baseDirectory;\r
+        this._filePattern = filePattern;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 指定したディレクトリの全てのファイルを監視する{@link FileMonitor}インスタンスを初期化します。\r
+     * </p>\r
+     * <p>\r
+     * このコンストラクタ呼び出しは、以下のコードと等価です。\r
+     * </p>\r
+     * \r
+     * <pre>\r
+     * new FileMonitor(baseDirectory, Pattern.compile(&quot;.*&quot;))\r
+     * </pre>\r
+     * \r
+     * @param baseDirectory\r
+     *            監視するディレクトリ。<br>\r
+     *            nullの場合、{@link IllegalArgumentException}例外をスローします。<br>\r
+     *            ディレクトリを表していない場合、{@link IllegalArgumentException}例外をスローします。\r
+     */\r
+    public FileMonitor(File baseDirectory) {\r
+        this(baseDirectory, Pattern.compile(".*"));\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ファイル・サイズを監視するかどうかを取得します。初期値はtrueです。\r
+     * </p>\r
+     * \r
+     * @return ファイル・サイズを監視する場合はtrue、監視しない場合はfalse。\r
+     */\r
+    public boolean isCheckLength() {\r
+        return this._checkLength;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ファイル・サイズを監視するかどうかを設定します。\r
+     * </p>\r
+     * \r
+     * @param checkLength\r
+     *            ファイル・サイズを監視する場合はtrue、監視しない場合はfalse。\r
+     */\r
+    public void setCheckLength(boolean checkLength) {\r
+        this._checkLength = checkLength;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 最終更新日時を監視するかどうかを取得します。初期値はtrueです。\r
+     * </p>\r
+     * \r
+     * @return 最終更新日時を監視する場合はtrue、監視しない場合はfalse。\r
+     */\r
+    public boolean isCheckLastModified() {\r
+        return this._checkLastModified;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 最終更新日時を監視するかどうかを設定します。\r
+     * </p>\r
+     * \r
+     * @param checkLastModified\r
+     *            最終更新日時を監視する場合はtrue、監視しない場合はfalse。\r
+     */\r
+    public void setCheckLastModified(boolean checkLastModified) {\r
+        this._checkLastModified = checkLastModified;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルの内容(ハッシュ値)を監視するかどうかを取得します。初期値はfalseです。\r
+     * </p>\r
+     * \r
+     * @return ファイルの内容を監視する場合はtrue、監視しない場合はfalse。\r
+     */\r
+    public boolean isCheckContent() {\r
+        return this._checkContent;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルの内容(ハッシュ値)を監視するかどうかを設定します。\r
+     * </p>\r
+     * <p>\r
+     * ファイルの内容を監視すると、監視のパフォーマンスが低下する場合があります。\r
+     * </p>\r
+     * \r
+     * @param checkContent\r
+     *            ファイルの内容を監視する場合はtrue、監視しない場合はfalse。\r
+     */\r
+    public void setCheckContent(boolean checkContent) {\r
+        this._checkContent = checkContent;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルの内容を比較するときに使用するハッシュ・アルゴリズムを取得します。初期値は"MD5"です。\r
+     * </p>\r
+     * \r
+     * @return ハッシュ・アルゴリズム。\r
+     */\r
+    public String getHashAlgorithm() {\r
+        return this._hashAlgorithm;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルの内容を比較するときに使用するハッシュ・アルゴリズムを設定します。\r
+     * </p>\r
+     * <p>\r
+     * ハッシュ値の計算は{@link MessageDigest}クラスを使用します。従って、このメソッドで指定するハッシュ・アルゴリズムは{@link MessageDigest}クラスがサポートするアルゴリズムである必要があります。{@link MessageDigest}クラスがサポートしないハッシュ・アルゴリズムを設定した場合、{@link #monitor()}メソッドの呼び出しで{@link FileMonitorFailException}例外がスローされる可能性があります。\r
+     * </p>\r
+     * \r
+     * @param hashAlgorithm\r
+     *            ハッシュ・アルゴリズム。\r
+     */\r
+    public void setHashAlgorithm(String hashAlgorithm) {\r
+        this._hashAlgorithm = hashAlgorithm;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルの作成、更新、削除を認識したときにイベントが通知されるリスナーを追加します。\r
+     * </p>\r
+     * <p>\r
+     * このメソッドはスレッドセーフです。\r
+     * </p>\r
+     * \r
+     * @param listener\r
+     *            イベントが通知されるリスナー。<br>\r
+     *            nullの場合、{@link IllegalArgumentException}例外をスローします。\r
+     */\r
+    public void addListener(FileMonitorListener listener) {\r
+        if (listener == null) {\r
+            throw new IllegalArgumentException("listener is null.");\r
+        }\r
+        synchronized (this._listenerList) {\r
+            this._listenerList.add(listener);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 登録されているリスナーを削除します。\r
+     * </p>\r
+     * <p>\r
+     * このメソッドはスレッドセーフです。\r
+     * </p>\r
+     * \r
+     * @param listener\r
+     *            削除するリスナー。\r
+     */\r
+    public void removeListener(FileMonitorListener listener) {\r
+        synchronized (this._listenerList) {\r
+            this._listenerList.remove(listener);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * リスナーの配列を返します。\r
+     * </p>\r
+     * <p>\r
+     * このメソッドはスレッドセーフです。\r
+     * </p>\r
+     * \r
+     * @return リスナーの配列。\r
+     */\r
+    private FileMonitorListener[] getListeners() {\r
+        synchronized (this._listenerList) {\r
+            return this._listenerList.toArray(new FileMonitorListener[0]);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルの作成、更新、削除を監視し、リスナーにイベントを通知します。\r
+     * </p>\r
+     * \r
+     * @throws FileMonitorFailException\r
+     *             ファイルの監視に失敗した場合。\r
+     */\r
+    public void monitor() throws FileMonitorFailException {\r
+        try {\r
+            this.checkCreateOrUpdate(this._baseDirectory);\r
+        } catch (NoSuchAlgorithmException e) {\r
+            throw new FileMonitorFailException(e);\r
+        } catch (IOException e) {\r
+            throw new FileMonitorFailException(e);\r
+        }\r
+        this.checkDelete();\r
+        this.checkClear();\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ディレクトリ内のファイルの作成、更新を確認します。\r
+     * </p>\r
+     * \r
+     * @param dir\r
+     *            確認するディレクトリ。\r
+     * @throws IOException\r
+     *             入出力に失敗した場合。\r
+     * @throws NoSuchAlgorithmException\r
+     *             ハッシュ・アルゴリズムが見つからなかった場合。\r
+     */\r
+    private void checkCreateOrUpdate(File dir) throws IOException, NoSuchAlgorithmException {\r
+        if (dir == null) {\r
+            return;\r
+        }\r
+\r
+        File[] files = dir.listFiles();\r
+        if (files == null) {\r
+            return;\r
+        }\r
+\r
+        for (File f : files) {\r
+            if (f.isFile()) {\r
+                this.checkFileCreateOrUpdate(f);\r
+            } else {\r
+                this.checkCreateOrUpdate(f);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルの作成、更新を確認します。\r
+     * </p>\r
+     * \r
+     * @param file\r
+     *            確認するファイル。\r
+     * @throws IOException\r
+     *             入出力に失敗した場合。\r
+     * @throws NoSuchAlgorithmException\r
+     *             ハッシュ・アルゴリズムが見つからなかった場合。\r
+     */\r
+    private void checkFileCreateOrUpdate(File file) throws NoSuchAlgorithmException, IOException {\r
+        if (this._filePattern.matcher(file.getAbsolutePath()).matches()) {\r
+            synchronized (this._monitoringFileMap) {\r
+                if (!this._monitoringFileMap.containsKey(file.getAbsolutePath())) {\r
+                    // ファイルがマップに存在しない場合、新規のモニター対象。\r
+                    MonitoringFileInfo info = new MonitoringFileInfo();\r
+                    info.path = file.getAbsolutePath();\r
+                    this.setMonitoringFileInfo(file, info);\r
+                    info.checked = true;\r
+                    this._monitoringFileMap.put(file.getAbsolutePath(), info);\r
+                    // イベントを通知する。\r
+                    FileMonitorListener[] listeners = this.getListeners();\r
+                    for (FileMonitorListener l : listeners) {\r
+                        l.create(this, file);\r
+                    }\r
+                } else {\r
+                    // ファイルがマップに存在する場合、変更のモニター対象。\r
+                    MonitoringFileInfo info = this._monitoringFileMap.get(file.getAbsolutePath());\r
+                    if (this.isModified(file, info)) {\r
+                        this.setMonitoringFileInfo(file, info);\r
+                        // イベントを通知する。\r
+                        FileMonitorListener[] listeners = this.getListeners();\r
+                        for (FileMonitorListener l : listeners) {\r
+                            l.update(this, file);\r
+                        }\r
+                    }\r
+                    info.checked = true;\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 更新されているかどうかを調べます。\r
+     * </p>\r
+     * \r
+     * @param file\r
+     *            元のファイル。\r
+     * @param info\r
+     *            監視中ファイルの情報。\r
+     * @return 更新されている場合はtrue、更新されていない場合はfalse。\r
+     * @throws IOException\r
+     *             入出力に失敗した場合。\r
+     * @throws NoSuchAlgorithmException\r
+     *             ハッシュ・アルゴリズムが見つからなかった場合。\r
+     */\r
+    private boolean isModified(File file, MonitoringFileInfo info) throws NoSuchAlgorithmException, IOException {\r
+        if (this._checkLength) {\r
+            if (file.length() != info.length) {\r
+                return true;\r
+            }\r
+        }\r
+        if (this._checkLastModified) {\r
+            if (file.lastModified() != info.lastModified) {\r
+                return true;\r
+            }\r
+        }\r
+        if (this._checkContent) {\r
+            if (!Arrays.equals(this.getHashData(file), info.hashData)) {\r
+                return true;\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 監視中ファイル情報に新しい情報を設定します。\r
+     * </p>\r
+     * \r
+     * @param file\r
+     *            元のファイル。\r
+     * @param info\r
+     *            監視中ファイルの情報。\r
+     * @throws IOException\r
+     *             入出力に失敗した場合。\r
+     * @throws NoSuchAlgorithmException\r
+     *             ハッシュ・アルゴリズムが見つからなかった場合。\r
+     */\r
+    private void setMonitoringFileInfo(File file, MonitoringFileInfo info) throws NoSuchAlgorithmException, IOException {\r
+        if (this._checkLength) {\r
+            info.length = file.length();\r
+        }\r
+        if (this._checkLastModified) {\r
+            info.lastModified = file.lastModified();\r
+        }\r
+        if (this._checkContent) {\r
+            info.hashData = this.getHashData(file);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * ハッシュ値を算出します。\r
+     * </p>\r
+     * \r
+     * @param file\r
+     *            算出元のファイル。\r
+     * @return ハッシュ値。\r
+     * @throws IOException\r
+     *             入出力に失敗した場合。\r
+     * @throws NoSuchAlgorithmException\r
+     *             ハッシュ・アルゴリズムが見つからなかった場合。\r
+     */\r
+    private byte[] getHashData(File file) throws IOException, NoSuchAlgorithmException {\r
+        MessageDigest md = MessageDigest.getInstance(this._hashAlgorithm);\r
+\r
+        FileInputStream fileIn = new FileInputStream(file);\r
+        try {\r
+            byte[] buf = new byte[Consts.BUFFER_LENGTH];\r
+            int len;\r
+            while ((len = fileIn.read(buf)) != -1) {\r
+                md.update(buf, 0, len);\r
+            }\r
+        } finally {\r
+            fileIn.close();\r
+        }\r
+\r
+        return md.digest();\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 削除されているかどうかを調べます。\r
+     * </p>\r
+     */\r
+    private void checkDelete() {\r
+        synchronized (this._monitoringFileMap) {\r
+            List<String> removeFileList = new ArrayList<String>();\r
+            for (MonitoringFileInfo info : this._monitoringFileMap.values()) {\r
+                if (!info.checked) {\r
+                    File f = new File(info.path);\r
+                    if (!f.exists()) {\r
+                        removeFileList.add(info.path);\r
+                        // イベントを通知する。\r
+                        FileMonitorListener[] listeners = this.getListeners();\r
+                        for (FileMonitorListener l : listeners) {\r
+                            l.delete(this, f);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            for (String path : removeFileList) {\r
+                this._monitoringFileMap.remove(path);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 監視中ファイルの情報のチェック済みマークをクリアします。\r
+     * </p>\r
+     */\r
+    private void checkClear() {\r
+        synchronized (this._monitoringFileMap) {\r
+            for (MonitoringFileInfo info : this._monitoringFileMap.values()) {\r
+                info.checked = false;\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * <p>\r
+     * 監視中ファイルの情報です。\r
+     * </p>\r
+     */\r
+    private class MonitoringFileInfo {\r
+\r
+        /**\r
+         * <p>\r
+         * パス。\r
+         * </p>\r
+         */\r
+        private String  path;\r
+\r
+        /**\r
+         * <p>\r
+         * ファイルの長さ。\r
+         * </p>\r
+         */\r
+        private long    length;\r
+\r
+        /**\r
+         * <p>\r
+         * 最終更新日時。\r
+         * </p>\r
+         */\r
+        private long    lastModified;\r
+\r
+        /**\r
+         * <p>\r
+         * ハッシュ値。\r
+         * </p>\r
+         */\r
+        private byte[]  hashData;\r
+\r
+        /**\r
+         * <p>\r
+         * チェック済みマーク。\r
+         * </p>\r
+         */\r
+        private boolean checked;\r
+\r
+        /**\r
+         * <p>\r
+         * インスタンスを初期化します。\r
+         * </p>\r
+         */\r
+        MonitoringFileInfo() {\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileMonitorFailException.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileMonitorFailException.java
new file mode 100644 (file)
index 0000000..d269f10
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+/**\r
+ * <p>\r
+ * ファイルの監視に失敗したことを表す例外です。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public class FileMonitorFailException extends Exception {\r
+\r
+    /**\r
+     * <p>\r
+     * インスタンスを初期化します。\r
+     * </p>\r
+     * \r
+     * @param e\r
+     *            例外の原因。\r
+     */\r
+    public FileMonitorFailException(Exception e) {\r
+        super("ファイルの監視に失敗しました。", e);\r
+    }\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileMonitorListener.java b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/FileMonitorListener.java
new file mode 100644 (file)
index 0000000..c83992d
--- /dev/null
@@ -0,0 +1,82 @@
+/*\r
+ * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ *    1. Redistributions of source code must retain the above copyright\r
+ *       notice, this list of conditions and the following disclaimer.\r
+ *\r
+ *    2. Redistributions in binary form must reproduce the above copyright\r
+ *       notice, this list of conditions and the following disclaimer in the\r
+ *       documentation and/or other materials provided with the distribution.\r
+ *\r
+ *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
+ *       contributors may be used to endorse or promote products derived\r
+ *       from this software without prior written permission. For written\r
+ *       permission, please contact clarkware@clarkware.com.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
+ * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+package jp.sourceforge.deployer;\r
+\r
+import java.io.File;\r
+\r
+/**\r
+ * <p>\r
+ * {@link FileMonitor}クラスによるファイル監視のイベントを受け取るリスナーです。\r
+ * </p>\r
+ * \r
+ * @author $Author$\r
+ * @version $Rev$\r
+ */\r
+public interface FileMonitorListener {\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルが作成されたときに呼び出されます。\r
+     * </p>\r
+     * \r
+     * @param monitor\r
+     *            イベントの通知元の{@link FileMonitor}インスタンス。\r
+     * @param file\r
+     *            作成されたファイル。\r
+     */\r
+    void create(FileMonitor monitor, File file);\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルが更新されたときに呼び出されます。\r
+     * </p>\r
+     * \r
+     * @param monitor\r
+     *            イベントの通知元の{@link FileMonitor}インスタンス。\r
+     * @param file\r
+     *            更新されたファイル。\r
+     */\r
+    void update(FileMonitor monitor, File file);\r
+\r
+    /**\r
+     * <p>\r
+     * ファイルが削除されたときに呼び出されます。\r
+     * </p>\r
+     * \r
+     * @param monitor\r
+     *            イベントの通知元の{@link FileMonitor}インスタンス。\r
+     * @param file\r
+     *            削除されたファイル。\r
+     */\r
+    void delete(FileMonitor monitor, File file);\r
+\r
+}\r
diff --git a/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/package.html b/deployer/tags/1.0.0/src/main/java/jp/sourceforge/deployer/package.html
new file mode 100644 (file)
index 0000000..4eb9f8d
--- /dev/null
@@ -0,0 +1,3 @@
+<body>\r
+    <p>ホット デプロイ機能を持つコンポーネントを提供します。デプロイヤーは、特定ディレクトリにファイルが配置されたとき、それを作業ディレクトリに展開し、独自クラスローダーを構築し、アプリケーションにイベントを通知します。</p>\r
+</body>\r
diff --git a/deployer/tags/1.0.0/src/site/changes.xml b/deployer/tags/1.0.0/src/site/changes.xml
new file mode 100644 (file)
index 0000000..6b92df0
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="Shift_JIS"?>\r
+<document>\r
+    <properties>\r
+        <title>\83f\83v\83\8d\83C\83\84\81[ - \95Ï\8dX\97\9a\97ð</title>\r
+        <author email="uguu@users.sourceforge.jp">uguu</author>\r
+    </properties>\r
+    <body>\r
+        <release version="1.0" date="2007-05-29" description="\8dÅ\8f\89\82Ì\83\8a\83\8a\81[\83X">\r
+            <action dev="uguu" type="update">\r
+                \8dÅ\8f\89\82Ì\83\8a\83\8a\81[\83X\82Å\82·\81B\r
+            </action>\r
+        </release>\r
+    </body>\r
+</document>\r
diff --git a/deployer/tags/1.0.0/src/site/site.xml b/deployer/tags/1.0.0/src/site/site.xml
new file mode 100644 (file)
index 0000000..a0a8a57
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="Shift_JIS"?>\r
+<project name="deployer">\r
+    <bannerLeft>\r
+        <name>\83f\83v\83\8d\83C\83\84\81[</name>\r
+        <href>http://deployer.sourceforge.jp/</href>\r
+    </bannerLeft>\r
+    <bannerRight>\r
+        <name>SourceForge.jp Project Info</name>\r
+        <src>http://sourceforge.jp/sflogo.php?group_id=2875</src>\r
+        <href>https://sourceforge.jp/projects/deployer/</href>\r
+    </bannerRight>\r
+    <body>\r
+        <links>\r
+            <item name="SourceForge.jp" href="http://sourceforge.jp/" />\r
+        </links>\r
+        <menu name="\83f\83v\83\8d\83C\83\84\81[">\r
+            <item name="\8aT\97v" href="index.html" />\r
+            <item name="\83z\83b\83g\83f\83v\83\8d\83C" href="hotdeploy.html" />\r
+            <item name="\83A\81[\83J\83C\83u\82Ì\8d\\91¢" href="archive.html" />\r
+            <item name="\83R\81[\83f\83B\83\93\83O\97á" href="coding.html" />\r
+            <item name="\83_\83E\83\93\83\8d\81[\83h" href="https://sourceforge.jp/projects/deployer/files/" />\r
+            <item name="\8dX\90V\97\9a\97ð" href="changes-report.html" />\r
+        </menu>\r
+        ${reports}\r
+    </body>\r
+</project>\r
diff --git a/deployer/tags/1.0.0/src/site/xdoc/archive.xml b/deployer/tags/1.0.0/src/site/xdoc/archive.xml
new file mode 100644 (file)
index 0000000..5c805e9
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="Shift_JIS"?>\r
+<document>\r
+    <properties>\r
+        <author email="uguu at users.sourceforge.jp">uguu</author>\r
+        <title>\83f\83v\83\8d\83C\83\84\81[ - \83A\81[\83J\83C\83u\82Ì\8d\\91¢</title>\r
+    </properties>\r
+    <body>\r
+        <section name="\83A\81[\83J\83C\83u\82Ì\8d\\91¢">\r
+            <p>\83A\81[\83J\83C\83u\82Í\88È\89º\82Ì\97v\91f\82Å\8d\\90¬\82³\82ê\82Ü\82·\81B</p>\r
+            <ul>\r
+                <li>\83N\83\89\83\83t\83@\83C\83\8b\81B</li>\r
+                <li>jar\83t\83@\83C\83\8b\81B</li>\r
+                <li>\82»\82Ì\91¼\82Ì\83t\83@\83C\83\8b(\83\8a\83\\81[\83X)\81B</li>\r
+            </ul>\r
+            <p>\82±\82Ì\8d\\90¬\82Í\8e©\97R\82É\92è\8b`\82·\82é\82±\82Æ\82ª\8fo\97\88\82Ü\82·\81B\97á\82¦\82Î\81A</p>\r
+            <source>/\r
++---WEB-INF/\r
+    +---classes/\r
+    |   +---\83N\83\89\83X\81E\83t\83@\83C\83\8b\81A\83\8a\83\\81[\83X\81B\r
+    +---lib/\r
+        +---jar\83t\83@\83C\83\8b\81B</source>\r
+            <p>\82Æ\82¢\82¤\8d\\90¬\82Å\82 \82Á\82½\82è\81A</p>\r
+            <source>/\r
++---bin/\r
+|   +---jar\83t\83@\83C\83\8b\81B\r
++---conf/\r
+    +---\83\8a\83\\81[\83X\81E\83t\83@\83C\83\8b(\95K\91R\93I\82É\83N\83\89\83X\81E\83t\83@\83C\83\8b\82à)\81B</source>\r
+            <p>\82Æ\82¢\82¤\8d\\90¬\82ð\92è\8b`\82·\82é\82±\82Æ\82ª\8fo\97\88\82Ü\82·\81B\82±\82ê\82Í\81ADeployerClassLoader\83N\83\89\83X\82Ì\83R\83\93\83X\83g\83\89\83N\83^\82É\8ew\92è\82·\82é\88ø\90\94\82Å\92è\8b`\82µ\82Ü\82·\81B</p>\r
+        </section>\r
+    </body>\r
+</document>\r
diff --git a/deployer/tags/1.0.0/src/site/xdoc/coding.xml b/deployer/tags/1.0.0/src/site/xdoc/coding.xml
new file mode 100644 (file)
index 0000000..f1bf88c
--- /dev/null
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="Shift_JIS"?>\r
+<document>\r
+    <properties>\r
+        <author email="uguu at users.sourceforge.jp">uguu</author>\r
+        <title>\83f\83v\83\8d\83C\83\84\81[ - \83R\81[\83f\83B\83\93\83O\97á</title>\r
+    </properties>\r
+    <body>\r
+        <section name="\83R\81[\83f\83B\83\93\83O\97á">\r
+            <p>\88È\89º\82Ì\82æ\82¤\82È\8d\\91¢\82Ì\83A\81[\83J\83C\83u\81E\83t\83@\83C\83\8b\82ð\8dl\82¦\82Ü\82·\81B</p>\r
+            <source>/\r
++---classes/\r
+|   +---\83N\83\89\83X\81E\83t\83@\83C\83\8b\r
++---lib/\r
+    +---jar\83t\83@\83C\83\8b</source>\r
+            <p>\88È\89º\82Ì\97v\8c\8f\82Ì\83T\81[\83o\81E\83N\83\89\83X\82ð\8f\91\82­\82±\82Æ\82ð\8dl\82¦\82Ü\82·\81B</p>\r
+            <ul>\r
+                <li>\83T\81[\83o\81E\83N\83\89\83X\82ÌFQN\82Í"example.ExampleServer"\82Æ\82µ\82Ü\82·\81B</li>\r
+                <li>\82±\82Ì\83A\81[\83J\83C\83u\81E\83t\83@\83C\83\8b\82ðdeploy\83f\83B\83\8c\83N\83g\83\8a\82É\94z\92u\82·\82é\82Æ\81Awork\83f\83B\83\8c\83N\83g\83\8a\82É\93W\8aJ\82µ\81A\83N\83\89\83X\83\8d\81[\83_\82ð\8d\\92z\82µ\81A\95Ê\83X\83\8c\83b\83h\82ÅMain\83N\83\89\83X\82Ìexecute()\83\81\83\\83b\83h\82ð\8cÄ\82Ñ\8fo\82µ\82Ü\82·\81B</li>\r
+                <li>deploy\83f\83B\83\8c\83N\83g\83\8a\82É\94z\92u\82³\82ê\82½\83A\81[\83J\83C\83u\81E\83t\83@\83C\83\8b\82ð\8dí\8f\9c\82·\82é\82Æ\81Awork\83f\83B\83\8c\83N\83g\83\8a\82É\93W\8aJ\82³\82ê\82½\83t\83@\83C\83\8b\82ª\8dí\8f\9c\82³\82ê\81A\83N\83\89\83X\83\8d\81[\83_\82ª\94j\8aü\82³\82ê\82Ü\82·\81B</li>\r
+            </ul>\r
+            <p>\82±\82Ì\82æ\82¤\82È\83T\81[\83o\82Í\81A\88È\89º\82Ì\82æ\82¤\82È\83R\81[\83h\82Å\8eÀ\8c»\82Å\82«\82Ü\82·\81B</p>\r
+            <source><![CDATA[package example;\r
+\r
+import java.io.File;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.regex.Pattern;\r
+\r
+import jp.sourceforge.deployer.Deployer;\r
+import jp.sourceforge.deployer.DeployerClassLoader;\r
+import jp.sourceforge.deployer.DeployerListener;\r
+\r
+public class ExampleServer implements DeployerListener {\r
+\r
+    private static Deployer                  deployer;\r
+\r
+    private Map<String, DeployerClassLoader> appMap = new HashMap<String, DeployerClassLoader>();\r
+\r
+    public static void main(String[] args) throws Exception {\r
+        File deployDir = new File("./deploy");\r
+        Pattern filePattern = Pattern.compile(".*\\.jar");\r
+        File workDir = new File("./work");\r
+\r
+        deployer = new Deployer(deployDir, filePattern, workDir);\r
+        deployer.addListener(new ExampleServer());\r
+\r
+        while (true) {\r
+            deployer.monitor();\r
+            Thread.sleep(1000);\r
+        }\r
+    }\r
+\r
+    public void deployEnd(Deployer deployer, File file, File destDirectory) {\r
+        try {\r
+            System.out.println("deployEnd: " + file.getAbsolutePath());\r
+\r
+            File[] fileDirectories = new File[] { new File(destDirectory, "classes") };\r
+            File[] jarDirectories = new File[] { new File(destDirectory, "lib") };\r
+\r
+            final DeployerClassLoader cl = new DeployerClassLoader(fileDirectories, jarDirectories);\r
+\r
+            this.appMap.put(file.getAbsolutePath(), cl);\r
+\r
+            Runnable r = new Runnable() {\r
+\r
+                public void run() {\r
+                    try {\r
+                        Class clazz = cl.loadClass("Main");\r
+                        Object obj = clazz.newInstance();\r
+                        clazz.getMethod("execute").invoke(obj);\r
+                    } catch (Exception e) {\r
+                        e.printStackTrace();\r
+                    }\r
+                }\r
+\r
+            };\r
+            Thread t = new Thread(r);\r
+            t.start();\r
+        } catch (Throwable t) {\r
+            t.printStackTrace();\r
+        }\r
+    }\r
+\r
+    public void deployFile(Deployer deployer, File file, File destDirectory, File deployFile) {\r
+        System.out.println("deployFile: " + deployFile.getAbsolutePath());\r
+    }\r
+\r
+    public void deployStart(Deployer deployer, File file) {\r
+        System.out.println("deployStart: " + file.getAbsolutePath());\r
+    }\r
+\r
+    public void undeployEnd(Deployer deployer, File file) {\r
+        System.out.println("undeployEnd: " + file.getAbsolutePath());\r
+\r
+        DeployerClassLoader cl = this.appMap.get(file.getAbsolutePath());\r
+        cl.dispose();\r
+    }\r
+\r
+    public void undeployStart(Deployer deployer, File file, File destDirectory) {\r
+        System.out.println("undeployStart: " + file.getAbsolutePath());\r
+    }\r
+\r
+}]]></source>\r
+        </section>\r
+    </body>\r
+</document>\r
diff --git a/deployer/tags/1.0.0/src/site/xdoc/hotdeploy.xml b/deployer/tags/1.0.0/src/site/xdoc/hotdeploy.xml
new file mode 100644 (file)
index 0000000..0a96afc
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="Shift_JIS"?>\r
+<document>\r
+    <properties>\r
+        <author email="uguu at users.sourceforge.jp">uguu</author>\r
+        <title>\83f\83v\83\8d\83C\83\84\81[ - \83z\83b\83g\83f\83v\83\8d\83C</title>\r
+    </properties>\r
+    <body>\r
+        <section name="\83z\83b\83g\83f\83v\83\8d\83C">\r
+            <p>\83A\83v\83\8a\83P\81[\83V\83\87\83\93\81E\83T\81[\83o\82É\82¨\82¢\82Ä\81A\83A\83v\83\8a\83P\81[\83V\83\87\83\93\82Ì\83t\83@\83C\83\8b\82ª\94z\92u\82³\82ê\82é\82Æ\8e©\93®\93I\82É\83T\81[\83o\82É\83f\83v\83\8d\83C\82³\82ê\81A\83t\83@\83C\83\8b\82ª\8dí\8f\9c\82³\82ê\82é\82Æ\8e©\93®\93I\82É\83T\81[\83o\82©\82ç\83A\83\93\83f\83v\83\8d\83C\82³\82ê\82é\8b@\94\\82ð\95\\82µ\82Ü\82·\81Bjava\82Ì\8fê\8d\87\81A\88ê\94Ê\93I\82É\82Í\83t\83@\83C\83\8b\82Íjar\88³\8fk\8c`\8e®(\8ag\92£\8eq\82Í\97l\81X\82È\82Å\82·\82ª)\82Å\81A\82 \82é\83f\83B\83\8c\83N\83g\83\8a\82É\94z\92u\82³\82ê\82é\82Æ\81A\83T\81[\83o\82ª\8e©\93®\93I\82É\8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\82Æ\8cÄ\82Î\82ê\82é\8fê\8f\8a\82É\83t\83@\83C\83\8b\82ð\93W\8aJ\82µ\82Ü\82·\81B</p>\r
+            <p>\83f\83v\83\8d\83C\83\84\81[\82Í\82±\82Ì\8b@\94\\82ð\92ñ\8b\9f\82µ\82Ü\82·\81B\94z\92u\83f\83B\83\8c\83N\83g\83\8a\82ð\92è\8aú\93I\82É\8aÄ\8e\8b\82µ\81A\83t\83@\83C\83\8b\82ª\94z\92u\82³\82ê\82é\82Æ\8e©\93®\93I\82É\8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\82É\93W\8aJ\82µ\81A\83T\81[\83o\82É\83C\83x\83\93\83g\82ð\92Ê\92m\82µ\82Ü\82·\81B</p>\r
+            <p>\94z\92u\83f\83B\83\8c\83N\83g\83\8a\81A\8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\82Í\8e©\97R\82É\92è\8b`\82·\82é\82±\82Æ\82ª\8fo\97\88\82Ü\82·\81B\97á\82¦\82Î\81A</p>\r
+            <source>/\r
++---bin/\r
+|   +---deployer.jar\82È\82Ç\83T\81[\83o\96{\91Ì\81B\r
++---deploy/\r
+|   +---\94z\92u\83f\83B\83\8c\83N\83g\83\8a\81B\r
++---work/\r
+    +---\8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\81B</source>\r
+            <p>\82Æ\82¢\82¤\8d\\90¬\82Å\82 \82Á\82½\82è\81A</p>\r
+            <source>/\r
++---bin/\r
+|   +---deployer.jar\82È\82Ç\82Ì\83T\81[\83o\96{\91Ì\81B\r
++---profiles/\r
+    +---user1\r
+    |   +---deploy/\r
+    |   |   +---\94z\92u\83f\83B\83\8c\83N\83g\83\8a\81B\r
+    |   +---work/\r
+    |       +---\8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\81B\r
+    +---user2\r
+    |   +---deploy/\r
+    |   |   +---\94z\92u\83f\83B\83\8c\83N\83g\83\8a\81B\r
+    |   +---work/\r
+    |       +---\8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\81B\r
+    +---user3\r
+        +---deploy/\r
+        |   +---\94z\92u\83f\83B\83\8c\83N\83g\83\8a\81B\r
+        +---work/\r
+            +---\8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\81B</source>\r
+            <p>\82Æ\82¢\82¤\8d\\90¬\82ð\92è\8b`\82·\82é\82±\82Æ\82ª\8fo\97\88\82Ü\82·\81B\82±\82ê\82Í\81ADeployer\83N\83\89\83X\82Ì\83R\83\93\83X\83g\83\89\83N\83^\82É\8ew\92è\82·\82é\88ø\90\94\82Å\92è\8b`\82µ\82Ü\82·\81B</p>\r
+        </section>\r
+    </body>\r
+</document>\r
diff --git a/deployer/tags/1.0.0/src/site/xdoc/index.xml b/deployer/tags/1.0.0/src/site/xdoc/index.xml
new file mode 100644 (file)
index 0000000..caf879d
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="Shift_JIS"?>\r
+<document>\r
+    <properties>\r
+        <author email="uguu at users.sourceforge.jp">uguu</author>\r
+        <title>\83f\83v\83\8d\83C\83\84\81[ - \8aT\97v</title>\r
+    </properties>\r
+    <body>\r
+        <section name="\8aT\97v">\r
+            <p>war\83t\83@\83C\83\8b\82Ì\82æ\82¤\82É\81A\83N\83\89\83\83t\83@\83C\83\8b\81Ajar\83t\83@\83C\83\8b\81A\83\8a\83\\81[\83X\82ð\8ai\94[\82µ\82½\83A\81[\83J\83C\83u\82Ì\83z\83b\83g\83f\83v\83\8d\83C\82ð\8ds\82¢\81A\83N\83\89\83X\83\8d\81[\83_\81[\82ð\8d\\92z\82·\82é\8b@\94\\82ð\8e\9d\82¿\82Ü\82·\81B</p>\r
+        </section>\r
+    </body>\r
+</document>\r
diff --git a/deployer/tags/1.0.0/uguu.checkstyle.xml b/deployer/tags/1.0.0/uguu.checkstyle.xml
new file mode 100644 (file)
index 0000000..2bcb1d9
--- /dev/null
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--
+       This configuration file was written by the eclipse-cs plugin configuration editor
+-->\r
+<!--
+Checkstyle-Configuration: Uguu Checks
+Description:
+
+-->\r
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">\r
+<module name="Checker">\r
+    <property name="severity" value="warning"/>\r
+    <module name="TreeWalker">\r
+        <property name="tabWidth" value="4"/>\r
+        <module name="ModifierOrder"/>\r
+        <module name="RedundantModifier"/>\r
+        <module name="AvoidNestedBlocks"/>\r
+        <module name="EmptyBlock"/>\r
+        <module name="LeftCurly"/>\r
+        <module name="NeedBraces"/>\r
+        <module name="RightCurly"/>\r
+        <module name="AvoidInlineConditionals"/>\r
+        <module name="DoubleCheckedLocking"/>\r
+        <module name="EmptyStatement"/>\r
+        <module name="EqualsHashCode"/>\r
+        <module name="IllegalInstantiation"/>\r
+        <module name="InnerAssignment"/>\r
+        <module name="MissingSwitchDefault"/>\r
+        <module name="RedundantThrows"/>\r
+        <module name="SimplifyBooleanExpression"/>\r
+        <module name="SimplifyBooleanReturn"/>\r
+        <module name="DesignForExtension"/>\r
+        <module name="HideUtilityClassConstructor"/>\r
+        <module name="InterfaceIsType"/>\r
+        <module name="VisibilityModifier"/>\r
+        <module name="ArrayTypeStyle"/>\r
+        <module name="GenericIllegalRegexp">\r
+            <property name="format" value="\s+$"/>\r
+            <property name="ignoreComments" value="true"/>\r
+            <property name="message" value="Line has trailing spaces."/>\r
+        </module>\r
+        <module name="TodoComment"/>\r
+        <module name="UpperEll"/>\r
+        <module name="DefaultComesLast"/>\r
+        <module name="FallThrough"/>\r
+        <module name="IllegalCatch"/>\r
+        <module name="IllegalThrows"/>\r
+        <module name="ModifiedControlVariable"/>\r
+        <module name="RequireThis"/>\r
+        <module name="StringLiteralEquality"/>\r
+        <module name="FinalClass"/>\r
+        <module name="Indentation"/>\r
+        <module name="TrailingComment"/>\r
+        <module name="JavadocStyle">\r
+            <property name="checkFirstSentence" value="false"/>\r
+        </module>\r
+        <module name="JavadocType">\r
+            <property name="authorFormat" value="^\$Author.*\$$"/>\r
+            <property name="versionFormat" value="^\$Rev.*\$$"/>\r
+        </module>\r
+        <module name="JavadocVariable"/>\r
+        <module name="AbstractClassName"/>\r
+        <module name="ConstantName"/>\r
+        <module name="LocalFinalVariableName"/>\r
+        <module name="LocalVariableName"/>\r
+        <module name="MemberName">\r
+            <property name="format" value="^[a-z_][a-zA-Z0-9]*$"/>\r
+        </module>\r
+        <module name="MethodName"/>\r
+        <module name="PackageName"/>\r
+        <module name="ParameterName"/>\r
+        <module name="StaticVariableName"/>\r
+        <module name="TypeName"/>\r
+        <module name="Header">\r
+            <property name="headerFile" value="${basedir}/LICENSE.txt"/>\r
+        </module>\r
+        <module name="AvoidStarImport"/>\r
+        <module name="IllegalImport"/>\r
+        <module name="ImportOrder"/>\r
+        <module name="RedundantImport"/>\r
+        <module name="UnusedImports"/>\r
+        <module name="EmptyForInitializerPad"/>\r
+        <module name="EmptyForIteratorPad"/>\r
+        <module name="NoWhitespaceAfter"/>\r
+        <module name="NoWhitespaceBefore"/>\r
+        <module name="OperatorWrap"/>\r
+        <module name="MethodParamPad"/>\r
+        <module name="ParenPad"/>\r
+        <module name="TabCharacter"/>\r
+        <module name="TypecastParenPad">\r
+            <property name="tokens" value="RPAREN,TYPECAST"/>\r
+        </module>\r
+        <module name="WhitespaceAfter"/>\r
+        <module name="WhitespaceAround">\r
+            <property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAND,LCURLY,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>\r
+        </module>\r
+        <module name="CovariantEquals"/>\r
+        <module name="DeclarationOrder"/>\r
+        <module name="ExplicitInitialization"/>\r
+        <module name="HiddenField"/>\r
+        <module name="IllegalType">\r
+            <property name="tokens" value="METHOD_DEF,PARAMETER_DEF,VARIABLE_DEF"/>\r
+        </module>\r
+        <module name="JUnitTestCase"/>\r
+        <module name="MagicNumber"/>\r
+        <module name="MissingCtor"/>\r
+        <module name="MultipleStringLiterals"/>\r
+        <module name="MultipleVariableDeclarations"/>\r
+        <module name="PackageDeclaration"/>\r
+        <module name="MutableException"/>\r
+    </module>\r
+    <module name="NewlineAtEndOfFile">\r
+        <property name="lineSeparator" value="lf"/>\r
+    </module>\r
+    <module name="Translation"/>\r
+    <module name="PackageHtml"/>\r
+</module>\r