OSDN Git Service

ブランチの整理
authoryuki <yuki@bdf3b611-c98c-6041-8292-703d9c9adbe7>
Mon, 25 May 2009 16:34:09 +0000 (16:34 +0000)
committeryuki <yuki@bdf3b611-c98c-6041-8292-703d9c9adbe7>
Mon, 25 May 2009 16:34:09 +0000 (16:34 +0000)
git-svn-id: http://192.168.11.7/svn/repository/NicoBrowser/trunk@137 bdf3b611-c98c-6041-8292-703d9c9adbe7

32 files changed:
README_sjis.txt [new file with mode: 0644]
README_utf8.txt [new file with mode: 0644]
build.xml [new file with mode: 0644]
createDDL.jdbc [new file with mode: 0644]
default/nicobrowser.properties [new file with mode: 0644]
dropDDL.jdbc [new file with mode: 0644]
manifest.mf [new file with mode: 0644]
master.jnlp [new file with mode: 0644]
nbproject/build-impl.xml [new file with mode: 0644]
nbproject/configs/JWS_generated.properties [new file with mode: 0644]
nbproject/genfiles.properties [new file with mode: 0644]
nbproject/groovy-build.xml [new file with mode: 0644]
nbproject/jnlp-impl.xml [new file with mode: 0644]
nbproject/project.properties [new file with mode: 0644]
nbproject/project.xml [new file with mode: 0644]
src/META-INF/persistence.xml [new file with mode: 0644]
src/commons-logging.properties [new file with mode: 0644]
src/log4j.properties [new file with mode: 0644]
src/nicobrowser/Config.java [new file with mode: 0644]
src/nicobrowser/NicoHttpClient.java [new file with mode: 0644]
src/nicobrowser/entity/NicoContent.java [new file with mode: 0644]
src/nicobrowser/main/Main.java [new file with mode: 0644]
src/nicobrowser/util/Result.java [new file with mode: 0644]
src/nicobrowser/util/ResultParse.groovy [new file with mode: 0644]
src/nicobrowser/util/Util.java [new file with mode: 0644]
src/resources/feedurl.txt [new file with mode: 0644]
test/nicobrowser/ConfigTest.java [new file with mode: 0644]
test/nicobrowser/NicoHttpClientRssTest.java [new file with mode: 0644]
test/nicobrowser/NicoHttpClientTest.java [new file with mode: 0644]
test/nicobrowser/util/UtilTest.java [new file with mode: 0644]
test/testdata/feedurl.txt [new file with mode: 0644]
test/testdata/nicobrowser.properties [new file with mode: 0644]

diff --git a/README_sjis.txt b/README_sjis.txt
new file mode 100644 (file)
index 0000000..710ce13
--- /dev/null
@@ -0,0 +1,93 @@
+\81\9c\89^\97p\95û\96@\82Ì\88ê\97á\r
+http://feather.cocolog-nifty.com/weblog/2008/03/post_7d4b.html\r
+\r
+\81\9c\91\80\8dì\95û\96@\81F\r
+\83R\83}\83\93\83h\83\89\83C\83\93\82Å\88È\89º\82ð\8eÀ\8ds\81B\r
+java -jar NicoBrowser.jar\r
+\r
+1\89ñ\96Ú\82Ì\8bN\93®\82Å\83R\83\93\83t\83B\83O\83t\83@\83C\83\8b\82ª\83A\83v\83\8a\83P\81[\83V\83\87\83\93\83f\83B\83\8c\83N\83g\83\8a\82É\8dì\90¬\82³\82ê\82é\81B\r
+Windows\82Å\82 \82ê\82Î\81A\97á\82¦\82Î\88È\89º\82Ì\83f\83B\83\8c\83N\83g\83\8a\81B\r
+C:\Documents and Settings\user\.nicobrowser\r
+\r
+nicobrowser.properties\82ð\8aJ\82«\81AID\82Æ\83p\83X\83\8f\81[\83h\82ð\90Ý\92è\82·\82é\81B\r
+\r
+\90Ý\92è\8cã\81A\8dÄ\93x\8eÀ\8ds\82·\82ê\82Î\83_\83E\83\93\83\8d\81[\83h\8aJ\8en\81B\r
+\r
+\r
+\81\9c20090323\94Å\88È\91O\82ð\8eg\97p\82µ\82Ä\82¢\82½\8fê\8d\87\82Ì\92\8d\88Ó\8e\96\8d\80\81F\r
+nicobrowser.properties\82Ì\8cÝ\8a·\90«\82Í\96³\82¢\82½\82ß\81A\88ê\92U\83\8a\83l\81[\83\80(or \8dí\8f\9c)\82µ\82Ä\82©\82ç\r
+\8eÀ\8ds\82·\82é\95K\97v\82ª\82 \82é\81B\82±\82¤\82·\82é\82±\82Æ\82Å\81A\90V\82µ\82¢nicobrowser.properties\82ª\8dì\90¬\82³\82ê\82é\81B\r
+\r
+path.db\82Ì\90Ý\92è\82Í\81A\8f]\97\88\82Í"\83t\83@\83C\83\8b\96¼"\82Ì\8ew\92è\82¾\82Á\82½\82ª\81A\r
+\8c»\8dÝ\82Í"\83f\83B\83\8c\83N\83g\83\8a\96¼"\82Ì\8ew\92è\82É\95Ï\82í\82Á\82Ä\82¢\82é\82±\82Æ\82É\92\8d\88Ó\81B\r
+\r
+\96{\91Ìlib\83f\83B\83\8c\83N\83g\83\8a\88È\89º\82É\82Â\82¢\82Ä\81A\8d\\90¬\82ª\91å\82«\82­\95Ï\82í\82Á\82Ä\82¢\82é\82½\82ß\81Alib\82Í\8fã\8f\91\82«\82Å\82È\82­\r
+\92u\8a·\82·\82é\82±\82Æ\82ð\90\84\8f§\81B\r
+\r
+\r
+\81\9cnicobrowser.properties\82Ì\90à\96¾\81F\r
+\r
+path.db=\r
+\97\9a\97ð\8aÇ\97\9dDB\82ð\95Û\91\82·\82é\83f\83B\83\8c\83N\83g\83\8a\81B\93ú\96{\8cê\96¼\95s\89Â\81B\r
+\r
+path.savefile=\r
+\83_\83E\83\93\83\8d\81[\83h\82µ\82½flv\83t\83@\83C\83\8b\82ð\95Û\91\82·\82é\83f\83B\83\8c\83N\83g\83\8a\81B\93ú\96{\8cê\96¼\95s\89Â\81B\r
+\r
+encoding=\r
+feedurl.txt\82Ì\95\8e\9a\83G\83\93\83R\81[\83f\83B\83\93\83O\81B\r
+\r
+nicovideo.mail=\r
+\83j\83R\83j\83R\93®\89æ\82Ì\83\81\81[\83\8b\83A\83h\83\8c\83X(ID)\81B\r
+\r
+nicovideo.password=\r
+\83j\83R\83j\83R\93®\89æ\82Ì\83p\83X\83\8f\81[\83h\81B\r
+\r
+download.mylist=\r
+\8ew\92è\82µ\82½\8cö\8aJ\83}\83C\83\8a\83X\83g\82É\93o\98^\82³\82ê\82Ä\82¢\82é\83R\83\93\83e\83\93\83c\82ð\83_\83E\83\93\83\8d\81[\83h\91Î\8fÛ\82É\8aÜ\82ß\82é\81B\r
+\97á\82¦\82Î\r
+http://www.nicovideo.jp/mylist/4573744\r
+http://www.nicovideo.jp/mylist/739988/1395449\r
+\8fã\8bL2\8cÂ\82Ì\83}\83C\83\8a\83X\83g\82ð\91Î\8fÛ\82Æ\82·\82é\8fê\8d\87\81A\r
+download.mylist=4573744,739988/1395449\r
+\82Æ\81AURL\82Ì mylist/ \88È\89º\82ð\83J\83\93\83}\82Å\8bæ\90Ø\82Á\82Ä\8ew\92è\82·\82é\81B\r
+\r
+\r
+\81\9cfeedurl.txt\82Ì\90à\96¾:\r
+1\8ds\82²\82Æ\82É\81A\91Î\8fÛ\82Æ\82·\82éRSS\83t\83B\81[\83h\82ÌURL\82Æ\92\8a\8fo\90\94\82ð\83J\83\93\83}\8bæ\90Ø\82è\82Å\90Ý\92è\82·\82é\81B\r
+\8f\91\8e®\82É\82Â\82¢\82Ä\82Í\83t\83@\83C\83\8b\93à\82Ì\83R\83\81\83\93\83g\8eQ\8fÆ\81B\r
+\r
+\r
+\81\9c\96¢\89ð\8c\88\82Ì\89Û\91è\81F\r
+web\83T\83C\83g\8eQ\8fÆ\81B\r
+\r
+\r
+\81\9c\8dX\90V\97\9a\97ð\r
+2009/05/24\r
+\83f\83C\83\8a\81[\83\89\83\93\83L\83\93\83O\88È\8aO\82Ì\83t\83B\81[\83h\82Ö\91Î\89\9e\81B\r
+\88ê\95\94\82Ìswf\82É\91Î\82µ\82Ä\83A\83N\83Z\83X\82Å\82«\82È\82¢\96â\91è\82Ì\91Î\89\9e(\90V\83v\83\8c\83C\83\84\91Î\89\9e)\81B\r
+\83\8d\83O\8fo\97Í\82Ì\8c©\92¼\82µ\81B\r
+\r
+2009/03/23\r
+\93®\89æ\83t\83@\83C\83\8b\8eæ\93¾\8e\9e403\82ð\82à\82ç\82Á\82½\8fê\8d\87\81A\83t\83@\83C\83\8b\82ð\83_\83E\83\93\83\8d\81[\83h\82µ\82È\82¢\82æ\82¤\82É\91Î\89\9e\81B\r
+\r
+2009/01/11\r
+\8e\8b\92®\8c \8cÀ\82ª\96³\82¢\93®\89æ\82ð\8eæ\93¾\82µ\82æ\82¤\82Æ\82µ\82½\8fê\8d\87\82É\83A\83v\83\8a\83P\81[\83V\83\87\83\93\82ª\8fI\97¹\82µ\82Ä\82µ\82Ü\82¤\96â\91è\82ð\8fC\90³\81B\r
+\r
+2008/08/03\r
+\83\89\83\93\83L\83\93\83O\82ÌRSS\82ðzio\82³\82ñ\8dì\83j\83RRSS\r
+http://zio3.net/nicoRss/Handler.ashx\r
+\82©\82ç\96{\89Æ\r
+http://www.nicovideo.jp/ranking/mylist/daily/all?rss=atom\r
+\82É\95Ï\8dX\82µ\82½\81B\r
+\r
+2008/04/09\r
+\91O\89ñ\83_\83E\83\93\83\8d\81[\83h\97v\8b\81\82©\82ç5\95b\91Ò\82Á\82Ä\82©\82ç\8e\9f\82Ì\83_\83E\83\93\83\8d\81[\83h\97v\8b\81\82ð\8ds\82¤\82æ\82¤\83E\83F\83C\83g\8f\88\97\9d\82ð\92Ç\89Á\82µ\82½\81B\r
+\83^\81[\83Q\83b\83g\82ðJDK6\82©\82çJDK5\82É\95Ï\8dX\82µ\82½\81B\r
+\r
+2008/03/21\r
+\8cö\8aJ\83}\83C\83\8a\83X\83g\82ð\8ew\92è\82µ\82½\83_\83E\83\93\83\8d\81[\83h\82ð\89Â\94\\82Æ\82µ\82½\81B\r
+\r
+2008/03/15\r
+\83_\83E\83\93\83\8d\81[\83h\82·\82é\8dÅ\92á\83\89\83\93\83L\83\93\83O\82ð\8ew\92è\89Â\94\\82Æ\82µ\82½\81B\r
+\83t\83@\83C\83\8b\96¼\82É\83h\83b\83g\82ª\93ü\82Á\82Ä\82¢\82½\8fê\8d\87\82É\82à\83A\83\93\83_\81[\83o\81[\82É\r
+\92u\8a·\82·\82é\82æ\82¤\92u\8a·\8bK\91¥\82ð\92Ç\89Á(Craving Explorer\82É\8d\87\82í\82¹\82½)\81B\r
diff --git a/README_utf8.txt b/README_utf8.txt
new file mode 100644 (file)
index 0000000..68314d5
--- /dev/null
@@ -0,0 +1,93 @@
+●運用方法の一例
+http://feather.cocolog-nifty.com/weblog/2008/03/post_7d4b.html
+
+●操作方法:
+コマンドラインで以下を実行。
+java -jar NicoBrowser.jar
+
+1回目の起動でコンフィグファイルがアプリケーションディレクトリに作成される。
+Windowsであれば、例えば以下のディレクトリ。
+C:\Documents and Settings\user\.nicobrowser
+
+nicobrowser.propertiesを開き、IDとパスワードを設定する。
+
+設定後、再度実行すればダウンロード開始。
+
+
+●20090323版以前を使用していた場合の注意事項:
+nicobrowser.propertiesの互換性は無いため、一旦リネーム(or 削除)してから
+実行する必要がある。こうすることで、新しいnicobrowser.propertiesが作成される。
+
+path.dbの設定は、従来は"ファイル名"の指定だったが、
+現在は"ディレクトリ名"の指定に変わっていることに注意。
+
+本体libディレクトリ以下について、構成が大きく変わっているため、libは上書きでなく
+置換することを推奨。
+
+
+●nicobrowser.propertiesの説明:
+
+path.db=
+履歴管理DBを保存するディレクトリ。日本語名不可。
+
+path.savefile=
+ダウンロードしたflvファイルを保存するディレクトリ。日本語名不可。
+
+encoding=
+feedurl.txtの文字エンコーディング。
+
+nicovideo.mail=
+ニコニコ動画のメールアドレス(ID)。
+
+nicovideo.password=
+ニコニコ動画のパスワード。
+
+download.mylist=
+指定した公開マイリストに登録されているコンテンツをダウンロード対象に含める。
+例えば
+http://www.nicovideo.jp/mylist/4573744
+http://www.nicovideo.jp/mylist/739988/1395449
+上記2個のマイリストを対象とする場合、
+download.mylist=4573744,739988/1395449
+と、URLの mylist/ 以下をカンマで区切って指定する。
+
+
+●feedurl.txtの説明:
+1行ごとに、対象とするRSSフィードのURLと抽出数をカンマ区切りで設定する。
+書式についてはファイル内のコメント参照。
+
+
+●未解決の課題:
+webサイト参照。
+
+
+●更新履歴
+2009/05/24
+デイリーランキング以外のフィードへ対応。
+一部のswfに対してアクセスできない問題の対応(新プレイヤ対応)。
+ログ出力の見直し。
+
+2009/03/23
+動画ファイル取得時403をもらった場合、ファイルをダウンロードしないように対応。
+
+2009/01/11
+視聴権限が無い動画を取得しようとした場合にアプリケーションが終了してしまう問題を修正。
+
+2008/08/03
+ランキングのRSSをzioさん作ニコRSS
+http://zio3.net/nicoRss/Handler.ashx
+から本家
+http://www.nicovideo.jp/ranking/mylist/daily/all?rss=atom
+に変更した。
+
+2008/04/09
+前回ダウンロード要求から5秒待ってから次のダウンロード要求を行うようウェイト処理を追加した。
+ターゲットをJDK6からJDK5に変更した。
+
+2008/03/21
+公開マイリストを指定したダウンロードを可能とした。
+
+2008/03/15
+ダウンロードする最低ランキングを指定可能とした。
+ファイル名にドットが入っていた場合にもアンダーバーに
+置換するよう置換規則を追加(Craving Explorerに合わせた)。
diff --git a/build.xml b/build.xml
new file mode 100644 (file)
index 0000000..d4e3b6e
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!-- You may freely edit this file. See commented blocks below for -->\r
+<!-- some examples of how to customize the build. -->\r
+<!-- (If you delete it and reopen the project it will be recreated.) -->\r
+<!-- By default, only the Clean and Build commands use this build script. -->\r
+<!-- Commands such as Run, Debug, and Test only use this build script if -->\r
+<!-- the Compile on Save feature is turned off for the project. -->\r
+<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->\r
+<!-- in the project's Project Properties dialog box.-->\r
+<project name="NicoBrowser" default="default" basedir=".">\r
+    <description>Builds, tests, and runs the project NicoBrowser.</description>\r
+    <import file="nbproject/build-impl.xml"/>\r
+    <!--\r
+\r
+    There exist several targets which are by default empty and which can be \r
+    used for execution of your tasks. These targets are usually executed \r
+    before and after some main targets. They are: \r
+\r
+      -pre-init:                 called before initialization of project properties\r
+      -post-init:                called after initialization of project properties\r
+      -pre-compile:              called before javac compilation\r
+      -post-compile:             called after javac compilation\r
+      -pre-compile-single:       called before javac compilation of single file\r
+      -post-compile-single:      called after javac compilation of single file\r
+      -pre-compile-test:         called before javac compilation of JUnit tests\r
+      -post-compile-test:        called after javac compilation of JUnit tests\r
+      -pre-compile-test-single:  called before javac compilation of single JUnit test\r
+      -post-compile-test-single: called after javac compilation of single JUunit test\r
+      -pre-jar:                  called before JAR building\r
+      -post-jar:                 called after JAR building\r
+      -post-clean:               called after cleaning build products\r
+\r
+    (Targets beginning with '-' are not intended to be called on their own.)\r
+\r
+    Example of inserting an obfuscator after compilation could look like this:\r
+\r
+        <target name="-post-compile">\r
+            <obfuscate>\r
+                <fileset dir="${build.classes.dir}"/>\r
+            </obfuscate>\r
+        </target>\r
+\r
+    For list of available properties check the imported \r
+    nbproject/build-impl.xml file. \r
+\r
+\r
+    Another way to customize the build is by overriding existing main targets.\r
+    The targets of interest are: \r
+\r
+      -init-macrodef-javac:     defines macro for javac compilation\r
+      -init-macrodef-junit:     defines macro for junit execution\r
+      -init-macrodef-debug:     defines macro for class debugging\r
+      -init-macrodef-java:      defines macro for class execution\r
+      -do-jar-with-manifest:    JAR building (if you are using a manifest)\r
+      -do-jar-without-manifest: JAR building (if you are not using a manifest)\r
+      run:                      execution of project \r
+      -javadoc-build:           Javadoc generation\r
+      test-report:              JUnit report generation\r
+\r
+    An example of overriding the target for project execution could look like this:\r
+\r
+        <target name="run" depends="NicoBrowser-impl.jar">\r
+            <exec dir="bin" executable="launcher.exe">\r
+                <arg file="${dist.jar}"/>\r
+            </exec>\r
+        </target>\r
+\r
+    Notice that the overridden target depends on the jar target and not only on \r
+    the compile target as the regular run target does. Again, for a list of available \r
+    properties which you can use, check the target you are overriding in the\r
+    nbproject/build-impl.xml file. \r
+\r
+    -->\r
+</project>\r
diff --git a/createDDL.jdbc b/createDDL.jdbc
new file mode 100644 (file)
index 0000000..50ff4cc
--- /dev/null
@@ -0,0 +1,3 @@
+CREATE TABLE NICOCONTENT (ID NUMBER(19) NOT NULL, CONVERTEDMP4 NUMBER(1) NOT NULL, PAGELINK VARCHAR(255), FILENAME VARCHAR(255), CONVERTEDMP3 NUMBER(1) NOT NULL, TITLE VARCHAR(255), FAILTIMES NUMBER(10), VERSION NUMBER(19), NICOID VARCHAR(255) NOT NULL, STATUS NUMBER(10) NOT NULL, PRIMARY KEY (ID))
+CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT NUMBER(19), PRIMARY KEY (SEQ_NAME))
+INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 1)
diff --git a/default/nicobrowser.properties b/default/nicobrowser.properties
new file mode 100644 (file)
index 0000000..792d50c
--- /dev/null
@@ -0,0 +1,10 @@
+nicovideo.mail=niconico.senyou@live.jp\r
+nicovideo.password=piyopiyo\r
+path.ffmpeg=C:\\Program Files\\Red Kawa\\Video Converter 3\\Tools\\FFmpeg\\ffmpeg.exe\r
+path.db=I:\\niconico\\flv\\browser\\db\\nicodb\r
+dir.save.src=I:\\niconico\\flv\\browser\r
+dir.save.mp4=\r
+dir.save.mp3=\r
+download.ext.mp4=true\r
+download.retry=3\r
+ffpmeg.option="-y -i %i -f %f -vcodec libx264 -level 30 -b 512k -bt 512k -bufsize 10000k -maxrate 10000k -g 300 -coder 0 -threads auto -acodec libfaac -ac 2 -ab 128k %o"\r
diff --git a/dropDDL.jdbc b/dropDDL.jdbc
new file mode 100644 (file)
index 0000000..62fa666
--- /dev/null
@@ -0,0 +1,2 @@
+DROP TABLE NICOCONTENT
+DELETE FROM SEQUENCE WHERE SEQ_NAME = 'SEQ_GEN'
diff --git a/manifest.mf b/manifest.mf
new file mode 100644 (file)
index 0000000..1574df4
--- /dev/null
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0\r
+X-COMMENT: Main-Class will be added automatically by build\r
+\r
diff --git a/master.jnlp b/master.jnlp
new file mode 100644 (file)
index 0000000..4bd96d2
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jnlp spec="1.0+" codebase="${jnlp.codebase}" href="launch.jnlp">
+    <information>
+        <title>${APPLICATION.TITLE}</title>
+        <vendor>${APPLICATION.VENDOR}</vendor>
+        <description>${APPLICATION.DESC}</description>
+        <description kind="short">${APPLICATION.DESC.SHORT}</description>
+        <homepage href="${APPLICATION.HOMEPAGE}"/>
+<!--${JNLP.ICONS}-->
+<!--${JNLP.OFFLINE.ALLOWED}-->
+    </information>
+<!--${JNLP.SECURITY}-->
+    <resources>
+<!--${JNLP.RESOURCES.RUNTIME}-->
+<!--${JNLP.RESOURCES.MAIN.JAR}-->
+<!--${JNLP.RESOURCES.JARS}-->
+    </resources>
+    <application-desc main-class="${jnlp.main.class}">
+<!--${JNLP.APPLICATION.ARGS}-->
+    </application-desc>
+</jnlp>
diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml
new file mode 100644 (file)
index 0000000..9b241b6
--- /dev/null
@@ -0,0 +1,702 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+*** GENERATED FROM project.xml - DO NOT EDIT  ***\r
+***         EDIT ../build.xml INSTEAD         ***\r
+\r
+For the purpose of easier reading the script\r
+is divided into following sections:\r
+\r
+  - initialization\r
+  - compilation\r
+  - jar\r
+  - execution\r
+  - debugging\r
+  - javadoc\r
+  - junit compilation\r
+  - junit execution\r
+  - junit debugging\r
+  - applet\r
+  - cleanup\r
+\r
+        -->\r
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="NicoBrowser-impl">\r
+    <import file="groovy-build.xml"/>\r
+    <import file="jnlp-impl.xml"/>\r
+    <fail message="Please build using Ant 1.7.1 or higher.">\r
+        <condition>\r
+            <not>\r
+                <antversion atleast="1.7.1"/>\r
+            </not>\r
+        </condition>\r
+    </fail>\r
+    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>\r
+    <!-- \r
+                ======================\r
+                INITIALIZATION SECTION \r
+                ======================\r
+            -->\r
+    <target name="-pre-init">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="-pre-init" name="-init-private">\r
+        <property file="nbproject/private/config.properties"/>\r
+        <property file="nbproject/private/configs/${config}.properties"/>\r
+        <property file="nbproject/private/private.properties"/>\r
+    </target>\r
+    <target depends="-pre-init,-init-private" name="-init-user">\r
+        <property file="${user.properties.file}"/>\r
+        <!-- The two properties below are usually overridden -->\r
+        <!-- by the active platform. Just a fallback. -->\r
+        <property name="default.javac.source" value="1.4"/>\r
+        <property name="default.javac.target" value="1.4"/>\r
+    </target>\r
+    <target depends="-pre-init,-init-private,-init-user" name="-init-project">\r
+        <property file="nbproject/configs/${config}.properties"/>\r
+        <property file="nbproject/project.properties"/>\r
+    </target>\r
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">\r
+        <available file="${manifest.file}" property="manifest.available"/>\r
+        <condition property="manifest.available+main.class">\r
+            <and>\r
+                <isset property="manifest.available"/>\r
+                <isset property="main.class"/>\r
+                <not>\r
+                    <equals arg1="${main.class}" arg2="" trim="true"/>\r
+                </not>\r
+            </and>\r
+        </condition>\r
+        <condition property="manifest.available+main.class+mkdist.available">\r
+            <and>\r
+                <istrue value="${manifest.available+main.class}"/>\r
+                <isset property="libs.CopyLibs.classpath"/>\r
+            </and>\r
+        </condition>\r
+        <condition property="have.tests">\r
+            <or>\r
+                <available file="${test.src.dir}"/>\r
+            </or>\r
+        </condition>\r
+        <condition property="have.sources">\r
+            <or>\r
+                <available file="${src.dir}"/>\r
+            </or>\r
+        </condition>\r
+        <condition property="netbeans.home+have.tests">\r
+            <and>\r
+                <isset property="netbeans.home"/>\r
+                <isset property="have.tests"/>\r
+            </and>\r
+        </condition>\r
+        <condition property="no.javadoc.preview">\r
+            <and>\r
+                <isset property="javadoc.preview"/>\r
+                <isfalse value="${javadoc.preview}"/>\r
+            </and>\r
+        </condition>\r
+        <property name="run.jvmargs" value=""/>\r
+        <property name="javac.compilerargs" value=""/>\r
+        <property name="work.dir" value="${basedir}"/>\r
+        <condition property="no.deps">\r
+            <and>\r
+                <istrue value="${no.dependencies}"/>\r
+            </and>\r
+        </condition>\r
+        <property name="javac.debug" value="true"/>\r
+        <property name="javadoc.preview" value="true"/>\r
+        <property name="application.args" value=""/>\r
+        <property name="source.encoding" value="${file.encoding}"/>\r
+        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">\r
+            <and>\r
+                <isset property="javadoc.encoding"/>\r
+                <not>\r
+                    <equals arg1="${javadoc.encoding}" arg2=""/>\r
+                </not>\r
+            </and>\r
+        </condition>\r
+        <property name="javadoc.encoding.used" value="${source.encoding}"/>\r
+        <property name="includes" value="**"/>\r
+        <property name="excludes" value=""/>\r
+        <property name="do.depend" value="false"/>\r
+        <condition property="do.depend.true">\r
+            <istrue value="${do.depend}"/>\r
+        </condition>\r
+        <condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">\r
+            <and>\r
+                <isset property="jaxws.endorsed.dir"/>\r
+                <available file="nbproject/jaxws-build.xml"/>\r
+            </and>\r
+        </condition>\r
+    </target>\r
+    <target name="-post-init">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">\r
+        <fail unless="src.dir">Must set src.dir</fail>\r
+        <fail unless="test.src.dir">Must set test.src.dir</fail>\r
+        <fail unless="build.dir">Must set build.dir</fail>\r
+        <fail unless="dist.dir">Must set dist.dir</fail>\r
+        <fail unless="build.classes.dir">Must set build.classes.dir</fail>\r
+        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>\r
+        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>\r
+        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>\r
+        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>\r
+        <fail unless="dist.jar">Must set dist.jar</fail>\r
+    </target>\r
+    <target name="-init-macrodef-property">\r
+        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">\r
+            <attribute name="name"/>\r
+            <attribute name="value"/>\r
+            <sequential>\r
+                <property name="@{name}" value="${@{value}}"/>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target name="-init-macrodef-javac">\r
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${src.dir}" name="srcdir"/>\r
+            <attribute default="${build.classes.dir}" name="destdir"/>\r
+            <attribute default="${javac.classpath}" name="classpath"/>\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="${javac.debug}" name="debug"/>\r
+            <attribute default="${empty.dir}" name="sourcepath"/>\r
+            <attribute default="${empty.dir}" name="gensrcdir"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <property location="${build.dir}/empty" name="empty.dir"/>\r
+                <mkdir dir="${empty.dir}"/>\r
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">\r
+                    <src>\r
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">\r
+                            <include name="*"/>\r
+                        </dirset>\r
+                    </src>\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                    <compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>\r
+                    <customize/>\r
+                </javac>\r
+            </sequential>\r
+        </macrodef>\r
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${src.dir}" name="srcdir"/>\r
+            <attribute default="${build.classes.dir}" name="destdir"/>\r
+            <attribute default="${javac.classpath}" name="classpath"/>\r
+            <sequential>\r
+                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                </depend>\r
+            </sequential>\r
+        </macrodef>\r
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${build.classes.dir}" name="destdir"/>\r
+            <sequential>\r
+                <fail unless="javac.includes">Must set javac.includes</fail>\r
+                <pathconvert pathsep="," property="javac.includes.binary">\r
+                    <path>\r
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>\r
+                    </path>\r
+                    <globmapper from="*.java" to="*.class"/>\r
+                </pathconvert>\r
+                <delete>\r
+                    <files includes="${javac.includes.binary}"/>\r
+                </delete>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target name="-init-macrodef-junit">\r
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${includes}" name="includes"/>\r
+            <attribute default="${excludes}" name="excludes"/>\r
+            <attribute default="**" name="testincludes"/>\r
+            <sequential>\r
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">\r
+                    <batchtest todir="${build.test.results.dir}">\r
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">\r
+                            <filename name="@{testincludes}"/>\r
+                        </fileset>\r
+                    </batchtest>\r
+                    <classpath>\r
+                        <path path="${run.test.classpath}"/>\r
+                    </classpath>\r
+                    <syspropertyset>\r
+                        <propertyref prefix="test-sys-prop."/>\r
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
+                    </syspropertyset>\r
+                    <formatter type="brief" usefile="false"/>\r
+                    <formatter type="xml"/>\r
+                    <jvmarg line="${run.jvmargs}"/>\r
+                </junit>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">\r
+        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">\r
+            <attribute default="${main.class}" name="name"/>\r
+            <attribute default="${debug.classpath}" name="classpath"/>\r
+            <attribute default="" name="stopclassname"/>\r
+            <sequential>\r
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                </nbjpdastart>\r
+            </sequential>\r
+        </macrodef>\r
+        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">\r
+            <attribute default="${build.classes.dir}" name="dir"/>\r
+            <sequential>\r
+                <nbjpdareload>\r
+                    <fileset dir="@{dir}" includes="${fix.classes}">\r
+                        <include name="${fix.includes}*.class"/>\r
+                    </fileset>\r
+                </nbjpdareload>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target name="-init-debug-args">\r
+        <property name="version-output" value="java version &quot;${ant.java.version}"/>\r
+        <condition property="have-jdk-older-than-1.4">\r
+            <or>\r
+                <contains string="${version-output}" substring="java version &quot;1.0"/>\r
+                <contains string="${version-output}" substring="java version &quot;1.1"/>\r
+                <contains string="${version-output}" substring="java version &quot;1.2"/>\r
+                <contains string="${version-output}" substring="java version &quot;1.3"/>\r
+            </or>\r
+        </condition>\r
+        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">\r
+            <istrue value="${have-jdk-older-than-1.4}"/>\r
+        </condition>\r
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">\r
+            <os family="windows"/>\r
+        </condition>\r
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">\r
+            <isset property="debug.transport"/>\r
+        </condition>\r
+    </target>\r
+    <target depends="-init-debug-args" name="-init-macrodef-debug">\r
+        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute default="${main.class}" name="classname"/>\r
+            <attribute default="${debug.classpath}" name="classpath"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <java classname="@{classname}" dir="${work.dir}" fork="true">\r
+                    <jvmarg line="${debug-args-line}"/>\r
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>\r
+                    <jvmarg value="-Dfile.encoding=${source.encoding}"/>\r
+                    <redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>\r
+                    <jvmarg line="${run.jvmargs}"/>\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                    <syspropertyset>\r
+                        <propertyref prefix="run-sys-prop."/>\r
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>\r
+                    </syspropertyset>\r
+                    <customize/>\r
+                </java>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target name="-init-macrodef-java">\r
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">\r
+            <attribute default="${main.class}" name="classname"/>\r
+            <attribute default="${run.classpath}" name="classpath"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <java classname="@{classname}" dir="${work.dir}" fork="true">\r
+                    <jvmarg value="-Dfile.encoding=${source.encoding}"/>\r
+                    <redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>\r
+                    <jvmarg line="${run.jvmargs}"/>\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                    <syspropertyset>\r
+                        <propertyref prefix="run-sys-prop."/>\r
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>\r
+                    </syspropertyset>\r
+                    <customize/>\r
+                </java>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+    <target name="-init-presetdef-jar">\r
+        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">\r
+            <jar compress="${jar.compress}" jarfile="${dist.jar}">\r
+                <j2seproject1:fileset dir="${build.classes.dir}"/>\r
+            </jar>\r
+        </presetdef>\r
+    </target>\r
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar" name="init"/>\r
+    <!--\r
+                ===================\r
+                COMPILATION SECTION\r
+                ===================\r
+            -->\r
+    <target depends="init" name="deps-jar" unless="no.deps"/>\r
+    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>\r
+    <target depends="init" name="-check-automatic-build">\r
+        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>\r
+    </target>\r
+    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">\r
+        <antcall target="clean"/>\r
+    </target>\r
+    <target depends="init,deps-jar,-groovy-init-macrodef-javac" name="-pre-pre-compile">\r
+        <mkdir dir="${build.classes.dir}"/>\r
+    </target>\r
+    <target name="-pre-compile">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target if="do.depend.true" name="-compile-depend">\r
+        <pathconvert property="build.generated.subdirs">\r
+            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">\r
+                <include name="*"/>\r
+            </dirset>\r
+        </pathconvert>\r
+        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>\r
+    </target>\r
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">\r
+        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>\r
+        <copy todir="${build.classes.dir}">\r
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>\r
+        </copy>\r
+    </target>\r
+    <target name="-post-compile">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>\r
+    <target name="-pre-compile-single">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">\r
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>\r
+        <j2seproject3:force-recompile/>\r
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>\r
+    </target>\r
+    <target name="-post-compile-single">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>\r
+    <!--\r
+                ====================\r
+                JAR BUILDING SECTION\r
+                ====================\r
+            -->\r
+    <target depends="init" name="-pre-pre-jar">\r
+        <dirname file="${dist.jar}" property="dist.jar.dir"/>\r
+        <mkdir dir="${dist.jar.dir}"/>\r
+    </target>\r
+    <target name="-pre-jar">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available">\r
+        <j2seproject1:jar/>\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">\r
+        <j2seproject1:jar manifest="${manifest.file}"/>\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">\r
+        <j2seproject1:jar manifest="${manifest.file}">\r
+            <j2seproject1:manifest>\r
+                <j2seproject1:attribute name="Main-Class" value="${main.class}"/>\r
+            </j2seproject1:manifest>\r
+        </j2seproject1:jar>\r
+        <echo>To run this application from the command line without Ant, try:</echo>\r
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>\r
+        <property location="${dist.jar}" name="dist.jar.resolved"/>\r
+        <pathconvert property="run.classpath.with.dist.jar">\r
+            <path path="${run.classpath}"/>\r
+            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>\r
+        </pathconvert>\r
+        <echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries">\r
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>\r
+        <pathconvert property="run.classpath.without.build.classes.dir">\r
+            <path path="${run.classpath}"/>\r
+            <map from="${build.classes.dir.resolved}" to=""/>\r
+        </pathconvert>\r
+        <pathconvert pathsep=" " property="jar.classpath">\r
+            <path path="${run.classpath.without.build.classes.dir}"/>\r
+            <chainedmapper>\r
+                <flattenmapper/>\r
+                <globmapper from="*" to="lib/*"/>\r
+            </chainedmapper>\r
+        </pathconvert>\r
+        <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>\r
+        <copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">\r
+            <fileset dir="${build.classes.dir}"/>\r
+            <manifest>\r
+                <attribute name="Main-Class" value="${main.class}"/>\r
+                <attribute name="Class-Path" value="${jar.classpath}"/>\r
+            </manifest>\r
+        </copylibs>\r
+        <echo>To run this application from the command line without Ant, try:</echo>\r
+        <property location="${dist.jar}" name="dist.jar.resolved"/>\r
+        <echo>java -jar "${dist.jar.resolved}"</echo>\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="libs.CopyLibs.classpath" name="-do-jar-with-libraries-without-manifest" unless="manifest.available+main.class">\r
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>\r
+        <pathconvert property="run.classpath.without.build.classes.dir">\r
+            <path path="${run.classpath}"/>\r
+            <map from="${build.classes.dir.resolved}" to=""/>\r
+        </pathconvert>\r
+        <pathconvert pathsep=" " property="jar.classpath">\r
+            <path path="${run.classpath.without.build.classes.dir}"/>\r
+            <chainedmapper>\r
+                <flattenmapper/>\r
+                <globmapper from="*" to="lib/*"/>\r
+            </chainedmapper>\r
+        </pathconvert>\r
+        <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>\r
+        <copylibs compress="${jar.compress}" jarfile="${dist.jar}" runtimeclasspath="${run.classpath.without.build.classes.dir}">\r
+            <fileset dir="${build.classes.dir}"/>\r
+        </copylibs>\r
+    </target>\r
+    <target name="-post-jar">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-do-jar-with-libraries-without-manifest,-post-jar,jnlp" description="Build JAR." name="jar"/>\r
+    <!--\r
+                =================\r
+                EXECUTION SECTION\r
+                =================\r
+            -->\r
+    <target depends="init,compile" description="Run a main class." name="run">\r
+        <j2seproject1:java>\r
+            <customize>\r
+                <arg line="${application.args}"/>\r
+            </customize>\r
+        </j2seproject1:java>\r
+    </target>\r
+    <target name="-do-not-recompile">\r
+        <property name="javac.includes.binary" value=""/>\r
+    </target>\r
+    <target depends="init,-do-not-recompile,compile-single" name="run-single">\r
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>\r
+        <j2seproject1:java classname="${run.class}"/>\r
+    </target>\r
+    <target depends="init,-do-not-recompile,compile-test-single" name="run-test-with-main">\r
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>\r
+        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>\r
+    </target>\r
+    <!--\r
+                =================\r
+                DEBUGGING SECTION\r
+                =================\r
+            -->\r
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger">\r
+        <j2seproject1:nbjpdastart name="${debug.class}"/>\r
+    </target>\r
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">\r
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>\r
+    </target>\r
+    <target depends="init,compile" name="-debug-start-debuggee">\r
+        <j2seproject3:debug>\r
+            <customize>\r
+                <arg line="${application.args}"/>\r
+            </customize>\r
+        </j2seproject3:debug>\r
+    </target>\r
+    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>\r
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">\r
+        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>\r
+    </target>\r
+    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>\r
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">\r
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>\r
+        <j2seproject3:debug classname="${debug.class}"/>\r
+    </target>\r
+    <target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>\r
+    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">\r
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>\r
+        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>\r
+    </target>\r
+    <target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>\r
+    <target depends="init" name="-pre-debug-fix">\r
+        <fail unless="fix.includes">Must set fix.includes</fail>\r
+        <property name="javac.includes" value="${fix.includes}.java"/>\r
+    </target>\r
+    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">\r
+        <j2seproject1:nbjpdareload/>\r
+    </target>\r
+    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>\r
+    <!--\r
+                ===============\r
+                JAVADOC SECTION\r
+                ===============\r
+            -->\r
+    <target depends="init" name="-javadoc-build">\r
+        <mkdir dir="${dist.javadoc.dir}"/>\r
+        <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">\r
+            <classpath>\r
+                <path path="${javac.classpath}"/>\r
+            </classpath>\r
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">\r
+                <filename name="**/*.java"/>\r
+            </fileset>\r
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">\r
+                <include name="**/*.java"/>\r
+            </fileset>\r
+        </javadoc>\r
+    </target>\r
+    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">\r
+        <nbbrowse file="${dist.javadoc.dir}/index.html"/>\r
+    </target>\r
+    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>\r
+    <!--\r
+                =========================\r
+                JUNIT COMPILATION SECTION\r
+                =========================\r
+            -->\r
+    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">\r
+        <mkdir dir="${build.test.classes.dir}"/>\r
+    </target>\r
+    <target name="-pre-compile-test">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target if="do.depend.true" name="-compile-test-depend">\r
+        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">\r
+        <j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>\r
+        <copy todir="${build.test.classes.dir}">\r
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>\r
+        </copy>\r
+    </target>\r
+    <target name="-post-compile-test">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>\r
+    <target name="-pre-compile-test-single">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">\r
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>\r
+        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>\r
+        <j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>\r
+        <copy todir="${build.test.classes.dir}">\r
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>\r
+        </copy>\r
+    </target>\r
+    <target name="-post-compile-test-single">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>\r
+    <!--\r
+                =======================\r
+                JUNIT EXECUTION SECTION\r
+                =======================\r
+            -->\r
+    <target depends="init" if="have.tests" name="-pre-test-run">\r
+        <mkdir dir="${build.test.results.dir}"/>\r
+    </target>\r
+    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">\r
+        <j2seproject3:junit testincludes="**/*Test.java"/>\r
+    </target>\r
+    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">\r
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>\r
+    </target>\r
+    <target depends="init" if="have.tests" name="test-report"/>\r
+    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>\r
+    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>\r
+    <target depends="init" if="have.tests" name="-pre-test-run-single">\r
+        <mkdir dir="${build.test.results.dir}"/>\r
+    </target>\r
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">\r
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>\r
+        <j2seproject3:junit excludes="" includes="${test.includes}"/>\r
+    </target>\r
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">\r
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>\r
+    </target>\r
+    <target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>\r
+    <!--\r
+                =======================\r
+                JUNIT DEBUGGING SECTION\r
+                =======================\r
+            -->\r
+    <target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">\r
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>\r
+        <property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>\r
+        <delete file="${test.report.file}"/>\r
+        <mkdir dir="${build.test.results.dir}"/>\r
+        <j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">\r
+            <customize>\r
+                <syspropertyset>\r
+                    <propertyref prefix="test-sys-prop."/>\r
+                    <mapper from="test-sys-prop.*" to="*" type="glob"/>\r
+                </syspropertyset>\r
+                <arg value="${test.class}"/>\r
+                <arg value="showoutput=true"/>\r
+                <arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>\r
+                <arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>\r
+            </customize>\r
+        </j2seproject3:debug>\r
+    </target>\r
+    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">\r
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>\r
+    </target>\r
+    <target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>\r
+    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">\r
+        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>\r
+    </target>\r
+    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>\r
+    <!--\r
+                =========================\r
+                APPLET EXECUTION SECTION\r
+                =========================\r
+            -->\r
+    <target depends="init,compile-single" name="run-applet">\r
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>\r
+        <j2seproject1:java classname="sun.applet.AppletViewer">\r
+            <customize>\r
+                <arg value="${applet.url}"/>\r
+            </customize>\r
+        </j2seproject1:java>\r
+    </target>\r
+    <!--\r
+                =========================\r
+                APPLET DEBUGGING  SECTION\r
+                =========================\r
+            -->\r
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">\r
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>\r
+        <j2seproject3:debug classname="sun.applet.AppletViewer">\r
+            <customize>\r
+                <arg value="${applet.url}"/>\r
+            </customize>\r
+        </j2seproject3:debug>\r
+    </target>\r
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>\r
+    <!--\r
+                ===============\r
+                CLEANUP SECTION\r
+                ===============\r
+            -->\r
+    <target depends="init" name="deps-clean" unless="no.deps"/>\r
+    <target depends="init" name="-do-clean">\r
+        <delete dir="${build.dir}"/>\r
+        <delete dir="${dist.dir}"/>\r
+    </target>\r
+    <target name="-post-clean">\r
+        <!-- Empty placeholder for easier customization. -->\r
+        <!-- You can override this target in the ../build.xml file. -->\r
+    </target>\r
+    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>\r
+</project>\r
diff --git a/nbproject/configs/JWS_generated.properties b/nbproject/configs/JWS_generated.properties
new file mode 100644 (file)
index 0000000..74df2c1
--- /dev/null
@@ -0,0 +1,4 @@
+#Mon Jan 07 02:20:53 JST 2008\r
+$label=Web Start\r
+$target.debug=jws-debug\r
+$target.run=jws-run\r
diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties
new file mode 100644 (file)
index 0000000..bc1ae26
--- /dev/null
@@ -0,0 +1,11 @@
+build.xml.data.CRC32=d1b53a37\r
+build.xml.script.CRC32=02aac843\r
+build.xml.stylesheet.CRC32=958a1d3e@1.26.0.45\r
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.\r
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.\r
+nbproject/build-impl.xml.data.CRC32=d1b53a37\r
+nbproject/build-impl.xml.script.CRC32=64e0e087\r
+nbproject/build-impl.xml.stylesheet.CRC32=5c621a33@1.26.0.45\r
+nbproject/groovy-build.xml.data.CRC32=d1b53a37\r
+nbproject/groovy-build.xml.script.CRC32=6721cc58\r
+nbproject/groovy-build.xml.stylesheet.CRC32=ad2b7201@1.7\r
diff --git a/nbproject/groovy-build.xml b/nbproject/groovy-build.xml
new file mode 100644 (file)
index 0000000..de0aef9
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+*** GENERATED FROM project.xml - DO NOT EDIT  ***\r
+***         EDIT ../build.xml INSTEAD         ***\r
+\r
+        -->\r
+<project xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc">\r
+    <target name="-groovy-init-macrodef-javac">\r
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute name="srcdir" default="${src.dir}"/>\r
+            <attribute name="destdir" default="${build.classes.dir}"/>\r
+            <attribute name="classpath" default="${javac.classpath}"/>\r
+            <attribute name="includes" default="${includes}"/>\r
+            <attribute name="excludes" default="${excludes}"/>\r
+            <attribute name="debug" default="${javac.debug}"/>\r
+            <attribute name="sourcepath" default="${empty.dir}"/>\r
+            <attribute name="gensrcdir" default="${empty.dir}"/>\r
+            <element name="customize" optional="true"/>\r
+            <sequential>\r
+                <taskdef name="groovyc" classpath="${javac.classpath}" classname="org.codehaus.groovy.ant.Groovyc"/>\r
+                <property name="empty.dir" location="${build.dir}/empty"/>\r
+                <mkdir dir="${empty.dir}"/>\r
+                <groovyc srcdir="@{srcdir}" sourcepath="@{sourcepath}" destdir="@{destdir}" encoding="${source.encoding}" includes="@{includes}" excludes="@{excludes}">\r
+                    <src>\r
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">\r
+                            <include name="*"/>\r
+                        </dirset>\r
+                    </src>\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                    <javac srcdir="@{srcdir}" sourcepath="@{sourcepath}" destdir="@{destdir}" debug="@{debug}" deprecation="${javac.deprecation}" encoding="${source.encoding}" source="${javac.source}" target="${javac.target}" includes="@{includes}" excludes="@{excludes}" includeantruntime="false">\r
+                        <src>\r
+                            <dirset dir="@{gensrcdir}" erroronmissingdir="false">\r
+                                <include name="*"/>\r
+                            </dirset>\r
+                        </src>\r
+                        <classpath>\r
+                            <path path="@{classpath}"/>\r
+                        </classpath>\r
+                        <compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>\r
+                        <customize/>\r
+                    </javac>\r
+                </groovyc>\r
+            </sequential>\r
+        </macrodef>\r
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute name="srcdir" default="${src.dir}"/>\r
+            <attribute name="destdir" default="${build.classes.dir}"/>\r
+            <attribute name="classpath" default="${javac.classpath}"/>\r
+            <sequential>\r
+                <depend srcdir="@{srcdir}" destdir="@{destdir}" cache="${build.dir}/depcache" includes="${includes}" excludes="${excludes}">\r
+                    <classpath>\r
+                        <path path="@{classpath}"/>\r
+                    </classpath>\r
+                </depend>\r
+            </sequential>\r
+        </macrodef>\r
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">\r
+            <attribute name="destdir" default="${build.classes.dir}"/>\r
+            <sequential>\r
+                <fail unless="javac.includes">Must set javac.includes</fail>\r
+                <pathconvert property="javac.includes.binary" pathsep=",">\r
+                    <path>\r
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>\r
+                    </path>\r
+                    <globmapper from="*.java" to="*.class"/>\r
+                </pathconvert>\r
+                <delete>\r
+                    <files includes="${javac.includes.binary}"/>\r
+                </delete>\r
+            </sequential>\r
+        </macrodef>\r
+    </target>\r
+</project>\r
diff --git a/nbproject/jnlp-impl.xml b/nbproject/jnlp-impl.xml
new file mode 100644 (file)
index 0000000..df18b4f
--- /dev/null
@@ -0,0 +1,453 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License.  When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
+particular file as subject to the "Classpath" exception as provided
+by Sun in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+Contributor(s):
+
+The Original Software is NetBeans. The Initial Developer of the Original
+Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+Microsystems, Inc. All Rights Reserved.
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+-->
+
+<project name="jnlp-impl" default="default" basedir="..">
+
+    <property name="master.jnlp.file" location="master.jnlp"/>
+    <property name="launch.jnlp.file" value="launch.jnlp"/>
+    <property name="jnlp.dest.dir" location="dist"/>
+    
+    <!-- helper file to create list of arguments, etc. -->
+    <property name="helper.file" location="helper.txt"/>
+    
+    <target name="default">
+        <echo message="Default target is not set."/>
+    </target>
+    
+    <!-- Main target -->
+    
+    <target name="jnlp" depends="-init-check,-test-jnlp-enabled" if="is.jnlp.enabled">
+        <delete file="dist/lib/javaws.jar" failonerror="false"/>
+        <antcall target="generate-jnlp"/>
+    </target>
+    
+    <!-- Generate master -->
+    
+    <target name="-check-for-master.jnlp">
+        <available file="${master.jnlp.file}" property="master.jnlp.exists"/>
+    </target>
+    <target name="jnlp-init-generate-master" depends="-check-for-master.jnlp" unless="master.jnlp.exists">
+        <echo file="${master.jnlp.file}" encoding="UTF-8"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<jnlp spec="1.0+" codebase="$${jnlp.codebase}" href="launch.jnlp">
+    <information>
+        <title>$${APPLICATION.TITLE}</title>
+        <vendor>$${APPLICATION.VENDOR}</vendor>
+        <description>$${APPLICATION.DESC}</description>
+        <description kind="short">$${APPLICATION.DESC.SHORT}</description>
+        <homepage href="$${APPLICATION.HOMEPAGE}"/>
+<!--$${JNLP.ICONS}-->
+<!--$${JNLP.OFFLINE.ALLOWED}-->
+    </information>
+<!--$${JNLP.SECURITY}-->
+    <resources>
+<!--$${JNLP.RESOURCES.RUNTIME}-->
+<!--$${JNLP.RESOURCES.MAIN.JAR}-->
+<!--$${JNLP.RESOURCES.JARS}-->
+    </resources>
+    <application-desc main-class="$${jnlp.main.class}">
+<!--$${JNLP.APPLICATION.ARGS}-->
+    </application-desc>
+</jnlp>
+]]></echo>
+    </target>
+    
+    <!-- Initial check -->
+    
+    <target name="-init-check">
+        <fail unless="application.title" message="Must set application title."/>
+        <fail unless="application.vendor" message="Must set application vendor."/>
+    </target>
+    
+    <!-- Icons -->
+    
+    <target name="-init-icons" depends="-preinit-icons,-set-icon-elem,-set-splash-elem">
+        <property name="jnlp.icon.elem" value=""/>
+        <property name="application.splash.elem" value=""/>
+        <property name="icon.separator" value=""/>
+        <property name="jnlp.icons.value" value="${jnlp.icon.elem}${icon.separator}${application.splash.elem}"/>
+    </target>
+    <target name="-preinit-icons" depends="-copy-app-icon,-copy-app-splash"/>
+    <target name="-copy-app-icon" if="jnlp.icon" depends="-get-app-icon-name">
+        <copy file="${jnlp.icon}" todir="${jnlp.dest.dir}" failonerror="false"/>
+        <available file="${jnlp.dest.dir}${file.separator}${jnlp.icon.name}" property="jnlp.icon.copied"/>
+    </target>
+    <target name="-copy-app-splash" if="application.splash" depends="-get-app-splash-name">
+        <copy file="${application.splash}" todir="${jnlp.dest.dir}" failonerror="false"/>
+        <available file="${jnlp.dest.dir}${file.separator}${application.splash.name}" property="application.splash.copied"/>
+    </target>
+    <target name="-get-app-icon-name" if="jnlp.icon">
+        <dirname file="${jnlp.icon}" property="jnlp.icon.basedir"/>
+        <pathconvert property="jnlp.icon.name" setonempty="false">
+            <path location="${jnlp.icon}"/>
+            <map from="${jnlp.icon.basedir}${file.separator}" to=""/>
+        </pathconvert>
+    </target>
+    <target name="-get-app-splash-name" if="application.splash">
+        <dirname file="${application.splash}" property="application.splash.basedir"/>
+        <pathconvert property="application.splash.name" setonempty="false">
+            <path location="${application.splash}"/>
+            <map from="${application.splash.basedir}${file.separator}" to=""/>
+        </pathconvert>
+    </target>
+    <target name="-set-icon-elem" if="jnlp.icon.copied">
+        <property name="jnlp.icon.elem" value='        &lt;icon href="${jnlp.icon.name}" kind="default"/&gt;'/>
+    </target>
+    <target name="-set-splash-elem" if="application.splash.copied" depends="-set-icon-elem">
+        <property name="application.splash.elem" value='        &lt;icon href="${application.splash.name}" kind="splash"/&gt;'/>
+        <condition property="icon.separator" value="${line.separator}">
+            <isset property="jnlp.icon.elem"/>
+        </condition>
+    </target>
+    
+    <!-- Offline-Allowed -->
+    
+    <target name="-init-offline" if="offline.allowed.set" depends="-preinit-offline">
+        <property name="jnlp.offline.allowed.value" value="        &lt;offline-allowed/&gt;"/>
+    </target>
+    <target name="-preinit-offline">
+        <condition property="offline.allowed.set">
+            <equals arg1="${jnlp.offline-allowed}" arg2="true" trim="true"/>
+        </condition>
+    </target>
+    
+    <!-- Descriptions -->
+    
+    <target name="-init-descriptions" depends="-descriptions-props-check,-init-desc-value,-init-desc-value-short">
+        <property name="application.desc.value" value="${application.title}"/>
+        <property name="application.desc.short.value" value="${application.title}"/>
+    </target>
+    <target name="-descriptions-props-check">
+        <condition property="application.desc.set">
+            <and>
+                <isset property="application.desc"/>
+                <not>
+                    <equals arg1="${application.desc}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="application.desc.short.set">
+            <and>
+                <isset property="application.desc.short"/>
+                <not>
+                    <equals arg1="${application.desc.short}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+    </target>
+    <target name="-init-desc-value" if="application.desc.set">
+        <property name="application.desc.value" value="${application.desc}"/>
+    </target>
+    <target name="-init-desc-value-short" if="application.desc.short.set">
+        <property name="application.desc.short.value" value="${application.desc.short}"/>
+    </target>
+    
+    <!-- Security -->
+    
+    <target name="-init-security" depends="-check-signing-possible" if="jnlp.signed.true+signjarstask.available">
+        <property name="jnlp.security" value="    &lt;security&gt;${line.separator}        &lt;all-permissions/&gt;${line.separator}    &lt;/security&gt;"/>
+    </target>
+    <target name="-security-props-check">
+        <condition property="jnlp.signed.true">
+            <istrue value="${jnlp.signed}"/>
+        </condition>
+    </target>
+    <target name="-jnlp-init-keystore" depends="-jnlp-init-keystore-props,-check-keystore-exists" unless="jnlp.signjar.keystore.exists">
+        <echo message="${application.vendor}" file="${helper.file}"/>
+        <loadfile property="application.vendor.filtered" srcfile="${helper.file}">
+            <filterchain>
+                <deletecharacters chars=","/>
+            </filterchain>
+        </loadfile>
+        <delete file="${helper.file}"/>
+        <property name="jnlp.signjar.vendor" value="CN=${application.vendor.filtered}"/>
+        <echo message="Going to create default keystore in ${jnlp.signjar.keystore}"/>
+        <genkey dname="${jnlp.signjar.vendor}" alias="${jnlp.signjar.alias}" keystore="${jnlp.signjar.keystore}"
+            storepass="${jnlp.signjar.storepass}" keypass="${jnlp.signjar.keypass}"/>
+    </target>
+    <target name="-check-keystore-exists">
+        <available property="jnlp.signjar.keystore.exists" file="${jnlp.signjar.keystore}"/>
+    </target>
+    <target name="-jnlp-init-keystore-props">
+        <property name="jnlp.signjar.keystore" value="${basedir}/build/nb-jws.ks"/>
+        <property name="jnlp.signjar.storepass" value="storepass"/>
+        <property name="jnlp.signjar.keypass" value="keypass"/>
+        <property name="jnlp.signjar.alias" value="nb-jws"/>
+    </target>    
+    
+    <!-- Generating JNLP file -->
+    
+    <target name="generate-jnlp" depends="jnlp-init-generate-master,-init-codebase,-init-resources-runtime,-init-security,-init-resources-jars,-init-application-args,-init-icons,-init-offline,-init-descriptions,jnlp-init-notinited">
+        <copy file="${master.jnlp.file}" tofile="${jnlp.dest.dir}/${launch.jnlp.file}__" overwrite="true" encoding="UTF-8">
+            <filterchain>
+                <replacestring from="$${jnlp.codebase}" to="${jnlp.codebase.value}"/>
+                <replacestring from="&lt;!--$${JNLP.ICONS}--&gt;" to="${jnlp.icons.value}"/>
+                <replacestring from="&lt;!--$${JNLP.SECURITY}--&gt;" to="${jnlp.security}"/>
+                <replacestring from="&lt;!--$${JNLP.OFFLINE.ALLOWED}--&gt;" to="${jnlp.offline.allowed.value}"/>
+                <replacestring from="&lt;!--$${JNLP.RESOURCES.RUNTIME}--&gt;" to="${jnlp.resources.runtime.value}"/>
+                <replacestring from="&lt;!--$${JNLP.RESOURCES.MAIN.JAR}--&gt;" to="${jnlp.resources.main.jar.value}"/>
+                <replacestring from="&lt;!--$${JNLP.RESOURCES.JARS}--&gt;" to="${jnlp.resources.jars.value}"/>
+                <replacestring from="&lt;!--$${JNLP.APPLICATION.ARGS}--&gt;" to="${jnlp.application.args.value}"/>
+                <replacestring from="$${APPLICATION.TITLE}" to="${application.title}"/>
+                <replacestring from="$${APPLICATION.VENDOR}" to="${application.vendor}"/>
+                <replacestring from="$${APPLICATION.DESC}" to="${application.desc.value}"/>
+                <replacestring from="$${APPLICATION.DESC.SHORT}" to="${application.desc.short.value}"/>
+                <replacestring from="$${APPLICATION.HOMEPAGE}" to="${application.homepage}"/>
+                <replacestring from="$${jnlp.main.class}" to="${main.class}"/>
+            </filterchain>
+        </copy>
+        <antcall target="-strip-empty-lines"/>
+        <antcall target="-generate-html-page"/>
+    </target>
+    <target name="jnlp-init-notinited">
+        <property name="jnlp.security" value=""/>
+        <property name="jnlp.offline.allowed.value" value=""/>
+        <property name="application.homepage" value=""/>
+        <property name="jnlp.application.args.value" value=""/>
+    </target>
+    <target name="-strip-empty-lines">
+        <move file="${jnlp.dest.dir}/${launch.jnlp.file}__" tofile="${jnlp.dest.dir}/${launch.jnlp.file}" overwrite="true" encoding="UTF-8">
+            <filterchain>
+                <linecontainsregexp>
+                    <regexp pattern=".+"/>
+                </linecontainsregexp>
+            </filterchain>
+        </move>
+    </target>
+    
+    <!-- Codebase processing -->
+    
+    <target name="-init-codebase" depends="-codebase-props-check,-init-non-user-codebase,-init-user-codebase"/>
+    <target name="-codebase-props-check">
+        <condition property="local.codebase">
+            <or>
+                <not>
+                    <isset property="jnlp.codebase.type"/>
+                </not>
+                <equals arg1="${jnlp.codebase.type}" arg2="local" trim="true"/>
+            </or>
+        </condition>
+        <condition property="non.user.codebase">
+            <or>
+                <not>
+                    <isset property="jnlp.codebase.type"/>
+                </not>
+                <equals arg1="${jnlp.codebase.type}" arg2="local" trim="true"/>
+                <equals arg1="${jnlp.codebase.type}" arg2="web" trim="true"/>
+            </or>
+        </condition>
+        <condition property="user.codebase">
+            <equals arg1="${jnlp.codebase.type}" arg2="user" trim="true"/>
+        </condition>
+    </target>
+    <target name="-init-non-user-codebase" if="non.user.codebase">
+        <property name="jnlp.codebase.value" value="${jnlp.codebase.url}"/>
+    </target>
+    <target name="-init-user-codebase" if="user.codebase">
+        <property name="jnlp.codebase.value" value="${jnlp.codebase.user}"/>
+    </target>
+    
+    <!-- j2se resources -->
+    
+    <target name="-init-resources-runtime" depends="-init-runtime-props">
+        <property name="run.jvmargs.value" value=""/>
+        <property name="initial-heap-size.value" value=""/>
+        <property name="max-heap-size.value" value=""/>
+        <property name="jnlp.resources.runtime.value" 
+            value='        &lt;j2se version="${javac.target}+"${initial-heap-size.value}${max-heap-size.value}${run.jvmargs.value}/&gt;'/>
+    </target>
+    <target name="-init-runtime-props" depends="-runtime-props-check,-init-run-jvmargs-value,-init-initial-heap-size-value,-init-max-heap-size-value"/>
+    <target name="-runtime-props-check">
+        <condition property="run.jvmargs.set">
+            <and>
+                <isset property="run.jvmargs"/>
+                <not>
+                    <equals arg1="${run.jvmargs}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="jnlp.initial-heap-size.set">
+            <and>
+                <isset property="jnlp.initial-heap-size"/>
+                <not>
+                    <equals arg1="${jnlp.initial-heap-size}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="jnlp.max-heap-size.set">
+            <and>
+                <isset property="jnlp.max-heap-size"/>
+                <not>
+                    <equals arg1="${jnlp.max-heap-size}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+    </target>
+    <target name="-init-run-jvmargs-value" if="run.jvmargs.set">
+        <property name="run.jvmargs.value" value=' java-vm-args="${run.jvmargs}"'/>
+    </target>
+    <target name="-init-initial-heap-size-value" if="jnlp.initial-heap-size.set">
+        <property name="initial-heap-size.value" value=' initial-heap-size="${jnlp.initial-heap-size}"'/>
+    </target>
+    <target name="-init-max-heap-size-value" if="jnlp.max-heap-size.set">
+        <property name="max-heap-size.value" value=' max-heap-size="${jnlp.max-heap-size}"'/>
+    </target>
+    
+    <!-- JAR resources -->
+    
+    <target name="-init-resources-jars" depends="-preinit-resources-unsigned-jars,-preinit-resources-signed-jars,-preinit-resources-main-jar"/>
+    <target name="-preinit-resources-unsigned-jars" depends="-exclude-javaws-from-cp,-check-signing-possible" unless="jnlp.signed.true+signjarstask.available">
+        <pathconvert pathsep="${line.separator}" property="jnlp.resources.jars.value">
+            <path path="${run.classpath.without.javaws.jar}"/>
+            <mapper type="regexp" from="^.*[/\\]([^/\\]+\.jar)"
+                to='        &lt;jar href="lib/\1" download="eager"/&gt;'/>
+        </pathconvert>
+    </target>
+    <target name="-preinit-resources-main-jar">
+        <pathconvert pathsep="${line.separator}" property="jnlp.resources.main.jar.value">
+            <path location="${dist.jar}"/>
+            <mapper type="regexp" from="^.*[/\\]([^/\\]+\.jar)"
+                to='        &lt;jar href="\1" main="true" download="eager"/&gt;'/>
+        </pathconvert>
+    </target>
+    <target name="-exclude-javaws-from-cp">
+        <pathconvert property="path.element.to.be.removed">
+            <path path="${run.classpath}"/>
+            <mapper type="regexp" from="(^.*[/\\]javaws.jar)" to="\1"/>
+        </pathconvert>
+        <pathconvert property="run.classpath.without.javaws.jar">
+            <path path="${run.classpath}"/>
+            <map from="${path.element.to.be.removed}" to=""/>
+        </pathconvert>
+    </target>
+    <target name="-check-task-available">
+        <condition property="signjarstask.available">
+            <isset property="netbeans.home"/>
+        </condition>
+    </target>
+    <target name="-check-signing-possible" depends="-security-props-check,-check-task-available">
+        <condition property="jnlp.signed.true+signjarstask.available">
+            <and>
+                <isset property="jnlp.signed.true"/>
+                <isset property="signjarstask.available"/>
+            </and>
+        </condition>
+    </target>
+    <target name="-unavailable-task-warning" depends="-check-task-available" unless="signjarstask.available">
+        <echo message="Signtask is not available, jar files will not be signed. Task is available only when running inside NetBeans IDE."/>
+    </target>
+    <target name="-preinit-resources-signed-jars" depends="-unavailable-task-warning,-sign-jars" if="jnlp.signed.true+signjarstask.available">
+        <property name="jnlp.resources.jars.value" value="${jnlp.signed.jars}${jnlp.components}"/>
+    </target>
+    <target name="-sign-jars" depends="-jnlp-init-keystore,-check-signing-possible" if="jnlp.signed.true+signjarstask.available">
+        <jnlpsignjars keystore="${jnlp.signjar.keystore}" storepass="${jnlp.signjar.storepass}" 
+                keypass="${jnlp.signjar.keypass}" alias="${jnlp.signjar.alias}" mainjar="${dist.jar}" destdir="dist"
+                codebase="${jnlp.codebase.value}" signedjarsprop="jnlp.signed.jars"
+                componentsprop="jnlp.components">
+            <fileset dir="dist/lib">
+                <include name="*.jar"/>
+            </fileset>
+        </jnlpsignjars>
+    </target>
+    
+    <!-- Application arguments -->
+    
+    <target name="-init-application-args" if="application.args">
+        <echo message="${application.args}" file="${helper.file}"/>
+        <loadfile srcfile="${helper.file}" property="jnlp.application.args.value">
+            <filterchain>
+                <tokenfilter delimoutput="\n">
+                    <stringtokenizer/>
+                    <replaceregex pattern="(.+)" replace="        &lt;argument&gt;\1&lt;/argument&gt;"/>
+                </tokenfilter>
+            </filterchain>
+        </loadfile>
+        <delete file="${helper.file}"/>
+    </target>
+    
+    <!-- Running/Debugging -->
+    
+    <target name="jws-run" depends="jar,-verify-jnlp-enabled,-verify-codebase" description="Start javaws execution">
+        <exec executable="${java.home}/bin/javaws">
+            <arg file="${jnlp.dest.dir}/${launch.jnlp.file}"/>
+        </exec>
+    </target>
+    <target name="jws-debug" if="netbeans.home" depends="jar,-verify-jnlp-enabled,-verify-codebase,-debug-start-debugger,-debug-javaws-debuggee" 
+        description="Debug javaws project in IDE"/>
+    <target name="-debug-javaws-debuggee">
+        <exec executable="${java.home}/bin/javaws">
+            <env key="JAVAWS_VM_ARGS" value="-Xdebug -Xnoagent -Djava.compiler=none -Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
+            <arg file="${jnlp.dest.dir}/${launch.jnlp.file}"/>
+        </exec>
+    </target>
+    <target name="-verify-codebase" depends="-codebase-props-check" unless="local.codebase">
+        <fail message="Project cannot be run with non-local codebase. Open project properties dialog and set Web Start Codebase to Local Execution."/>
+    </target>
+    <target name="-verify-jnlp-enabled" depends="-test-jnlp-enabled" unless="is.jnlp.enabled">
+        <fail message="Project cannot be run with selected Run Configuration when Java Web Start is disabled."/>
+    </target>
+    
+    <!-- Test JNLP enabled-->
+    
+    <target name="-test-jnlp-enabled">
+        <condition property="is.jnlp.enabled">
+            <equals arg1="${jnlp.enabled}" arg2="true" casesensitive="false" trim="true"/>
+        </condition>
+    </target>
+    
+    <!-- Generate simple HTML test page -->
+    
+    <target name="-generate-html-page">
+        <echo file="${jnlp.dest.dir}/launch.html"><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+    <head>
+        <title>Test page for launching the application via JNLP</title>
+    </head>
+    <body>
+        <h3>Test page for launching the application via JNLP</h3>
+        <a href="launch.jnlp">Launch the application</a>
+    </body>
+</html>
+]]></echo>
+    </target>
+    
+</project>
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644 (file)
index 0000000..8e1f1d2
--- /dev/null
@@ -0,0 +1,97 @@
+application.homepage=http://feather.cocolog-nifty.com/\r
+application.title=DEMO:\u30cb\u30b3\u30cb\u30b3\u52d5\u753b\u30b3\u30f3\u30c6\u30f3\u30c4\u60c5\u5831\u30d6\u30e9\u30a6\u30b6\r
+application.vendor=yukihane\r
+build.classes.dir=${build.dir}/classes\r
+build.classes.excludes=\r
+# This directory is removed when the project is cleaned:\r
+build.dir=build\r
+build.generated.dir=${build.dir}/generated\r
+build.generated.sources.dir=${build.dir}/generated-sources\r
+# Only compile against the classpath explicitly listed here:\r
+build.sysclasspath=ignore\r
+build.test.classes.dir=${build.dir}/test/classes\r
+build.test.results.dir=${build.dir}/test/results\r
+debug.classpath=\\r
+    ${run.classpath}\r
+debug.test.classpath=\\r
+    ${run.test.classpath}\r
+# This directory is removed when the project is cleaned:\r
+dist.dir=dist\r
+dist.jar=${dist.dir}/NicoBrowser.jar\r
+dist.javadoc.dir=${dist.dir}/javadoc\r
+excludes=\r
+file.reference.commons-io-1.4.jar=F:\\data\\java\\commons\\commons-io-1.4\\commons-io-1.4.jar\r
+includes=**\r
+jar.compress=false\r
+javac.classpath=\\r
+    ${libs.Codec.classpath}:\\r
+    ${libs.Rome.classpath}:\\r
+    ${libs.H2_DB.classpath}:\\r
+    ${libs.toplink.classpath}:\\r
+    ${libs.HttpClient4.classpath}:\\r
+    ${libs.Log4J.classpath}:\\r
+    ${libs.NekoHtml.classpath}:\\r
+    ${file.reference.commons-io-1.4.jar}:\\r
+    ${libs.groovy-all.classpath}\r
+# Space-separated list of extra javac options\r
+javac.compilerargs=\r
+javac.deprecation=false\r
+javac.source=1.5\r
+javac.target=1.5\r
+javac.test.classpath=\\r
+    ${javac.classpath}:\\r
+    ${build.classes.dir}:\\r
+    ${libs.junit_4.classpath}:\\r
+    ${libs.groovy-all.classpath}\r
+javadoc.additionalparam=\r
+javadoc.author=false\r
+javadoc.encoding=${source.encoding}\r
+javadoc.noindex=false\r
+javadoc.nonavbar=false\r
+javadoc.notree=false\r
+javadoc.private=false\r
+javadoc.reference.commons-io-1.4.jar=F:\\data\\java\\commons\\commons-io-1.4\\docs\r
+javadoc.splitindex=true\r
+javadoc.use=true\r
+javadoc.version=false\r
+javadoc.windowtitle=\r
+jnlp.codebase.type=user\r
+jnlp.codebase.user=http://feather.cocolog-nifty.com/weblog/program/NicoBrowser\r
+jnlp.descriptor=application\r
+jnlp.enabled=false\r
+jnlp.offline-allowed=true\r
+jnlp.signed=true\r
+# Property libs.Codec.classpath is set here just to make sharing of project simpler.\r
+# The library definition has always preference over this property.\r
+libs.Codec.classpath=../../../java/commons/commons-codec-1.3/commons-codec-1.3.jar\r
+# Property libs.H2_DB.classpath is set here just to make sharing of project simpler.\r
+# The library definition has always preference over this property.\r
+libs.H2_DB.classpath=../../../java/h2-2008-02-02/h2/bin/h2.jar\r
+# Property libs.HttpClient4.classpath is set here just to make sharing of project simpler.\r
+# The library definition has always preference over this property.\r
+libs.HttpClient4.classpath=../../../java/commons/httpcomponents-client-4.0-alpha3-bin-with-dependencies/httpcomponents-client-4.0-alpha3/lib/commons-io-1.2.jar;../../../java/commons/httpcomponents-client-4.0-alpha3-bin-with-dependencies/httpcomponents-client-4.0-alpha3/lib/httpclient-4.0-alpha3.jar;../../../java/commons/httpcomponents-client-4.0-alpha3-bin-with-dependencies/httpcomponents-client-4.0-alpha3/lib/httpcore-4.0-beta1.jar;../../../java/commons/httpcomponents-client-4.0-alpha3-bin-with-dependencies/httpcomponents-client-4.0-alpha3/lib/httpmime-4.0-alpha3.jar\r
+# Property libs.Log4J.classpath is set here just to make sharing of project simpler.\r
+# The library definition has always preference over this property.\r
+libs.Log4J.classpath=../../../java/commons/commons-logging-1.1/commons-logging-adapters-1.1.jar;../../../java/commons/commons-logging-1.1/commons-logging-api-1.1.jar\r
+# Property libs.Rome.classpath is set here just to make sharing of project simpler.\r
+# The library definition has always preference over this property.\r
+libs.Rome.classpath=../../../java/commons/rome-0.9/rome-0.9.jar;../../../java/commons/jdom-1.1/build/jdom.jar\r
+main.class=nicobrowser.main.Main\r
+manifest.file=manifest.mf\r
+meta.inf.dir=${src.dir}/META-INF\r
+platform.active=default_platform\r
+run.classpath=\\r
+    ${javac.classpath}:\\r
+    ${build.classes.dir}\r
+# Space-separated list of JVM arguments used when running the project\r
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value\r
+# or test-sys-prop.name=value to set system properties for unit tests):\r
+run.jvmargs=\r
+run.test.classpath=\\r
+    ${javac.test.classpath}:\\r
+    ${build.test.classes.dir}\r
+source.encoding=UTF-8\r
+source.reference.commons-io-1.4.jar=F:\\data\\java\\commons\\commons-io-1.4\\commons-io-1.4-sources.jar\r
+src.dir=src\r
+test.src.dir=test\r
+compile.on.save.unsupported.groovy=true\r
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644 (file)
index 0000000..7fcdea1
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<project xmlns="http://www.netbeans.org/ns/project/1">\r
+    <type>org.netbeans.modules.java.j2seproject</type>\r
+    <configuration>\r
+        <buildExtensions xmlns="http://www.netbeans.org/ns/ant-build-extender/1">\r
+            <extension file="groovy-build.xml" id="groovy">\r
+                <dependency dependsOn="-groovy-init-macrodef-javac" target="-pre-pre-compile"/>\r
+            </extension>\r
+            <extension file="jnlp-impl.xml" id="jws">\r
+                <dependency dependsOn="jnlp" target="jar"/>\r
+            </extension>\r
+        </buildExtensions>\r
+        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">\r
+            <name>NicoBrowser</name>\r
+            <minimum-ant-version>1.6.5</minimum-ant-version>\r
+            <source-roots>\r
+                <root id="src.dir"/>\r
+            </source-roots>\r
+            <test-roots>\r
+                <root id="test.src.dir"/>\r
+            </test-roots>\r
+        </data>\r
+    </configuration>\r
+</project>\r
diff --git a/src/META-INF/persistence.xml b/src/META-INF/persistence.xml
new file mode 100644 (file)
index 0000000..4f93d6c
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
+  <persistence-unit name="NicoBrowserPU" transaction-type="RESOURCE_LOCAL">
+    <provider>oracle.toplink.essentials.PersistenceProvider</provider>
+    <class>nicobrowser.entity.NicoContent</class>
+    <properties>
+      <property name="toplink.jdbc.user" value="sa"/>
+      <property name="toplink.jdbc.password" value=""/>
+      <property name="toplink.jdbc.url" value="jdbc:h2:db/NicoDB"/>
+      <property name="toplink.jdbc.driver" value="org.h2.Driver"/>
+      <property name="toplink.ddl-generation" value="create-tables"/>
+    </properties>
+  </persistence-unit>
+</persistence>
diff --git a/src/commons-logging.properties b/src/commons-logging.properties
new file mode 100644 (file)
index 0000000..aacf15a
--- /dev/null
@@ -0,0 +1 @@
+org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
\ No newline at end of file
diff --git a/src/log4j.properties b/src/log4j.properties
new file mode 100644 (file)
index 0000000..d1746b6
--- /dev/null
@@ -0,0 +1,19 @@
+### stdout ###
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %5p - %m%n
+
+### file output ###
+log4j.appender.file=org.apache.log4j.FileAppender
+log4j.appender.file.File=log.log
+log4j.appender.file.Append=true
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%m%n
+
+### null ###
+log4j.appender.null=org.apache.log4j.varia.NullAppender
+
+
+# log4j.logger.nicobrowser=trace, file
+log4j.rootLogger=info, stdout
diff --git a/src/nicobrowser/Config.java b/src/nicobrowser/Config.java
new file mode 100644 (file)
index 0000000..02d33e8
--- /dev/null
@@ -0,0 +1,260 @@
+/*$Id$*/
+package nicobrowser;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public final class Config {
+
+    /**
+     * feedurl.txtから取得した情報を格納する.
+     */
+    public static class NicoFeed {
+
+        private final String url;
+        private final int number;
+
+        public NicoFeed(String url, int number) {
+            this.url = url;
+            this.number = number;
+        }
+
+        /** @return 上位いくつまでダウンロード対象とするか. */
+        public int getNumber() {
+            return number;
+        }
+
+        /** @return フィードのURL. */
+        public String getUrl() {
+            return url;
+        }
+
+        @Override
+        public String toString() {
+            return getUrl() + ", " + getNumber();
+        }
+    }
+    private static Log log = LogFactory.getLog(Config.class);
+    private static Config instance;
+    private final Properties properties;
+    private static final String APPLICATION_NAME = "nicobrowser";
+    private static final String CONFIG_NAME = APPLICATION_NAME + ".properties";
+    private static final String FEEDURL_NAME = "feedurl.txt";
+    private static final File APP_HOME = new File(System.getProperty("user.home", "."), "." + APPLICATION_NAME);
+    private static final File CONFIG_FILE = new File(APP_HOME, CONFIG_NAME);
+    private static final File FEEDURL_FILE = new File(APP_HOME, FEEDURL_NAME);
+    private static final String P_PATH_DB = "path.db";
+    private static final String P_PATH_SAVEFILE = "path.savefile";
+    private static final String P_FILE_ENCODING = "encoding";
+    private static final String P_NICOVIDEO_MAIL = "nicovideo.mail";
+    private static final String P_NICOVIDEO_PASSWORD = "nicovideo.password";
+    private static final String P_DOWNLOAD_RETRY = "download.retry";
+    private static final String P_DOWNLOAD_MYLIST = "download.mylist";
+
+    /**
+     * プログラム実行に必要なコンフィグファイルを作成する.
+     * @return 今回コンフィグを作成したのであればtrue. 既に存在していたため, ファイル作成を行わなかった場合にはfalse.
+     * @throws java.io.IOException ファイル作成に失敗した.
+     */
+    public static boolean createNewConfigFiles() throws IOException {
+        boolean result = false;
+        if (!CONFIG_FILE.exists()) {
+            createNewConfigFile(CONFIG_FILE);
+            result = true;
+            log.info("コンフィグファイルを作成しました: " + CONFIG_FILE.getCanonicalPath());
+        }
+        if (!FEEDURL_FILE.exists()) {
+            InputStream resource = null;
+            try {
+                resource = ClassLoader.getSystemResourceAsStream("resources/" + FEEDURL_NAME);
+                createNewFeedFile(resource, FEEDURL_FILE);
+                result = true;
+                log.info("FEED URLファイルを作成しました: " + FEEDURL_FILE.getCanonicalPath());
+            } finally {
+                if (resource != null) {
+                    resource.close();
+                }
+            }
+        }
+        return result;
+    }
+
+    private static void createNewConfigFile(File file) throws IOException {
+        ArrayList<CharSequence> props = new ArrayList<CharSequence>();
+
+        StringBuilder dbpath = new StringBuilder(P_PATH_DB + "=");
+        File dbDir = new File(APP_HOME, "db");
+        dbDir.mkdirs();
+        //Windowsのパス区切りバックスペースをエスケープするための処理も入れている.
+        dbpath.append(dbDir.getAbsolutePath().replaceAll("\\\\", "\\\\\\\\"));
+        props.add(dbpath);
+
+        StringBuilder savepath = new StringBuilder(P_PATH_SAVEFILE + "=");
+        File saveDir = new File(APP_HOME, "flv");
+        saveDir.mkdirs();
+        savepath.append(saveDir.getAbsolutePath().replaceAll("\\\\", "\\\\\\\\"));
+        props.add(savepath);
+
+        props.add(P_FILE_ENCODING + "=" + System.getProperty("file.encoding"));
+
+        props.add(P_NICOVIDEO_MAIL + "=set.your@mail.address");
+        props.add(P_NICOVIDEO_PASSWORD + "=set_your_password");
+        props.add(P_DOWNLOAD_RETRY + "=3");
+        props.add(P_DOWNLOAD_MYLIST + "=");
+
+        FileUtils.writeLines(file, props);
+    }
+
+    private static void createNewFeedFile(InputStream resource, File dest) throws IOException {
+        List<String> list = new ArrayList<String>();
+        BufferedReader br = new BufferedReader(new InputStreamReader(resource, "UTF-8"));
+        while (true) {
+            String text = br.readLine();
+            if (text == null) {
+                break;
+            }
+            list.add(text);
+        }
+        FileUtils.writeLines(dest, list);
+    }
+
+    private Config() {
+        properties = new Properties();
+        FileInputStream fis = null;
+        try {
+            fis = new FileInputStream(CONFIG_FILE);
+            properties.load(fis);
+        } catch (IOException ex) {
+            log.fatal("コンフィグの読み込みに失敗: " + CONFIG_FILE);
+            throw new RuntimeException(ex);
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException ex) {
+                    log.warn("", ex);
+                }
+            }
+        }
+
+        try {
+            List urls = FileUtils.readLines(FEEDURL_FILE);
+        } catch (IOException ex) {
+            log.fatal("コンフィグの読み込みに失敗: " + CONFIG_FILE);
+            throw new RuntimeException(ex);
+        }
+    }
+
+    public static Config getInstance() {
+        if (instance == null) {
+            instance = new Config();
+        }
+        return instance;
+    }
+
+    /**
+     * @return ニコニコ動画ログインID.
+     */
+    public String getNicoMail() {
+        return properties.getProperty(P_NICOVIDEO_MAIL);
+    }
+
+    /**
+     * @return ニコニコ動画ログインパスワード.
+     */
+    public String getNicoPassword() {
+        return properties.getProperty(P_NICOVIDEO_PASSWORD);
+    }
+
+    /** @return DBパス */
+    public String getDbFile() {
+        return new File(properties.getProperty(P_PATH_DB), "nicodb").getAbsolutePath();
+    }
+
+    /** @return 保存先の指定. */
+    public String getSrcSaveDir() {
+        return properties.getProperty(P_PATH_SAVEFILE);
+    }
+
+    /** @return feedurl.txtの文字エンコーディング. */
+    public String getEncoding() {
+        String res = properties.getProperty(P_FILE_ENCODING, System.getProperty("file.encoding"));
+        return res;
+    }
+//    /**
+//     * video/mp4のストリーム保存時、ファイルの拡張子に
+//     * .mp4を使用する(true)か、使用しない(.flv)か.
+//     * @return mp4拡張子を使用する場合true.
+//     */
+//    public boolean isExtMp4Use() {
+//        String res = properties.getProperty("download.ext.mp4");
+//        if ("false".equalsIgnoreCase(res)) {
+//            return false;
+//        }
+//        return true;
+//    }
+//
+
+    /**
+     * 失敗したダウンロードファイルの最大リトライ回数を取得する.
+     * @return リトライ回数.
+     */
+    public int getMaxRetry() {
+        String res = properties.getProperty(P_DOWNLOAD_RETRY);
+        return Integer.parseInt(res);
+    }
+//
+//    /**
+//     * 上位何位までの動画をダウンロードするか.
+//     * @return ダウンロードするファイルの最下位.
+//     */
+//    public int getMaxDownloadNumber() {
+//        String res = properties.getProperty("download.number");
+//        return Integer.parseInt(res);
+//    }
+//
+
+    public List<String> getDownLoadMyList() {
+        List<String> list = new ArrayList<String>();
+        String res = properties.getProperty(P_DOWNLOAD_MYLIST);
+        String[] nums = res.split(",");
+        for (int i = 0; i < nums.length; i++) {
+            String text = nums[i].trim();
+            if (!text.isEmpty()) {
+                list.add(text);
+            }
+        }
+        return list;
+    }
+
+    public List<NicoFeed> getNicoFeeds() {
+        List<NicoFeed> list = new ArrayList<NicoFeed>();
+        try {
+            List lines = FileUtils.readLines(FEEDURL_FILE, getEncoding());
+            for (Object line : lines) {
+                final String str = line.toString();
+                if (str.isEmpty() || str.startsWith("#")) {
+                    // 空行, コメント行はスキップ.
+                    continue;
+                }
+
+                String[] values = str.split(",");
+                NicoFeed feed = new NicoFeed(values[0].trim(), Integer.parseInt(values[1].trim()));
+                list.add(feed);
+            }
+        } catch (IOException ex) {
+            log.error("ファイルが見つかりません: " + FEEDURL_FILE);
+        }
+        return list;
+    }
+}
diff --git a/src/nicobrowser/NicoHttpClient.java b/src/nicobrowser/NicoHttpClient.java
new file mode 100644 (file)
index 0000000..1a020c9
--- /dev/null
@@ -0,0 +1,607 @@
+/*$Id$*/
+package nicobrowser;
+
+import java.net.URISyntaxException;
+import nicobrowser.entity.NicoContent;
+import com.sun.syndication.feed.synd.SyndContentImpl;
+import com.sun.syndication.feed.synd.SyndEntryImpl;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.io.FeedException;
+import com.sun.syndication.io.SyndFeedInput;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.List;
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.html.parser.ParserDelegator;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import nicobrowser.entity.NicoContent.Status;
+import nicobrowser.util.Result;
+import nicobrowser.util.Util;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.client.params.CookiePolicy;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ *
+ * @author yuki
+ */
+public class NicoHttpClient extends DefaultHttpClient {
+
+    private static Log log = LogFactory.getLog(NicoHttpClient.class);
+    static NicoHttpClient instance;
+    private static final String LOGIN_PAGE =
+            "https://secure.nicovideo.jp/secure/login?site=niconico";
+    private static final String LOGOUT_PAGE =
+            "https://secure.nicovideo.jp/secure/logout";
+    private static final String MY_LIST_PAGE_HEADER =
+            "http://www.nicovideo.jp/mylist/";
+    private static final String MOVIE_THUMBNAIL_PAGE_HEADER =
+            "http://www.nicovideo.jp/api/getthumbinfo/";
+    private static final String GET_FLV_INFO = "http://www.nicovideo.jp/api/getflv/";
+    private static final String SEARCH_HEAD = "http://www.nicovideo.jp/search/";
+    private static final String SEARCH_TAIL = "?sort=v";
+
+    private NicoHttpClient() {
+        super();
+        getParams().setParameter(
+                ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
+        instance = this;
+    }
+
+    public static NicoHttpClient getInstance() {
+        if (instance == null) {
+            return new NicoHttpClient();
+        }
+        return instance;
+    }
+
+    /**
+     * ニコニコ動画へログインする.
+     * @param mail ログイン識別子(登録メールアドレス).
+     * @param password パスワード.
+     * @return 認証がOKであればtrue.
+     */
+    public boolean login(String mail, String password) throws URISyntaxException, HttpException, InterruptedException {
+        boolean auth = false;
+        HttpPost post = new HttpPost(LOGIN_PAGE);
+
+        try {
+            NameValuePair[] nvps = new NameValuePair[]{
+                new BasicNameValuePair("mail", mail),
+                new BasicNameValuePair("password", password),
+                new BasicNameValuePair("next_url", "")
+            };
+            post.setEntity(new UrlEncodedFormEntity(Arrays.asList(nvps), "UTF-8"));
+
+            //post.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
+            HttpResponse response = execute(post);
+            log.debug("ログインステータスコード: " + response.getStatusLine().getStatusCode());
+
+            // ログイン可否の判定.
+            HttpEntity entity = response.getEntity();
+            entity.consumeContent();
+            List<Cookie> cookies = getCookieStore().getCookies();
+            if (!cookies.isEmpty()) {
+                auth = true;
+            }
+        } catch (IOException ex) {
+            log.error("ログイン時に問題が発生", ex);
+        }
+        return auth;
+    }
+
+    /**
+     * ニコニコ動画からログアウトする.
+     * @return ログアウトに成功すればtrue.
+     */
+    public boolean logout() throws URISyntaxException, HttpException, InterruptedException {
+        boolean result = false;
+        HttpGet method = new HttpGet(LOGOUT_PAGE);
+        try {
+            HttpResponse response = execute(method);
+            log.debug("ログアウトステータスコード: " + response.getStatusLine().getStatusCode());
+
+            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+                result = true;
+            }
+            response.getEntity().consumeContent();
+        } catch (IOException ex) {
+            log.error("ログアウト時に問題が発生", ex);
+        }
+        return result;
+    }
+
+    /**
+     * キーワード検索を行う.
+     * @param word 検索キーワード
+     * @return 検索結果.
+     */
+    public List<NicoContent> search(String word) {
+        log.debug("検索:" + word);
+
+        InputStream is = null;
+        List<NicoContent> conts = new ArrayList<NicoContent>();
+        String url = new String(SEARCH_HEAD + word + SEARCH_TAIL);
+
+        try {
+            while (url != null) {
+                HttpGet get = new HttpGet(url);
+                HttpResponse response;
+                response = execute(get);
+                is = new BufferedInputStream(response.getEntity().getContent());
+                assert is.markSupported();
+                is.mark(1024 * 1024);
+                List<Result> results = Util.parseSerchResult(is);
+                for (Result r : results) {
+                    NicoContent c = loadMyMovie(r.getId());
+                    if (c != null) {
+                        conts.add(c);
+                    }
+                }
+                is.reset();
+                url = Util.getNextPage(is);
+                is.close();
+            }
+        } catch (IOException ex) {
+            log.error("検索結果処理時に例外発生", ex);
+        }
+        return conts;
+    }
+
+    /**
+     * 「マイリスト登録数ランキング(本日)」の動画一覧を取得する。
+     * @return 動画一覧.
+     */
+    public List<NicoContent> loadMyListDaily() throws URISyntaxException, HttpException, InterruptedException {
+        List<NicoContent> list = new ArrayList<NicoContent>();
+        String url = new String("http://www.nicovideo.jp/ranking/mylist/daily/all?rss=atom");
+        log.debug("全動画サイトのマイリスト登録数ランキング(本日)[全体] : " + url);
+
+        HttpGet get = new HttpGet(url);
+
+        BufferedReader reader = null;
+        try {
+            HttpResponse response = execute(get);
+            reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
+            // BOMを読み捨て
+            // reader.skip(1);
+            list = getNicoContents(reader);
+            deleteRankString(list);
+            response.getEntity().consumeContent();
+        } catch (FeedException ex) {
+            log.error("", ex);
+        } catch (IOException ex) {
+            log.error("", ex);
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException ex) {
+                    log.error("", ex);
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * ニコニコ動画のRSSからコンテンツリストを取得する.
+     * @param url 取得するrssのurl.
+     * @return コンテンツリスト.
+     */
+    public List<NicoContent> getContentsFromRss(String url) {
+        log.debug("アクセスURL: " + url);
+        List<NicoContent> list = accessRssUrl(url);
+        if (url.contains("ranking")) {
+            deleteRankString(list);
+        }
+        return list;
+    }
+
+    /**
+     * rankingの場合、本当のタイトルの前に"第XX位:"の文字列が
+     * 挿入されているため, それを削る.
+     * @param list 対象のリスト.
+     */
+    private void deleteRankString(List<NicoContent> list) {
+        for (NicoContent c : list) {
+            String title = c.getTitle();
+            int offset = title.indexOf(":") + 1;
+            c.setTitle(title.substring(offset));
+        }
+    }
+
+    /**
+     * マイリストに登録した動画一覧の取得.
+     * 「公開」設定にしていないリストからは取得できない.
+     * ログインしていなくても取得可能.
+     * @param listNo マイリストNo.
+     * @return 動画一覧.
+     */
+    public List<NicoContent> loadMyList(String listNo) {
+        String url = new String(MY_LIST_PAGE_HEADER + listNo + "?rss=atom");
+        log.debug("マイリストURL: " + url);
+        return accessRssUrl(url);
+    }
+
+    /**
+     * 動画番号を指定したコンテンツ情報の取得.
+     * @param movieNo 動画番号.
+     * @return コンテンツ情報.
+     */
+    public NicoContent loadMyMovie(String movieNo) {
+        NicoContent cont = null;
+        InputStream re = null;
+        List<SyndEntryImpl> list = null;
+        String url = new String(MOVIE_THUMBNAIL_PAGE_HEADER + movieNo);
+        log.debug("動画サムネイルURL: " + url);
+
+        HttpGet get;
+
+        try {
+            get = new HttpGet(url);
+            HttpResponse response = execute(get);
+            re = response.getEntity().getContent();
+            // ドキュメントビルダーファクトリを生成
+            DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
+            // ドキュメントビルダーを生成
+            DocumentBuilder builder = dbfactory.newDocumentBuilder();
+            // パースを実行してDocumentオブジェクトを取得
+            Document doc = builder.parse(re);
+            // ルート要素を取得(タグ名:site)
+            Element root = doc.getDocumentElement();
+
+            if ("fail".equals(root.getAttribute("status"))) {
+                log.warn("情報取得できません: " + movieNo);
+                return null;
+            }
+
+            NodeList list2 = root.getElementsByTagName("thumb");
+            cont = new NicoContent();
+            Element element = (Element) list2.item(0);
+
+            String watch_url = ((Element) element.getElementsByTagName("watch_url").item(0)).getFirstChild().
+                    getNodeValue();
+            cont.setPageLink(watch_url);
+
+            String title = ((Element) element.getElementsByTagName("title").item(0)).getFirstChild().getNodeValue();
+            cont.setTitle(title);
+
+            // TODO 投稿日の設定
+//            String first_retrieve = ((Element) element.getElementsByTagName("first_retrieve").item(0)).getFirstChild().getNodeValue();
+//            cont.setPublishedDate(DateFormat.getInstance().parse(first_retrieve));
+//
+//        } catch (ParseException ex) {
+//            Logger.getLogger(NicoHttpClient.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (SAXException ex) {
+            log.error("", ex);
+        } catch (IOException ex) {
+            log.error("", ex);
+        } catch (ParserConfigurationException ex) {
+            log.error("", ex);
+        } finally {
+            try {
+                if (re != null) {
+                    re.close();
+                }
+            } catch (IOException ex) {
+                log.error("", ex);
+            }
+        }
+        return cont;
+    }
+
+    private List<NicoContent> accessRssUrl(String url) {
+        List<NicoContent> contList = new ArrayList<NicoContent>();
+        HttpGet get = new HttpGet(url);
+        BufferedReader reader = null;
+        try {
+            HttpResponse response = execute(get);
+            reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
+            if (log.isTraceEnabled()) {
+                reader.mark(1024 * 1024);
+                while (true) {
+                    String str = reader.readLine();
+                    if (str == null) {
+                        break;
+                    }
+                    log.trace(str);
+                }
+                reader.reset();
+            }
+            contList = getNicoContents(reader);
+        } catch (FeedException ex) {
+            log.warn("アクセスできません: " + url);
+            log.debug("", ex);
+        } catch (IOException ex) {
+            log.error("", ex);
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException ex) {
+                    log.error("", ex);
+                }
+            }
+        }
+        return contList;
+    }
+
+    private List<NicoContent> getNicoContents(Reader reader) throws FeedException {
+        List<SyndEntryImpl> list = null;
+        SyndFeedInput input = new SyndFeedInput();
+        SyndFeed feed = input.build(reader);
+
+        list = (List<SyndEntryImpl>) feed.getEntries();
+
+        List<NicoContent> contList;
+        if (list == null) {
+            contList = new ArrayList<NicoContent>();
+        } else {
+            contList = createContentsList(list);
+        }
+        return contList;
+    }
+
+    private List<NicoContent> createContentsList(List<SyndEntryImpl> list) {
+        class CallBack extends HTMLEditorKit.ParserCallback {
+
+            private boolean descFlag;
+            private String imageLink = new String();
+            private StringBuilder description = new StringBuilder();
+
+            @Override
+            public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
+                log.debug("--------<" + t.toString() + ">--------");
+                log.debug(a);
+                if (HTML.Tag.IMG.equals(t)) {
+                    imageLink = a.getAttribute(HTML.Attribute.SRC).toString();
+                }
+            }
+
+            @Override
+            public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
+                if (HTML.Tag.P.equals(t)) {
+                    if ("nico-description".equals(
+                            a.getAttribute(HTML.Attribute.CLASS).toString())) {
+                        descFlag = true;
+                    }
+                }
+                log.debug("--------<" + t.toString() + ">--------");
+                log.debug(a);
+            }
+
+            @Override
+            public void handleEndTag(HTML.Tag t, int pos) {
+                if (HTML.Tag.P.equals(t)) {
+                    descFlag = false;
+                }
+                log.debug("--------</" + t.toString() + ">--------");
+            }
+
+            @Override
+            public void handleText(char[] data, int pos) {
+                if (descFlag) {
+                    description.append(data);
+                }
+                log.debug("--------TEXT--------");
+                log.debug(data);
+            }
+
+            private void printAttributes(MutableAttributeSet a) {
+                Enumeration e = a.getAttributeNames();
+                while (e.hasMoreElements()) {
+                    Object key = e.nextElement();
+                    log.debug("---- " + key.toString() + " : " + a.getAttribute(key));
+                }
+            }
+
+            public String getImageLink() {
+                return imageLink;
+            }
+
+            public String getDescription() {
+                return description.toString();
+            }
+        }
+
+        List<NicoContent> contList = new ArrayList<NicoContent>();
+
+        for (SyndEntryImpl entry : list) {
+            NicoContent content = new NicoContent();
+
+            String title = entry.getTitle();
+            content.setTitle(title);
+            content.setPageLink(entry.getLink());
+
+            // サムネイル画像リンクと説明文の取得
+            CallBack callBack = new CallBack();
+            for (SyndContentImpl sc : (List<SyndContentImpl>) entry.getContents()) {
+                try {
+                    Reader reader = new StringReader(sc.getValue());
+                    new ParserDelegator().parse(reader, callBack, true);
+                } catch (IOException ex) {
+                    log.error("RSSの読み込み失敗: " + content.getTitle());
+                }
+            }
+
+// リストへ追加.
+            contList.add(content);
+        }
+        return contList;
+    }
+
+    /**
+     * FLVファイルのURLを取得する. ログインが必要.
+     * また, 実際にFLVファイルの実態をダウンロードするには
+     * 一度http://www.nicovideo.jp/watch/ビデオIDに一度アクセスする必要があることに
+     * 注意.
+     * (参考: http://yusukebe.com/tech/archives/20070803/124356.html)
+     * @param videoID ニコニコ動画のビデオID.
+     * @return FLVファイル実体があるURL.
+     * @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も.
+     */
+    public URL getFlvUrl(String videoID) throws IOException {
+        String accessUrl = GET_FLV_INFO + videoID;
+        if(videoID.startsWith("nm")){
+            accessUrl += "?as3=1";
+        }
+        log.debug("アクセス: " + accessUrl);
+        HttpGet get = new HttpGet(accessUrl);
+        String resultString;
+        BufferedReader reader = null;
+        try {
+            HttpResponse response = execute(get);
+            reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
+
+            String str;
+            StringBuilder strBuilder = new StringBuilder();
+            while ((str = reader.readLine()) != null) {
+                strBuilder.append(str);
+            }
+            resultString = strBuilder.toString();
+            response.getEntity().consumeContent();
+            log.debug(resultString);
+        } finally {
+            if (reader != null) {
+                reader.close();
+            }
+        }
+
+        String[] urls = resultString.split("&");
+        final String marker = "url=";
+        for (String url : urls) {
+            if (url.contains(marker)) {
+                String result = url.substring(marker.length());
+                result = URLDecoder.decode(result, "UTF-8");
+
+                return new URL(result);
+            }
+        }
+        throw new IOException("フォーマット仕様変更? ID: " + videoID + ", パラメータ:" + resultString);
+    }
+
+    /**
+     * ニコニコ動画から動画ファイルをダウンロードする.
+     * @param videoID smxxxx形式のビデオID.
+     * @param fileName ダウンロード後のファイル名. 拡張子は別途付与されるため不要.
+     * @param nowStatus ダウンロードしようとしている動画ファイルの, 現在のステータス.
+     * @param mp4ExtIsMp4 mp4ファイルの拡張子に.mp4を用いるか. falseの場合は.flvを付与する(過去のCraving Explorer互換用).
+     * @return この処理を行った後の, 対象ファイルのステータス.
+     * @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も.
+     */
+    public Status getFlvFile(String videoID, String fileName, Status nowStatus, boolean mp4ExtIsMp4) throws IOException,
+            URISyntaxException, HttpException, InterruptedException {
+        byte[] buffer = new byte[1024 * 32];
+        final String watchUrl = "http://www.nicovideo.jp/watch/" + videoID;
+        log.debug("アクセス: " + watchUrl);
+        HttpGet get = new HttpGet(watchUrl);
+        HttpResponse response = execute(get);
+        response.getEntity().consumeContent();
+
+        URL url = getFlvUrl(videoID);
+        if (nowStatus == Status.GET_LOW && url.toString().contains("low")) {
+            log.info("lowファイル取得済みのためスキップ" + videoID + ":" + fileName);
+            return nowStatus;
+        }
+
+        get = new HttpGet(url.toURI());
+        response = execute(get);
+        String contentType = response.getEntity().getContentType().getValue();
+        log.debug(contentType);
+        log.debug(fileName);
+        if ("text/plain".equals(contentType) || "text/html".equals(contentType)) {
+            log.error("取得できませんでした. サーバが混みあっている可能性があります: " + videoID + ":" + fileName);
+            response.getEntity().consumeContent();
+            return Status.GET_INFO;
+        }
+        String ext = Util.getExtention(contentType);
+        if (!mp4ExtIsMp4) {
+            if (ext.equals("mp4")) {
+                ext = "flv";
+            }
+        }
+
+        BufferedInputStream in = new BufferedInputStream(response.getEntity().getContent());
+
+        File file = new File(fileName + "." + ext);
+//        int postfix = 0;
+//        while (file.isFile()) {
+//            postfix++;
+//            file = new File(fileName + "(" + postfix + ")" + "." + ext);
+//        }
+        log.info("保存します: " + file.getPath());
+        FileOutputStream fos = new FileOutputStream(file);
+        BufferedOutputStream out = new BufferedOutputStream(fos);
+
+        int i;
+        while ((i = in.read(buffer)) != -1) {
+            out.write(buffer, 0, i);
+        }
+
+        response.getEntity().consumeContent();
+        out.close();
+        in.close();
+        if (url.toString().contains("low")) {
+            return Status.GET_LOW;
+        }
+        return Status.GET_FILE;
+    }
+
+    /**
+     * ニコニコ動画から動画ファイルをダウンロードする.
+     * @param videoID smxxxx形式のビデオID.
+     * @param fileName ダウンロード後のファイル名. 拡張子は別途付与されるため不要.
+     * @return この処理を行った後の, 対象ファイルのステータス.
+     * @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も.
+     */
+    public Status getFlvFile(String videoID, String fileName) throws IOException, URISyntaxException, HttpException,
+            InterruptedException {
+        return getFlvFile(videoID, fileName, Status.GET_INFO, true);
+    }
+
+    /**
+     * ニコニコ動画から動画ファイルをダウンロードする.
+     * ファイル名はビデオID名となる.
+     * @param videoID smxxxx形式のビデオID.
+     * @return この処理を行った後の, 対象ファイルのステータス.
+     * @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も.
+     */
+    public Status getFlvFile(String videoID) throws IOException, URISyntaxException, HttpException,
+            InterruptedException {
+        return getFlvFile(videoID, videoID, Status.GET_INFO, true);
+    }
+}
diff --git a/src/nicobrowser/entity/NicoContent.java b/src/nicobrowser/entity/NicoContent.java
new file mode 100644 (file)
index 0000000..df84377
--- /dev/null
@@ -0,0 +1,165 @@
+/*$Id$*/
+package nicobrowser.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+/**
+ * ニコニコ動画コンテンツ情報.
+ */
+@Entity
+public class NicoContent implements java.io.Serializable {
+
+    public enum Status {
+
+        GET_INFO, GET_LOW, GET_FILE
+    }
+    private static final long serialVersionUID = 1L;
+    private Long id;
+    private Long version;
+    private String nicoId;
+    private String pageLink;
+    private String title;
+    private String fileName;
+    private Status status = Status.GET_INFO;
+    private int failTimes;
+    private boolean convertedMp3;
+    private boolean convertedMp4;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    @Version
+    public Long getVersion() {
+        return version;
+    }
+
+    public void setVersion(Long version) {
+        this.version = version;
+    }
+
+    @Column(nullable = false)
+    public String getNicoId() {
+        return nicoId;
+    }
+
+    protected void setNicoId(String nicoId) {
+        this.nicoId = nicoId;
+    }
+
+    public String getPageLink() {
+        return pageLink;
+    }
+
+    public void setPageLink(String pageLink) {
+        this.pageLink = pageLink;
+        String[] elm = pageLink.split("/");
+        setNicoId(elm[elm.length - 1]);
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+        setFileName(title);
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    protected void setFileName(String fileName) {
+        if (fileName == null) {
+            this.fileName = null;
+            return;
+        }
+
+        StringBuilder str = new StringBuilder();
+        try {
+            for (int i = 0; i < fileName.length(); i++) {
+                char c = fileName.charAt(i);
+                if (c == '\\' || c == '/' || c == ':' || c == '*' || c == '?' ||
+                        c == '"' || c == '<' || c == '>' || c == '|' || c == '.') {
+                    c = '_';
+                }
+                str.append(c);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        this.fileName = str.toString();
+    }
+
+    @Column(nullable = false)
+    public Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+
+    public int getFailTimes() {
+        return failTimes;
+    }
+
+    public void setFailTimes(int failTimes) {
+        this.failTimes = failTimes;
+    }
+
+    @Column(nullable = false)
+    public boolean isConvertedMp3() {
+        return convertedMp3;
+    }
+
+    public void setConvertedMp3(boolean convertedMp3) {
+        this.convertedMp3 = convertedMp3;
+    }
+
+    @Column(nullable = false)
+    public boolean isConvertedMp4() {
+        return convertedMp4;
+    }
+
+    public void setConvertedMp4(boolean convertedMp4) {
+        this.convertedMp4 = convertedMp4;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        hash += (id != null ? id.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        // TODO: Warning - this method won't work in the case the id fields are not set
+        if (!(object instanceof NicoContent)) {
+            return false;
+        }
+        NicoContent other = (NicoContent) object;
+        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return new String(getTitle() + ": " + getPageLink());
+    }
+}
diff --git a/src/nicobrowser/main/Main.java b/src/nicobrowser/main/Main.java
new file mode 100644 (file)
index 0000000..0390aa5
--- /dev/null
@@ -0,0 +1,158 @@
+/*$Id$*/
+package nicobrowser.main;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+import nicobrowser.Config;
+import nicobrowser.Config.NicoFeed;
+import nicobrowser.NicoHttpClient;
+import nicobrowser.entity.NicoContent;
+import nicobrowser.entity.NicoContent.Status;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class Main {
+
+    private static Log log = LogFactory.getLog(Main.class);
+
+    public static void main(String[] args) throws IOException {
+        boolean res = Config.createNewConfigFiles();
+        if (res) {
+            System.out.println("コンフィグファイルを作成しました. 編集後, 再実行してください.");
+            return;
+        }
+
+        new Main().start();
+    }
+
+    public void start() {
+        log.info("program start");
+
+        Config config = Config.getInstance();
+        List<NicoContent> dailyList = new ArrayList<NicoContent>();
+        ArrayList<List<NicoContent>> myLists = new ArrayList<List<NicoContent>>();
+        NicoHttpClient instance = null;
+        try {
+            log.info("リストを取得します");
+            instance = NicoHttpClient.getInstance();
+            List<NicoFeed> feeds = config.getNicoFeeds();
+            for (NicoFeed f : feeds) {
+                List<NicoContent> list = instance.getContentsFromRss(f.getUrl());
+                int count = 0;
+                for (NicoContent l : list) {
+                    if (count >= f.getNumber()) {
+                        break;
+                    }
+                    dailyList.add(l);
+                    count++;
+                }
+            }
+            List<String> mylists = config.getDownLoadMyList();
+            for (String l : mylists) {
+                List<NicoContent> list = instance.loadMyList(l);
+                myLists.add(list);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return;
+        }
+
+        log.info("今回取得したデータを過去の取得データと比較します");
+
+        EntityManagerFactory factory;
+        EntityManager manager;
+
+        HashMap<String, String> map = new HashMap<String, String>();
+        map.put("toplink.jdbc.url", "jdbc:h2:" + config.getDbFile());
+        factory = Persistence.createEntityManagerFactory("NicoBrowserPU", map);
+        manager = factory.createEntityManager();
+
+        EntityTransaction transaction = manager.getTransaction();
+
+        transaction.begin();
+        try {
+            // ランキング上位のコンテンツ保存
+            int num = 0;
+            for (NicoContent c : dailyList) {
+                save(manager, c);
+                num++;
+            }
+
+            // マイリストに登録したコンテンツ保存
+            for (List<NicoContent> l : myLists) {
+                for (NicoContent c : l) {
+                    save(manager, c);
+                }
+            }
+
+            transaction.commit();
+
+            Query query = manager.createQuery("SELECT cont FROM NicoContent AS cont " + "WHERE ?1 <> cont.status").
+                    setParameter(1, NicoContent.Status.GET_FILE);
+            List<NicoContent> results = query.getResultList();
+            instance.login(config.getNicoMail(), config.getNicoPassword());
+            Date prevDate = null;
+            for (NicoContent c : results) {
+                if (c.getFailTimes() > config.getMaxRetry() + 1) {
+                    continue;
+                }
+                if (prevDate != null) {
+                    Date nowDate = Calendar.getInstance().getTime();
+                    long sleep = nowDate.getTime() - prevDate.getTime();
+                    sleep = 5000 - sleep;
+                    if (sleep > 0) {
+                        log.info("" + sleep + "ms sleep");
+                        Thread.sleep(sleep);
+                    }
+                }
+                prevDate = Calendar.getInstance().getTime();
+                File saveLocation = new File(config.getSrcSaveDir(), c.getFileName());
+                log.info("ファイルを取得します: " + c.getNicoId() + " " + c.getTitle());
+                Status status;
+                try {
+                    status = instance.getFlvFile(c.getNicoId(),
+                            saveLocation.getCanonicalPath(), c.getStatus(),
+                            true);
+                    c.setStatus(status);
+                    if (status == Status.GET_INFO) {
+                        c.setFailTimes(c.getFailTimes() + 1);
+                    }
+                } catch (Exception ex) {
+                    c.setFailTimes(c.getFailTimes() + 1);
+                    log.error("ファイル取得に失敗しました。" + c.getNicoId() + ", 通算失敗回数: " + c.getFailTimes(), ex);
+                }
+                transaction.begin();
+                manager.persist(c);
+                transaction.commit();
+                log.info("完了しました");
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            transaction.rollback();
+        } finally {
+            manager.close();
+            factory.close();
+        }
+
+    }
+
+    private void save(EntityManager manager, NicoContent c) {
+        Query query = manager.createQuery("SELECT cont FROM NicoContent AS cont " + "WHERE ?1 = cont.nicoId").
+                setParameter(1, c.getNicoId());
+        List<NicoContent> resList = query.getResultList();
+        if (resList.isEmpty()) {
+            log.info("NEW! " + c.getNicoId() + " : " + c.getFileName());
+            manager.persist(c);
+        }
+    }
+}
diff --git a/src/nicobrowser/util/Result.java b/src/nicobrowser/util/Result.java
new file mode 100644 (file)
index 0000000..c94a0de
--- /dev/null
@@ -0,0 +1,26 @@
+/* $Id$ */
+package nicobrowser.util;
+
+public class Result {
+
+    private final String id;
+    private final String name;
+
+    public Result(String id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return id + ", " + name;
+    }
+}
diff --git a/src/nicobrowser/util/ResultParse.groovy b/src/nicobrowser/util/ResultParse.groovy
new file mode 100644 (file)
index 0000000..5ec1365
--- /dev/null
@@ -0,0 +1,27 @@
+/* $Id$ */
+
+package nicobrowser.util
+import org.cyberneko.html.parsers.SAXParser
+
+
+class ResultParse {
+    List<nicobrowser.util.Result> parse(InputStream is){
+        def html = new XmlSlurper(new SAXParser()).parse(is)
+        def res = html.'**'.findAll{it.attributes()['class'] == 'video'}
+
+        List<nicobrowser.util.Result> list = []
+        res.each{list += new nicobrowser.util.Result(
+                it.attributes()['href'].replaceAll('watch/','').toString(),
+                it.toString())}
+
+        return list
+    }
+
+    String getNextPage(InputStream is){
+        def html = new XmlSlurper(new SAXParser()).parse(is)
+        def res = html.'**'.find{it.attributes()['class'] == 'nextpage'}
+        if(res==null) return null
+        return res.attributes()['href']
+    }
+}
+
diff --git a/src/nicobrowser/util/Util.java b/src/nicobrowser/util/Util.java
new file mode 100644 (file)
index 0000000..3881fc8
--- /dev/null
@@ -0,0 +1,29 @@
+/*$Id$*/
+package nicobrowser.util;
+
+import java.io.InputStream;
+import java.util.List;
+
+public class Util {
+
+    static ResultParse rp = new ResultParse();
+
+    public static String getExtention(String contentType) {
+        if ("video/flv".equals(contentType) || "video/x-flv".equals(contentType)) {
+            return "flv";
+        } else if ("video/mp4".equals(contentType)) {
+            return "mp4";
+        } else if ("application/x-shockwave-flash".equals(contentType)) {
+            return "swf";
+        }
+        return contentType.split("/")[1];
+    }
+
+    public static List<Result> parseSerchResult(InputStream is) {
+        return rp.parse(is);
+    }
+
+    public static String getNextPage(InputStream is) {
+        return rp.getNextPage(is);
+    }
+}
diff --git a/src/resources/feedurl.txt b/src/resources/feedurl.txt
new file mode 100644 (file)
index 0000000..70c38b9
--- /dev/null
@@ -0,0 +1,24 @@
+http://www.nicovideo.jp/ranking/mylist/daily/all?rss=atom, 20\r
+\r
+\r
+# URL, 抽出数\r
+# というフォーマットで記載する.\r
+# カンマの後のスペースはあっても無くても可.\r
+# 抽出数は100以内.\r
+# 行頭が#の行はコメント扱い.\r
+\r
+\r
+### 記述例 ###\r
+### フィードのURLについては http://nicowiki.com/?RSSフィード一覧 などを参照のこと.\r
+\r
+# 新着投稿動画\r
+# http://www.nicovideo.jp/newarrival?rss=2.0, 100\r
+\r
+# 新着動画(カテゴリ:科学)\r
+# http://www.nicovideo.jp/tag/科学?sort=f&rss=2.0, 3\r
+\r
+# 新着コメント動画\r
+# http://www.nicovideo.jp/recent?rss=2.0,10\r
+\r
+# 自然のマイリストランキング(月間)\r
+# http://www.nicovideo.jp/ranking/mylist/monthly/nature?rss=2.0,10\r
diff --git a/test/nicobrowser/ConfigTest.java b/test/nicobrowser/ConfigTest.java
new file mode 100644 (file)
index 0000000..9cdbf3e
--- /dev/null
@@ -0,0 +1,240 @@
+/*$Id$*/
+package nicobrowser;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.List;
+import nicobrowser.Config.NicoFeed;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class ConfigTest {
+
+    private static File APP_HOME;
+    private static File CONFIG_FILE;
+    private static File FEEDURL_FILE;
+    private final File TEST_PROPERTY_FILE;
+    private final File TEST_FEED_FILE;
+
+    public ConfigTest() {
+        TEST_PROPERTY_FILE = new File("test/testdata/nicobrowser.properties");
+        TEST_FEED_FILE = new File("test/testdata/feedurl.txt");
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
+        try {
+            Field f;
+            f = Config.class.getDeclaredField("APP_HOME");
+            f.setAccessible(true);
+            APP_HOME = (File) f.get(null);
+
+            f = Config.class.getDeclaredField("CONFIG_FILE");
+            f.setAccessible(true);
+            CONFIG_FILE = (File) f.get(null);
+
+            f = Config.class.getDeclaredField("FEEDURL_FILE");
+            f.setAccessible(true);
+            FEEDURL_FILE = (File) f.get(null);
+
+            if (APP_HOME.exists()) {
+                String message = "ディレクトリを削除/移動してから再実行してください: " + APP_HOME;
+                System.err.println(message);
+                throw new Error(message);
+            }
+        } catch (Throwable th) {
+            throw new Error(th);
+        }
+    }
+
+    @After
+    public void tearDown() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
+        // コンフィグディレクトリを削除
+        FileUtils.deleteQuietly(APP_HOME);
+
+        // コンフィグインスタンスを削除.
+        Field f = Config.class.getDeclaredField("instance");
+        f.setAccessible(true);
+        f.set(null, null);
+    }
+
+    /**
+     * Test of getInstance method, of class Config.
+     */
+    @Test
+    public void testGetInstance() throws IOException {
+        System.out.println("getInstance");
+
+        try {
+            Config.getInstance();
+            fail("コンフィグファイル未作成の場合は例外発生");
+        } catch (Exception ex) {
+        }
+
+        Config.createNewConfigFiles();
+        assertNotNull(Config.getInstance());
+
+    }
+
+    /**
+     * Test of createNewConfigFiles method, of class Config.
+     */
+    @Test
+    public void testCreateNewConfigFiles() throws Exception {
+        System.out.println("createNewConfigFiles");
+        boolean result;
+
+        result = Config.createNewConfigFiles();
+        assertTrue("コンフィグが無いので新規作成される", result);
+        assertTrue(CONFIG_FILE.isFile());
+        assertTrue(FEEDURL_FILE.isFile());
+
+        result = Config.createNewConfigFiles();
+        assertFalse("作成済みなので作成されない", result);
+
+        CONFIG_FILE.delete();
+        assertFalse(CONFIG_FILE.exists());
+        result = Config.createNewConfigFiles();
+        assertTrue("コンフィグファイルだけ無くてもtrue", result);
+        assertTrue(CONFIG_FILE.isFile());
+
+        FEEDURL_FILE.delete();
+        assertFalse(FEEDURL_FILE.exists());
+        result = Config.createNewConfigFiles();
+        assertTrue("フィードファイルだけ無くてもtrue", result);
+        assertTrue(FEEDURL_FILE.isFile());
+    }
+
+    /**
+     * 初期作成コンフィグの妥当性をテストする.
+     */
+    @Test
+    public void testConfigInitialMake() throws IOException {
+        System.out.println("testConfigInitialMake");
+        Config.createNewConfigFiles();
+
+        Config conf = Config.getInstance();
+        assertEquals(new File(APP_HOME, "db/nicodb").getAbsolutePath(), conf.getDbFile());
+        assertEquals(new File(APP_HOME, "flv").getAbsolutePath(), conf.getSrcSaveDir());
+    }
+
+    /**
+     * コンフィグ初期生成を行うためのヘルパーメソッド.
+     */
+    private void initConfig() {
+        try {
+            Config.createNewConfigFiles();
+            FileUtils.copyFile(TEST_PROPERTY_FILE, CONFIG_FILE);
+            FileUtils.copyFile(TEST_FEED_FILE, FEEDURL_FILE);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Test of getNicoMail method, of class Config.
+     */
+    @Test
+    public void testGetNicoMail() {
+        System.out.println("getNicoMail");
+        initConfig();
+
+        String result = Config.getInstance().getNicoMail();
+        assertEquals("my@mail.address", result);
+    }
+
+    /**
+     * Test of getNicoPassword method, of class Config.
+     */
+    @Test
+    public void testGetNicoPassword() {
+        System.out.println("getNicoPassword");
+        initConfig();
+
+        String result = Config.getInstance().getNicoPassword();
+        assertEquals("my_password", result);
+    }
+
+    /**
+     * Test of getDbFile method, of class Config.
+     */
+    @Test
+    public void testGetDbFile() {
+        System.out.println("getDbFile");
+        initConfig();
+
+        String result = Config.getInstance().getDbFile();
+        assertEquals("C:\\Documents and Settings\\test\\.nicobrowser\\db\\nicodb", result);
+    }
+
+    /**
+     * Test of getSrcSaveDir method, of class Config.
+     */
+    @Test
+    public void testGetSrcSaveDir() {
+        System.out.println("getSrcSaveDir");
+        initConfig();
+
+        String result = Config.getInstance().getSrcSaveDir();
+        assertEquals("d:\\test", result);
+    }
+
+    /**
+     * Test of getEncoding method, of class Config.
+     */
+    @Test
+    public void testGetEncoding() {
+        System.out.println("getEncoding");
+        initConfig();
+
+        String result = Config.getInstance().getEncoding();
+        assertEquals("UTF-8", result);
+    }
+
+    /**
+     * Test of getMaxRetry method, of class Config.
+     */
+    @Test
+    public void testGetMaxRetry() {
+        System.out.println("getMaxRetry");
+        initConfig();
+
+        int result = Config.getInstance().getMaxRetry();
+        assertEquals(3, result);
+    }
+
+    /**
+     * Test of getDownLoadMyList method, of class Config.
+     */
+    @Test
+    public void testGetDownLoadMyList() {
+        System.out.println("getDownLoadMyList");
+        initConfig();
+
+        List<String> result = Config.getInstance().getDownLoadMyList();
+        List expected = Arrays.asList(new String[]{"100", "200", "300"});
+        assertEquals(expected, result);
+    }
+
+    @Test
+    public void testGetFeeds() {
+        System.out.println("testGetFeeds");
+        initConfig();
+
+        List<Config.NicoFeed> feeds = Config.getInstance().getNicoFeeds();
+        assertEquals(5, feeds.size());
+
+        NicoFeed feed = feeds.get(2);
+        assertEquals("http://www.nicovideo.jp/tag/科学?sort=f&rss=2.0", feed.getUrl());
+        assertEquals(3, feed.getNumber());
+
+        for (Config.NicoFeed nf : feeds) {
+            System.out.println(nf);
+        }
+    }
+}
diff --git a/test/nicobrowser/NicoHttpClientRssTest.java b/test/nicobrowser/NicoHttpClientRssTest.java
new file mode 100644 (file)
index 0000000..b331b3f
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package nicobrowser;
+
+import java.net.MalformedURLException;
+import java.util.List;
+import nicobrowser.entity.NicoContent;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Test;
+
+/**
+ *
+ * @author yuki
+ */
+public class NicoHttpClientRssTest {
+
+    static final Log log = LogFactory.getLog(NicoHttpClientRssTest.class);
+    final NicoHttpClient client = NicoHttpClient.getInstance();
+
+    @Test
+    public void testNewArraivalCategory() throws MalformedURLException {
+        log.info("testNewArraivalCategory");
+
+        String page = "http://www.nicovideo.jp/tag/科学?sort=f&rss=2.0";
+        List<NicoContent> contents = client.getContentsFromRss(page);
+        for (NicoContent c : contents) {
+            System.out.println(c.getNicoId() + ": " + c.getTitle());
+        }
+    }
+
+    @Test
+    public void testNewArraival() {
+        log.info("testNewArraival");
+
+        String page = "http://www.nicovideo.jp/newarrival?rss=2.0";
+        List<NicoContent> contents = client.getContentsFromRss(page);
+        for (NicoContent c : contents) {
+            System.out.println(c.getNicoId() + ": " + c.getTitle());
+        }
+    }
+
+    @Test
+    public void testNewArraivalCommentMovie() {
+        log.info("testNewArraivalCommentMovie");
+
+        String page = "http://www.nicovideo.jp/recent?rss=2.0";
+        List<NicoContent> contents = client.getContentsFromRss(page);
+        for (NicoContent c : contents) {
+            System.out.println(c.getNicoId() + ": " + c.getTitle());
+        }
+    }
+
+    @Test
+    public void testRanking() {
+        log.info("testRanking");
+
+        String page = "http://www.nicovideo.jp/ranking/mylist/daily/science?rss=2.0";
+        List<NicoContent> contents = client.getContentsFromRss(page);
+        for (NicoContent c : contents) {
+            System.out.println(c.getNicoId() + ": " + c.getTitle());
+        }
+    }
+}
diff --git a/test/nicobrowser/NicoHttpClientTest.java b/test/nicobrowser/NicoHttpClientTest.java
new file mode 100644 (file)
index 0000000..6cf4fca
--- /dev/null
@@ -0,0 +1,259 @@
+/*$Id$*/
+package nicobrowser;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import nicobrowser.entity.NicoContent;
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+import nicobrowser.entity.NicoContent.Status;
+import org.apache.http.HttpException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author yuki
+ */
+public class NicoHttpClientTest {
+
+    static final String OK_MAIL = "niconico.senyou@live.jp";
+    static final String OK_PASS = "piyopiyo";
+    static final String OK_LIST_NO = "3693055";
+
+    public NicoHttpClientTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getInstance method, of class NicoHttpClient.
+     */
+    @Test
+    public void getInstance() {
+        System.out.println("getInstance");
+        NicoHttpClient result = NicoHttpClient.getInstance();
+        assertNotNull(result);
+
+        // 2回目でも同じインスタンスが返る.
+        NicoHttpClient instance = NicoHttpClient.getInstance();
+        assertEquals(result, instance);
+    }
+
+    /**
+     * Test of login method, of class NicoHttpClient.
+     */
+    @Test
+    public void login() throws HttpException, URISyntaxException, InterruptedException {
+        System.out.println("login");
+        NicoHttpClient instance = NicoHttpClient.getInstance();
+
+        // ログイン失敗ケース
+        instance.logout();
+        String mail = "test@example.com";
+        String password = "xxxx";
+        boolean result = instance.login(mail, password);
+        assertEquals(false, result);
+
+        // ログイン成功ケース
+        instance.logout();
+        mail = OK_MAIL;
+        password = OK_PASS;
+        result = instance.login(mail, password);
+        assertEquals(true, result);
+    }
+
+    @Test
+    public void logout() throws URISyntaxException, HttpException, InterruptedException {
+        System.out.println("logout");
+
+        boolean result;
+        result = NicoHttpClient.getInstance().logout();
+        assertEquals(true, result);
+
+        result = NicoHttpClient.getInstance().logout();
+        assertEquals(true, result);
+    }
+
+    @Test
+    public void loadMyList() throws URISyntaxException, HttpException, InterruptedException {
+        System.out.println("loadMyList");
+
+        NicoHttpClient instance = NicoHttpClient.getInstance();
+        List list;
+
+        list = instance.loadMyList(OK_LIST_NO);
+        assertNotNull(list);
+        assertNotSame(0, list.size());
+//        for (Object o : list) {
+//            System.out.println(o.toString());
+//        }
+
+        list = instance.loadMyList("XXXX");
+        assertNotNull(list);
+        assertSame(0, list.size());
+    }
+
+    @Test
+    public void loadMyListDaily() throws URISyntaxException, HttpException, InterruptedException {
+        System.out.println("loadMyListDaily");
+        NicoHttpClient instance = NicoHttpClient.getInstance();
+        List<NicoContent> list = instance.loadMyListDaily();
+        assertNotNull(list);
+        assertNotSame(0, list.size());
+//        System.out.println(list.size());
+//        for (Object o : list) {
+//            System.out.println(o.toString());
+//        }
+
+        EntityManagerFactory factory;
+        EntityManager manager;
+
+        factory = Persistence.createEntityManagerFactory("NicoBrowserPU");
+        manager = factory.createEntityManager();
+
+        EntityTransaction transaction = manager.getTransaction();
+
+        transaction.begin();
+        try {
+            for (NicoContent c : list) {
+                manager.persist(c);
+            }
+
+            transaction.commit();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            transaction.rollback();
+        } finally {
+            manager.close();
+            factory.close();
+        }
+
+    }
+
+    @Test
+    public void getFlvUrl() throws URISyntaxException, HttpException, InterruptedException, IOException {
+        System.out.println("getFlv");
+
+        NicoHttpClient instance = NicoHttpClient.getInstance();
+        instance.login(OK_MAIL, OK_PASS);
+        try {
+            URL str = instance.getFlvUrl("sm1359820");
+            System.out.println(str);
+        } catch (IOException ex) {
+            fail();
+            Logger.getLogger(NicoHttpClientTest.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+    }
+
+    @Test
+    public void downLoad() throws URISyntaxException, IOException, HttpException, InterruptedException {
+        System.out.println("downLoad");
+
+        NicoHttpClient instance = NicoHttpClient.getInstance();
+        instance.login(OK_MAIL, OK_PASS);
+
+        try {
+            instance.getFlvFile("sm183036", "sm183036", NicoContent.Status.GET_INFO, false);
+        } catch (IOException ex) {
+            Logger.getLogger(NicoHttpClientTest.class.getName()).log(Level.SEVERE, null, ex);
+            fail();
+        }
+    }
+
+    /**
+     * Test of getFlvFile method, of class NicoHttpClient.
+     */
+    @Test
+    public void getFlvFile_String() throws HttpException, InterruptedException, URISyntaxException {
+        System.out.println("getFlvFile");
+        String videoID = "sm1097445";
+        NicoHttpClient instance = NicoHttpClient.getInstance();
+        instance.login(OK_MAIL, OK_PASS);
+        Status result;
+        try {
+            result = instance.getFlvFile(videoID);
+            System.out.println(result);
+            assertNotSame(Status.GET_INFO, result);
+        } catch (Exception ex) {
+            Logger.getLogger(NicoHttpClientTest.class.getName()).log(Level.SEVERE, null, ex);
+            fail();
+        }
+
+        // 権限が無い動画?の取得
+        // http://www.nicovideo.jp/watch/1231042440
+        // 【亡き王女の為のセプテット・ツェペシュの幼き末裔】Priere -プリエール-
+        try {
+            result = instance.getFlvFile("1231042440");
+            fail("権限が無い動画を取得しようとした場合は例外が送出される");
+        } catch (IOException ex) {
+            Logger.getLogger(NicoHttpClientTest.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    @Test
+    public void search() throws URISyntaxException, InterruptedException, HttpException, IOException {
+        System.out.println("search");
+        NicoHttpClient instance = NicoHttpClient.getInstance();
+        instance.login(OK_MAIL, OK_PASS);
+
+        List<NicoContent> conts = instance.search("初音ミク");
+        System.out.println("検索結果件数: " + conts.size());
+        assertTrue(conts.size() > 0);
+        assertTrue(conts.size() > 100);
+
+    }
+
+    @Test
+    public void loadMyMovie() throws URISyntaxException, InterruptedException, HttpException, IOException {
+        System.out.println("search");
+        NicoHttpClient instance = NicoHttpClient.getInstance();
+        instance.login(OK_MAIL, OK_PASS);
+
+        NicoContent cont;
+
+        // 通常の動画
+        cont = instance.loadMyMovie("sm9");
+        assertNotNull(cont);
+        assertEquals("sm9", cont.getNicoId());
+
+        // チャンネル動画はnull(statusがfailなので)
+        cont = instance.loadMyMovie("1228201771");
+        assertNull(cont);
+
+        // 削除済み
+        cont = instance.loadMyMovie("sm1");
+        assertNull(cont);
+
+        // 存在しない
+        cont = instance.loadMyMovie("xxx");
+        assertNull(cont);
+
+
+    }
+}
diff --git a/test/nicobrowser/util/UtilTest.java b/test/nicobrowser/util/UtilTest.java
new file mode 100644 (file)
index 0000000..e69f56e
--- /dev/null
@@ -0,0 +1,89 @@
+/* $Id$ */
+package nicobrowser.util;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+import nicobrowser.NicoHttpClient;
+import nicobrowser.entity.NicoContent;
+import nicobrowser.util.Result;
+import org.apache.http.HttpException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class UtilTest {
+
+    static final String OK_MAIL = "niconico.senyou@live.jp";
+    static final String OK_PASS = "piyopiyo";
+
+    public UtilTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getExtention method, of class Util.
+     */
+    @Test
+    public void testGetExtention() {
+        System.out.println("getExtention");
+        String result;
+        result = Util.getExtention("video/x-flv");
+        assertEquals("flv", result);
+
+        result = Util.getExtention("video/flv");
+        assertEquals("flv", result);
+
+        result = Util.getExtention("video/mp4");
+        assertEquals("mp4", result);
+
+        result = Util.getExtention("application/x-shockwave-flash");
+        assertEquals("swf", result);
+
+        result = Util.getExtention("");
+        assertEquals("txt", result);
+    }
+
+    /**
+     * Test of getNextPage method, of class Util.
+     */
+    @Test
+    public void testGetNextPage() throws FileNotFoundException, MalformedURLException {
+        System.out.println("getNextPage");
+
+        InputStream is;
+        String result;
+
+        // 次のページがある場合
+        is = new FileInputStream("test_data/momiji.html");
+        result = Util.getNextPage(is);
+        assertEquals("http://www.nicovideo.jp/search/%E7%B4%85%E8%91%89?page=2", result);
+
+        // 最終ページ
+        is = new FileInputStream("test_data/momiji_lastpage.html");
+        result = Util.getNextPage(is);
+        assertNull(result);
+    }
+}
\ No newline at end of file
diff --git a/test/testdata/feedurl.txt b/test/testdata/feedurl.txt
new file mode 100644 (file)
index 0000000..2c65d1f
--- /dev/null
@@ -0,0 +1,24 @@
+http://www.nicovideo.jp/ranking/mylist/daily/all?rss=atom, 20\r
+\r
+\r
+# URL, 抽出数\r
+# というフォーマットで記載する.\r
+# カンマの後のスペースはあっても無くても可.\r
+# 抽出数は100以内.\r
+# 行頭が#の行はコメント扱い.\r
+\r
+\r
+### 記述例 ###\r
+### フィードのURLについては http://nicowiki.com/?RSSフィード一覧 などを参照のこと.\r
+\r
+# 新着投稿動画\r
+http://www.nicovideo.jp/newarrival?rss=2.0, 1\r
+\r
+# 新着動画(カテゴリ:科学)\r
+http://www.nicovideo.jp/tag/科学?sort=f&rss=2.0, 3\r
+\r
+# 新着コメント動画\r
+http://www.nicovideo.jp/recent?rss=2.0, 5\r
+\r
+# 自然のマイリストランキング(月間)\r
+http://www.nicovideo.jp/ranking/mylist/monthly/nature?rss=2.0,10\r
diff --git a/test/testdata/nicobrowser.properties b/test/testdata/nicobrowser.properties
new file mode 100644 (file)
index 0000000..10d331d
--- /dev/null
@@ -0,0 +1,7 @@
+path.db=C:\\Documents and Settings\\test\\.nicobrowser\\db\r
+path.savefile=d:\\test\r
+encoding=UTF-8\r
+nicovideo.mail=my@mail.address\r
+nicovideo.password=my_password\r
+download.retry=3\r
+download.mylist=100, 200 ,300  \r