home ホーム search 検索 -  login ログイン  | help ヘルプ

find 検索

191 - 200 / 1320    [|<]  [|<]  [<]  11  12  13  14  15  16  17  18  19  20   [>]  [>|][>|]
タイトル/名前 更新者 更新日
日記/2014/04/26/VirtualBox 上の CentOS6 の GNOME で CapsLock がおかしい件が解決 msakamoto-sf 2014-04-26 19:48:27
日記/2014/04/26/業務系文書の自動生成についての予備調査(OIpenXML, OpenDocument, OpenOffice.org, LibreOffice) msakamoto-sf 2014-04-26 19:03:00
技術/OSSライセンス/勉強メモ msakamoto-sf 2014-04-26 18:18:24
日記/2014/04/20/牡蠣料理のメモ msakamoto-sf 2014-04-20 16:53:33
日記/2014/04/20/CheckstyleとかNetBeansとEclipseのフォーマットメモ msakamoto-sf 2014-04-20 14:57:34
日記/2014/04/14/flywayとApache DbUtilsの練習メモ msakamoto-sf 2014-04-14 03:09:36
日記/2014/04/13/ScheduledExecutorServiceの練習メモ msakamoto-sf 2014-04-13 14:23:40
日記/2014/04/07/Javaのconcurrentパッケージ勉強中・・・ msakamoto-sf 2014-04-07 00:08:11
Java/JSON Schema Validation msakamoto-sf 2014-02-24 01:43:41
日記/2014/02/18/JDKのCookie管理機能 msakamoto-sf 2014-02-18 23:46:59
ソート項目 / ソート順     1ページ 件ずつ表示

日記/2014/04/26/VirtualBox 上の CentOS6 の GNOME で CapsLock がおかしい件が解決  

所有者: msakamoto-sf    作成日: 2014-04-26 19:30:03
カテゴリ: Linux 

技術/Linux/CentOS/VirtualBoxにインストールメモ(CentOS6, 2014-01版) でちらと書いた、CapsLockがおかしい件、色々調べたけどGNOMEの"Keyboard Layout Options"で"Caps Lock key behaviour"を "Default" から "Caps Lock toggles normal capitalization of alphabetic characters" にしたら直った。・・・何が悪かったのか・・・。


現象としてはこんな感じだったのです。

環境:

物理マシン : Win7 Pro SP1 日本語版 64bit版
キーボード : USB接続 FILCO Majestictouch テンキーレス
※特に物理マシン側でキーのmappingは変更してない
VirtualBox : 4.3.6
VM : CentOS 6.5 x64版, GNOME

まず、runlevel=3のコマンドラインコンソールモードであればCapsLockについて全く問題はありませんでした。

runlevel=5で、GNOMEのX環境になると、以下の様な謎の挙動になりました。

  1. (物理マシンはWinなので) Shift + CapsLock でCapsLockをONにする。
  2. 物理マシン上では大文字が入力できる。
  3. GNOME上では、小文字しか入力できないまま。
  4. もう一度Shift + CapsLock -> 物理マシン上ではCapsLockがOFFになり、小文字入力に戻る。
  5. GNOME側では、なぜかこれで大文字入力になる。
  6. 以降、物理マシンとVM上のGNOMEとで、CapsLockのON/OFFが逆転する。
  7. 戻すには、CapsLock切り替えを1秒未満のうちに素早くON/OFFする。すると、VM側でCapsLockの取りこぼしがあるのか、1つスキップして結果として物理マシン側とON/OFFが同期する。

また、GNOME上でも、CapsLockの切り替え後、1秒ほど待ってから入力を開始すればちゃんとCapsLockのON/OFFが反映されました。
取りこぼし(?)らしき現象が発生するのは、CapsLock切り替え後1秒未満の間に続けて入力を行う場合です。

一応、CapsLock切り替えで1秒以上待ってから入力を開始すれば問題は発生しないのですが、プログラミングをする上ではCapsLock切り替えでいちいち1秒以上またされるのはキツイです。

で、なかなか問題の切り分けが出来なかったのです。最初はVirtualBox側の問題かと思ったのですが、それらしき記事も見つからず、なによりrunlevel=3のCUIモードであれば全く問題は発生していなかったので、原因はX WindowsかGNOME側にアリそうでした。
試しにキーボードレイアウト設定でCapsLockのモード設定があったので、"Default"になってたのを、いくつか設定を切り替えてみたら、"Caps Lock toggles normal capitalization of alphabetic characters" で正常になった次第です。
他にもCapsLockの切り替えモードが色々用意されてるんですが、全部は試せておらず、とりあえずいくつか試してみて、通常使用時と同等で問題が解決できたのがたまたま上記の設定でした。

ちなみに、VMware Fusion でCapsLockの取りこぼしがある、というVMwareのKBが見つかったのですが、VirtualBoxですし、runlevel=3のCUIなら問題は発生しないので、違うようでした。


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2014-04-26 19:48:27
md5:06132940a3ae151791bd517069d6d83f
sha1:c3b5bb3021d94cc2e10e0876df106b4bc046c6f3

日記/2014/04/26/業務系文書の自動生成についての予備調査(OIpenXML, OpenDocument, OpenOffice.org, LibreOffice)  

所有者: msakamoto-sf    作成日: 2014-04-26 19:02:26
カテゴリ: Java 

いわゆるワード文書やスプレッドシートを、ソフトウェアから自動生成するにはどんな方法があるかの調査メモです。
Javaから生成するのを念頭に置いてます。
そんなに突っ込んで調べてるわけではなくて、適当にググった結果の上位3-5くらいのURLを漁っただけの、浅い内容です。

Office Open XML フォーマット(MS-Officeの ".docx", ".xlsx")

Microsoft社提供のSDK:

JavaからOffice文書を生成するので有名なApachePOI関連:

  • Apache POI - the Java API for Microsoft Documents
    • http://poi.apache.org/
    • もともと OpenXML4J として開発されていたのが、2008年にPOIに寄贈され、利用できるようになった。
  • 最新POIでOffice Open XML形式のExcelファイルを操作:CodeZine(コードジン)

OpenDocumentフォーマット(OpenOffice.org, LibreOffice)

  • OpenDocument Format for developers
    • http://www.opendocumentformat.org/developers/
      • 言語ごとに、ODFを生成するライブラリが紹介されている。
      • ただし、サイトが消失している(lpod-project.org)ものがあり、最新情報とはいえない。

OpenOffice.org と LibreOffice の両方で、マクロとして、あるいは外部プログラムからドキュメントを操作するためのAPIが公開されており、最近だとこちらを使ったほうが良いかもしれない。
どちらも、OpenOffice.org で開発されている "UNO" (Universal Netowrk Objects) という、RPCを複数言語でBINDしたようなアーキテクチャの上でAPIを公開しているため、JavaやPython、.NETなどから利用できるようになっている。

OpenOffice.orgでのAPIとUNO関連資料:

LibreOfficeでのAPIとUNO関連資料:

OpenOffice.orgはApacheライセンスですが、LibreOfficeはGPLv3という点に注意が必要かもしれません。

ちなみに、Webアプリなどから非同期でマルチスレッドで呼び出すような用途だとどうなるんだろう・・・と、"uno multithread"でぐぐったらこんなのが見つかりました。対応してるのか、してないのか、ちょっとまだ調べきれてないです。


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2014-04-26 19:03:00
md5:396bceac4a5855613d147b0ba24ff479
sha1:790aa9199e7587fdbf15fbbbeb232e7fa5953d0f

技術/OSSライセンス/勉強メモ  

所有者: msakamoto-sf    作成日: 2014-04-25 08:55:20
カテゴリ: License 

OSSライセンスについて勉強したメモです。
最終的には日米間での著作権法の違いにまで話が及んでしまう「解釈」の問題になってしまう部分が多いので、特にGPLについてはそのソフトウェアの開発元に、「これこれこういう利用形態で使いたいんだけどライセンスどうなる?」と尋ねるのが一番確実なようです。

日本語での分かりやすい資料

IPAによる調査資料:

  • 『ビジネスユースにおけるオープンソースソフトウェアの法的リスクに関する調査調査報告書[平成 17 年 2 月]』独立行政法人情報処理推進機構 (以降、本記事では [BOLR2014] と表記)
    • http://www.ipa.go.jp/about/jigyoseika/04fy-pro/open/2004-741d.pdf
      • 著作権の話や、GPLが「契約」なのか「ライセンス」なのか、それにより日米でどういう法的解釈の違いが生じるのかなど、OSSのライセンスについて丹念に、かつ分かりやすく解説されている。
      • 後述のOSSモデルカリキュラムの「法務分野に関する知識」でも参考資料として使われているので、信頼性は高いと思われる。
  • IPA 独立行政法人 情報処理推進機構:OSSライセンス関連情報
  • OSSライセンスの比較、利用動向および係争に関する調査
    • http://ossipedia.ipa.go.jp/doc/203/
    • 係争に関する調査もさることながら、比較調査の内容も以下の点が他の資料と比べ、異彩を放っている。調査に相当の労力が注ぎ込まれたであろう、力作。
      • それぞれのライセンスの作成に関わったメンバーにインタビューした内容が書かれているため、そのライセンスが作られた意図や他の類似ライセンスと異なるポイントが明確になっている。
      • 原型となるライセンスから、そのバリエーションでどこが変更されたか、という順序で紹介されている。類似したライセンスの作者たちが、既存のライセンスに対して何を不満に思い、どういう意図で新しいライセンスを作るに至ったのかが分かる紹介順になっている。

OSC2009でのNECの人の発表資料:

  • オープンソースをライセンス的に正しくつかうための11のチェックポイント - builder by ZDNet Japan

OSSライセンスについて精力的に啓蒙活動を行われている可知豊氏のコンテンツ:

各種ライセンス文書

その他ライセンス毎の日本語訳やWikiページ、FAQ

ざっくりとした分類

よく見かけるライセンスについて:

  • コピーレフト性が無いか、スゴイ弱い : BSD/MIT/Apache Software License
  • コピーレフト性はあるが、他のライセンスと組み合わせることもできる : MPL/EPL/CDDL/LGPL
  • コピーレフト性が強く、他のライセンスとの組み合わせに注意が必要 : GPL

※CDDL(Common Developement and Distribution License)は、GlassFish系のOSSで見かけた。

「派生物」について

ヒントとなる単語:
「派生物 (Derived Work, Derivative Works)(CDDLでは「拡大制作物」"Larger Work")」・「リンク」・OOPでの継承やインターフェイスの実装

OSSを使って商用製品を開発する、あるいは、使っているOSSライブラリとは別のOSSライセンスを自分が作成したコードに適用する、等の場合に問題となるが、「派生物」の範囲となる。
なぜかというと、GPL系はもとより、MPL/EPL/CPL/CDDL系についても派生物の場合はそのソースコードを利用者が入手できるように、との記載があるためである。このため、自分達自身で作成したコードがどういった場合にOSSプログラムから見て派生物とみなされるのかは、死活問題となる。

例えば、少なくともGPLv2においては、GPLv2でライセンスされたライブラリに対して、動的・静的関わらず「リンク」しているプログラムにもGPLv2が適用されてしまうという強いコピーレフト性を持っている。非常に便利なGPLv2でライセンスされたOSSのライブラリがあるとして、これを商用製品の開発でリンクして用い、製品を独自のライセンスで提供したいケースでは、相当の注意が必要となる。

[BOLR2014]でも「2.1 伝播性のリスク」についてどこまでを派生物とみなすか、の説明がある。ただ面白いことに、その説明の中では特にライブラリのリンクについて Debian / RedHat / MySQL という比較的大きな開発組織のリーダやCTOで、それぞれ見解が異なっている。法的にも解釈の余地が残っている状態らしい。

他にも、GPLv2のFAQによると、2つのプログラムが結合され、事実上一つのプログラムの2つの部分となるなら、派生物とみなされるようだ。
http://ja.wikipedia.org/wiki/%E6%B4%BE%E7%94%9F%E7%89%A9

より確度の高い資料として以下がある。これはLGPLとJavaについて書かれたもので、結論としてはJavaの場合、ライブラリにアクセスするクライアント側のコードは、ライブラリの「派生物」とみなす、と書かれている。ただしLGPLの話なので、クライアント側のJavaコードについてはリバースエンジニアリングを許可するのであればLGPL以外のライセンスを適用できる、とも書かれている。
https://www.gnu.org/licenses/lgpl-java.html

一方で、EPL(Eclipse Public License)のFAQでは、以下の様な回答が記載されている。

For clarity, merely interfacing or interoperating with Eclipse plug-in APIs (without
modification) does not make an Eclipse plug-in a derivative work.

Eclipseは大部分がJavaで開発され、Eclipseプラグインはプラグイン用のAPIでEclipseと「リンク」していることになるが、単にインターフェイスを使っているだけであれば派生物とはみなされないようだ。
http://www.eclipse.org/legal/eplfaq.php#EXAMPLE

Javaについては以下も参照:
http://programmers.stackexchange.com/questions/224161/gpl-writing-an-exception-for-a-plugin-interface-under-section-7-of-gplv3
http://www.law.washington.edu/lta/swp/law/derivative.html

[BOLR2014]に戻ると、Javaのような動的リンクが行われるケースでは、標準インターフェイスを介しているかどうかが分かれ目のようである。
例えばServletAPIを使ったWebApplicationでは、確かに、デプロイされるコンテナがGPLで開発されたものであろうと、非GPLで開発されたものであろうと関係ない(コンテナに依存するような独自のAPIを利用するケースを除く)。

GPLとASPサービスとAGPL

ASPサービスなど、ネットワーク経由で使われるソフトウェアの場合、利用者の手元にソフトウェアが「頒布」されるわけではない。
この場合、GPLについては利用者がソースコードを入手できるようにする必要はない。
これはGPLの抜け道として知られており、利用者へのソースコード公開を義務付けた、さらにコピーレフト性が強くなった
http://ja.wikipedia.org/wiki/Affero_General_Public_License

クラウド向けサービスとGPL

ASPサービスではGPLの抜け道を使って、GPLでライセンスされたライブラリを、独自開発のプログラムにリンクして実行し、ASPサービスとして利用してもらうことが可能だった。
しかし、クラウド利用で利用者に直接VMイメージをコピーして、利用者自身のクラウド環境で使用してもらうような場合、少なくともオブジェクトファイルのコピーが発生する、つまり「頒布」に相当すると考えられないだろうか?
そうなるとGPLの伝播性、コピーレフトの影響を考え無くてはならない、と思われる。

JavaScriptとGPL

(調査中)

JavaScriptライブラリがGPLでライセンスされていた場合、そのライブラリを使ったJavaScriptもGPLになるのだろうか?
そのJavaScriptをscirptタグでロードするHTMLページをレンダリングするサーバサイドプログラムもGPLになるのだろうか?

観点1 : JavaScriptはブラウザ上にDLされて実行されるとすれば、「頒布」に相当するのか?
観点2 : JavaScriptライブラリをscriptタグでロードしているHTMLファイルは、そのJavaScriptライブラリにリンクしている派生物とみなされるのか?
観点3 : 上記HTMLファイルをサーバサイドで生成している場合、サーバサイドのプログラムも、そのJavaScriptライブラリが無ければ製品として成立しないようなケースではリンクしている派生物とみなされるのか?

参考:

その他参考資料



プレーンテキスト形式でダウンロード
現在のバージョン : 2
更新者: msakamoto-sf
更新日: 2014-04-26 18:18:24
md5:32a3ddac641af4b7566dc71a5658d164
sha1:8d1c0d3b50f91eb9f1cf599e682665b5f4a66936

日記/2014/04/20/牡蠣料理のメモ  

所有者: msakamoto-sf    作成日: 2014-04-20 16:51:45
カテゴリ:

2月ごろに殻付きの牡蠣をもらって、料理したのでその時のメモです。cookpadの参考URLなど。

牡蠣

マリネにしてみる:

牡蠣 適量
エキストラバージンオリーブオイル 適量
にんにく1~2かけ
オリーブ(緑・黒)各適量
酢・塩・こしょう 各少々
ローズマリー 少々
  1. 牡蠣を酢水で、沸騰させずに茹でる。
  2. にんにくとオリーブオイルを熱しておく。
  3. 茹でない場合は、この後牡蠣を炒め煮する。
  4. 塩コショウ、ローズマリー、オリーブとオリーブオイルで漬け込む。

片栗粉で洗ったあと炒め煮して、オイスターソースで風味漬けするバリエーション:


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2014-04-20 16:53:33
md5:a8e121216638c89849844713837f6d50
sha1:e763618affcacf80f04e1f394e739a8b952ca2d5

日記/2014/04/20/CheckstyleとかNetBeansとEclipseのフォーマットメモ  

所有者: msakamoto-sf    作成日: 2014-04-20 14:54:03
カテゴリ: Java 

プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2014-04-20 14:57:34
md5:4d2116a81e336bc3df5800168b9d83e8
sha1:38999ce50ff9490aa6ff130bb457a9a283ecd56c

日記/2014/04/13/ScheduledExecutorServiceの練習メモ  

所有者: msakamoto-sf    作成日: 2014-04-13 14:21:44
カテゴリ: Java 

練習用メモ。

AlarmListener:

package timer;
 
public interface AlarmListener {
    public void onAlarm();
}

PeriodicAlarm:

package timer;
 
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
 
/**
http://www.02.246.ne.jp/~torutk/javahow2/timer.html#doc1_id120
http://d.hatena.ne.jp/AWAWA/20080423/1208955538
http://www.ibm.com/developerworks/jp/java/library/j-5things5.html
 */
public class PeriodicAlarm implements Runnable {
 
    ScheduledFuture future;
    ScheduledExecutorService executorService;
    final Set<AlarmListener> listeners = new HashSet<>();
    final long initialDelay;
    final long period;
    final TimeUnit timeUnit;
 
    public PeriodicAlarm(long initialDelay, long period, TimeUnit timeUnit) {
        this.executorService = Executors.newScheduledThreadPool(1);
        this.initialDelay = initialDelay;
        this.period = period;
        this.timeUnit = timeUnit;
    }
 
    public void start() {
        this.future = this.executorService.scheduleAtFixedRate(this, this.initialDelay, this.period, this.timeUnit);
    }
 
    public void stop() {
        this.future.cancel(true);
    }
 
    public void shutdown() {
        this.stop();
        this.executorService.shutdown();
    }
 
    public void addAlarmListener(AlarmListener l) {
        synchronized (listeners) {
            listeners.add(l);
        }
    }
 
    public void removeAlarmListener(AlarmListener l) {
        synchronized (listeners) {
            listeners.remove(l);
        }
    }
 
    @Override
    public void run() {
        synchronized (listeners) {
            for (AlarmListener l : this.listeners) {
                l.onAlarm();
            }
        }
    }
}

PeriodicAlarmTest:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import static org.testng.Assert.*;
import org.testng.annotations.Test;
import timer.AlarmListener;
import timer.PeriodicAlarm;
 
public class PeriodicAlarmTest {
 
    public PeriodicAlarmTest() {
    }
 
    class Countup implements AlarmListener {
 
        String name;
        int count = 0;
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss.SSS");
 
        public Countup(String name) {
            this.name = name;
        }
 
        @Override
        public void onAlarm() {
            Calendar c = Calendar.getInstance();
            String snow;
            synchronized (this.sdf) {
                snow = sdf.format(c.getTime());
            }
            count++;
            System.out.println("[" + this.name + "]:now=" + snow + ", count=" + count);
 
        }
    }
 
    @Test
    public void hello() throws InterruptedException {
        PeriodicAlarm a = new PeriodicAlarm(0, 1, TimeUnit.SECONDS);
        a.start();
        Countup c1 = new Countup("c1");
        a.addAlarmListener(c1);
        Thread.sleep(2 * 1000);
        Countup c2 = new Countup("c2");
        a.addAlarmListener(c2);
        Thread.sleep(2 * 1000);
        Countup c3 = new Countup("c3");
        a.addAlarmListener(c3);
        Thread.sleep(2 * 1000);
        a.shutdown();
        assertEquals(c1.count, 6);
        assertEquals(c2.count, 4);
        assertEquals(c3.count, 2);
    }
 
}

プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2014-04-13 14:23:40
md5:71d0c4a1bdeb295c9fd0c153638d3194
sha1:ad47ab1a63eddabc4895db3c09647223cda033d7

日記/2014/04/07/Javaのconcurrentパッケージ勉強中・・・  

所有者: msakamoto-sf    作成日: 2014-04-07 00:05:28
カテゴリ: Java 

日付変わってしまったけど。勉強中の練習プログラム。TestNG使ったテストケースで。

一応、ドメイン限定で、非同期ジョブ制御用のAPIに挑戦しようと思ってるので、使ってないメソッドとかも想像上のものとして残してたり。

HogeTest.java:

package hoge;
 
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
 
/**
 *
 * @author FengJing
 */
public class HogeTest {
 
    public HogeTest() {
    }
 
    class JobMailBox<T> extends LinkedBlockingQueue<T> {
 
        protected boolean isShutdown = false;
 
        public void shutdown() {
            this.isShutdown = true;
        }
 
        @Override
        public boolean offer(T e) {
            if (this.isShutdown) {
                return false;
            }
            return super.offer(e);
        }
 
        @Override
        public boolean offer(T e, long timeout, TimeUnit unit) throws InterruptedException {
            if (this.isShutdown) {
                return false;
            }
            return super.offer(e, timeout, unit);
        }
 
        @Override
        public void put(T e) throws InterruptedException {
            if (this.isShutdown) {
                return;
            }
            super.put(e);
        }
 
        @Override
        public T poll(long timeout, TimeUnit unit) throws InterruptedException {
            return super.poll(timeout, unit);
        }
 
        @Override
        public T take() throws InterruptedException {
            return super.take();
        }
 
    }
 
    enum JobEvent {
 
        STARTED, RUNNING, CANCELLED, TERMINATED;
    }
 
    class JobSignal {
 
        public final JobEvent event;
        public final String key;
        public final String message;
 
        public JobSignal(JobEvent event, String key, String message) {
            this.event = event;
            this.key = key;
            this.message = message;
        }
    }
 
    interface JobHandle<R, M> {
 
        public R main(BlockingQueue<M> mailbox) throws Exception;
    }
 
    class JobButler {
 
        protected ExecutorService executorService;
        protected Map<String, Future> jobs = new ConcurrentHashMap<String, Future>();
        protected Map<String, BlockingQueue> mailboxes = new ConcurrentHashMap<String, BlockingQueue>();
        protected final JobMailBox<JobSignal> butlerMailBox = new JobMailBox<>();
 
        public JobButler(ExecutorService executorService) {
            this.executorService = executorService;
        }
 
        public JobMailBox<JobSignal> getButlersMailBox() {
            return this.butlerMailBox;
        }
 
        public <R, M> Future<R> submitNewJob(final String key, final JobHandle<R, M> job) throws InterruptedException {
            final BlockingQueue<M> mailbox = new ArrayBlockingQueue<M>(100);
            Callable<R> c = new Callable<R>() {
                public R call() throws Exception {
                    butlerMailBox.put(new JobSignal(JobEvent.RUNNING, key, "running"));
                    R result = job.main(mailbox);
                    butlerMailBox.put(new JobSignal(JobEvent.TERMINATED, key, "terminated"));
                    return result;
                }
            };
            butlerMailBox.put(new JobSignal(JobEvent.STARTED, key, "started"));
            Future<R> f = this.executorService.submit(c);
            this.jobs.put(key, f);
            this.mailboxes.put(key, mailbox);
            return f;
        }
 
        public Future getFuture(String key) {
            return this.jobs.get(key);
        }
 
        public Future terminateJob(String key) {
            Future f = this.jobs.get(key);
            if (f.isCancelled() || f.isDone()) {
                return f;
            }
            f.cancel(true);
            return f;
        }
 
        public void shutdown() {
            this.executorService.shutdown();
        }
    }
 
    class HogeJob implements JobHandle<String, String> {
 
        private final String name;
 
        public HogeJob(String name) {
            this.name = name;
        }
 
        public String main(BlockingQueue<String> mailbox) throws Exception {
            StringBuilder sb = new StringBuilder(1024);
            sb.append(this.name);
            sb.append(":");
            for (int i = 0; i < 10; i++) {
                sb.append(i);
            }
            return sb.toString();
        }
    }
 
    class CountJob implements JobHandle<Integer, String> {
 
        private int sum = 0;
 
        public Integer main(BlockingQueue<String> mailbox) throws Exception {
            for (int i = 0; i < 10; i++) {
                this.sum += i;
            }
            return new Integer(this.sum);
        }
 
    }
 
    @Test
    public void hoge2() throws InterruptedException, ExecutionException {
        JobButler jb = new JobButler(Executors.newCachedThreadPool());
        Future<String> f1 = jb.submitNewJob("job1", new HogeJob("jon"));
        Future<String> f2 = jb.submitNewJob("job2", new HogeJob("bob"));
        Future<Integer> f3 = jb.submitNewJob("job3", new CountJob());
 
        assertEquals(f1.get(), "jon:0123456789");
        assertEquals(f2.get(), "bob:0123456789");
        assertEquals(f3.get(), new Integer(45));
 
        jb.shutdown();
    }
 
    class SlowCountJob implements JobHandle<Integer, String> {
 
        private int sum = 0;
        private final String name;
 
        public SlowCountJob(String name) {
            this.name = name;
        }
 
        @Override
        public Integer main(BlockingQueue<String> mailbox) throws Exception {
            int i = 0;
            while (!"terminate".equals(mailbox.poll(1000, TimeUnit.MILLISECONDS))) {
                this.sum += i;
                i++;
                System.out.println(this.name + ":" + this.sum);
            }
            return new Integer(this.sum);
        }
 
    }
 
    @Test(expectedExceptions = CancellationException.class)
    public void hoge3() throws InterruptedException, ExecutionException, TimeoutException {
        JobButler jb = new JobButler(Executors.newCachedThreadPool());
        Future<Integer> f1 = jb.submitNewJob("job1", new SlowCountJob("scj-1"));
 
        try {
            Thread.sleep(5000);
        } catch (InterruptedException ignore) {
        }
        // cancel flag was set, but not interrupted ... orphan thread!!!
        f1.cancel(false);
        assertTrue(f1.isCancelled());
        assertTrue(f1.isDone());
        try {
            f1.get(1, TimeUnit.SECONDS);
        } finally {
            jb.shutdown();
        }
    }
 
    @Test(expectedExceptions = CancellationException.class)
    public void hoge4() throws InterruptedException, ExecutionException, TimeoutException {
        JobButler jb = new JobButler(Executors.newCachedThreadPool());
        Future<Integer> f1 = jb.submitNewJob("job1", new SlowCountJob("scj-2"));
 
        try {
            Thread.sleep(5000);
        } catch (InterruptedException ignore) {
        }
        // cancel flag was set, and, inerrupted -> thread terminates.
        f1.cancel(true);
        assertTrue(f1.isCancelled());
        assertTrue(f1.isDone());
        try {
            f1.get(1, TimeUnit.SECONDS);
        } finally {
            jb.shutdown();
        }
    }
 
    class AbnormalEndCountJob implements JobHandle<Integer, String> {
 
        private int sum = 0;
        private final String name;
        private final int stopper;
 
        public AbnormalEndCountJob(String name, int stopper) {
            this.name = name;
            this.stopper = stopper;
        }
 
        @Override
        public Integer main(BlockingQueue<String> mailbox) throws Exception {
            int i = 0;
            while (!"terminate".equals(mailbox.poll(1000, TimeUnit.MILLISECONDS))) {
                this.sum += i;
                i++;
                System.out.println(this.name + ":" + this.sum);
                if (i > stopper) {
                    throw new IllegalStateException("stopper threashold over.");
                }
            }
            return new Integer(this.sum);
        }
 
    }
 
    @Test(expectedExceptions = IllegalStateException.class)
    public void hoge5() throws InterruptedException, ExecutionException, TimeoutException, Throwable {
        JobButler jb = new JobButler(Executors.newCachedThreadPool());
        Future<Integer> f1 = jb.submitNewJob("job1", new AbnormalEndCountJob("abend-job-1", 3));
 
        try {
            Thread.sleep(5000);
        } catch (InterruptedException ignore) {
        }
        // job is already done (stopper = 3 means "After 3 seconds, throw IllegalStateException")
        // so, cancel() does not effect any more. isCancelled() returns false.
        f1.cancel(true);
        assertFalse(f1.isCancelled());
        assertTrue(f1.isDone());
        try {
            f1.get(1, TimeUnit.SECONDS);
        } catch (ExecutionException expected) {
            Throwable t = expected.getCause();
            assertEquals(t.getMessage(), "stopper threashold over.");
            throw t;
        } finally {
            jb.shutdown();
        }
    }
 
    @Test
    public void hoge() throws InterruptedException, ExecutionException {
        ExecutorService es = Executors.newCachedThreadPool();
        Callable<String> c = new Callable<String>() {
            public String call() throws Exception {
                StringBuilder sb = new StringBuilder(1024);
                for (int i = 0; i < 10; i++) {
//                    Thread.sleep(1000);
                    sb.append(i);
                }
                return sb.toString();
            }
        };
        Future<String> f = es.submit(c);
        assertEquals(f.get(), "0123456789");
    }
}

BoheTest.java:

package hoge;
 
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
 
/**
 *
 * @author FengJing
 */
public class BoheTest {
 
    public BoheTest() {
    }
 
    class JobMailBox<T> extends LinkedBlockingQueue<T> {
 
        protected boolean isShutdown = false;
 
        public void shutdown() {
            this.isShutdown = true;
        }
 
        @Override
        public boolean offer(T e) {
            if (this.isShutdown) {
                return false;
            }
            return super.offer(e);
        }
 
        @Override
        public boolean offer(T e, long timeout, TimeUnit unit) throws InterruptedException {
            if (this.isShutdown) {
                return false;
            }
            return super.offer(e, timeout, unit);
        }
 
        @Override
        public void put(T e) throws InterruptedException {
            if (this.isShutdown) {
                return;
            }
            super.put(e);
        }
 
        @Override
        public T poll(long timeout, TimeUnit unit) throws InterruptedException {
            return super.poll(timeout, unit);
        }
 
        @Override
        public T take() throws InterruptedException {
            return super.take();
        }
 
    }
 
    interface JobHandle<R, M> {
 
        public R main(BlockingQueue<M> mailbox) throws Exception;
    }
 
    class JobTask<V> extends FutureTask<V> {
 
        protected final String key;
 
        protected final JobButler butler;
 
        public JobTask(JobButler butler, String key, Callable<V> callable) {
            super(callable);
            this.key = key;
            this.butler = butler;
        }
 
        public JobTask(JobButler butler, String key, Runnable runnable, V result) {
            super(runnable, result);
            this.key = key;
            this.butler = butler;
        }
 
        @Override
        protected void done() {
            butler.notifyJobTermination(key);
        }
    }
 
    class JobGateway<R, M> {
 
        final Future<R> future;
        final JobMailBox<M> mailbox;
 
        public JobGateway(Future<R> f, JobMailBox<M> mb) {
            this.future = f;
            this.mailbox = mb;
        }
    }
 
    class JobButler {
 
        protected ExecutorService executorService;
        protected Map<String, JobGateway> jobs = new ConcurrentHashMap<>();
 
        public JobButler(ExecutorService executorService) {
            this.executorService = executorService;
        }
 
        public synchronized <R, M> JobGateway<R, M> submitNewJob(final String key, final JobHandle<R, M> job) throws InterruptedException {
            final JobMailBox<M> mailbox = new JobMailBox<>();
            JobTask<R> task = new JobTask<>(this, key, new Callable<R>() {
                @Override
                public R call() throws Exception {
                    R result = job.main(mailbox);
                    return result;
                }
            });
            this.executorService.execute(task);
            JobGateway<R, M> jobgw = new JobGateway(task, mailbox);
            this.jobs.put(key, jobgw);
            return jobgw;
        }
 
        public synchronized JobGateway getJobGateway(String key) {
            return this.jobs.get(key);
        }
 
        synchronized void notifyJobTermination(String key) {
            if (!this.jobs.containsKey(key)) {
                return;
            }
            JobGateway jobgw = this.jobs.get(key);
            jobgw.mailbox.shutdown();
            this.jobs.remove(key);
        }
 
        public void shutdown() {
            this.executorService.shutdown();
        }
    }
 
    class HogeJob implements JobHandle<String, String> {
 
        private final String name;
 
        public HogeJob(String name) {
            this.name = name;
        }
 
        @Override
        public String main(BlockingQueue<String> mailbox) throws Exception {
            StringBuilder sb = new StringBuilder(1024);
            sb.append(this.name);
            sb.append(":");
            for (int i = 0; i < 10; i++) {
                sb.append(i);
            }
            return sb.toString();
        }
    }
 
    class CountJob implements JobHandle<Integer, String> {
 
        private int sum = 0;
 
        @Override
        public Integer main(BlockingQueue<String> mailbox) throws Exception {
            for (int i = 0; i < 10; i++) {
                this.sum += i;
            }
            return new Integer(this.sum);
        }
 
    }
 
    @Test
    public void hoge2() throws InterruptedException, ExecutionException {
        JobButler jb = new JobButler(Executors.newCachedThreadPool());
        JobGateway<String, String> jgw1 = jb.submitNewJob("job1", new HogeJob("jon"));
        JobGateway<String, String> jgw2 = jb.submitNewJob("job2", new HogeJob("bob"));
        JobGateway<Integer, String> jgw3 = jb.submitNewJob("job3", new CountJob());
 
        assertEquals(jgw1.future.get(), "jon:0123456789");
        assertEquals(jgw2.future.get(), "bob:0123456789");
        assertEquals(jgw3.future.get(), new Integer(45));
 
        assertTrue(jgw1.future.isDone());
        assertTrue(jgw2.future.isDone());
        assertTrue(jgw3.future.isDone());
 
        assertNull(jb.getJobGateway("job1"));
        assertNull(jb.getJobGateway("job2"));
        assertNull(jb.getJobGateway("job3"));
 
        jb.shutdown();
    }
 
    class SlowCountJob implements JobHandle<Integer, String> {
 
        private int sum = 0;
        private final String name;
 
        public SlowCountJob(String name) {
            this.name = name;
        }
 
        @Override
        public Integer main(BlockingQueue<String> mailbox) throws Exception {
            int i = 0;
            while (!"terminate".equals(mailbox.poll(1000, TimeUnit.MILLISECONDS))) {
                this.sum += i;
                i++;
                System.out.println(this.name + ":" + this.sum);
            }
            return new Integer(this.sum);
        }
 
    }
 
    @Test(expectedExceptions = CancellationException.class)
    public void hoge3() throws InterruptedException, ExecutionException, TimeoutException {
        JobButler jb = new JobButler(Executors.newCachedThreadPool());
        JobGateway<Integer, String> jgw = jb.submitNewJob("job1", new SlowCountJob("scj-1"));
 
        try {
            Thread.sleep(5000);
        } catch (InterruptedException ignore) {
        }
        // cancel flag was set, but not interrupted ... orphan thread!!!
        jgw.future.cancel(false);
        assertTrue(jgw.future.isCancelled());
        assertTrue(jgw.future.isDone());
        try {
            jgw.future.get(1, TimeUnit.SECONDS);
        } finally {
            // cancel(false) internally called done().
            assertNull(jb.getJobGateway("job1"));
            jb.shutdown();
        }
    }
 
    @Test(expectedExceptions = CancellationException.class)
    public void hoge4() throws InterruptedException, ExecutionException, TimeoutException {
        JobButler jb = new JobButler(Executors.newCachedThreadPool());
        JobGateway<Integer, String> jgw = jb.submitNewJob("job1", new SlowCountJob("scj-2"));
 
        try {
            Thread.sleep(5000);
        } catch (InterruptedException ignore) {
        }
        // cancel flag was set, and, inerrupted -> thread terminates.
        jgw.future.cancel(true);
        assertTrue(jgw.future.isCancelled());
        assertTrue(jgw.future.isDone());
        try {
            jgw.future.get(1, TimeUnit.SECONDS);
        } finally {
            assertNull(jb.getJobGateway("job1"));
            jb.shutdown();
        }
    }
 
    class AbnormalEndCountJob implements JobHandle<Integer, String> {
 
        private int sum = 0;
        private final String name;
        private final int stopper;
 
        public AbnormalEndCountJob(String name, int stopper) {
            this.name = name;
            this.stopper = stopper;
        }
 
        @Override
        public Integer main(BlockingQueue<String> mailbox) throws Exception {
            int i = 0;
            while (!"terminate".equals(mailbox.poll(1000, TimeUnit.MILLISECONDS))) {
                this.sum += i;
                i++;
                System.out.println(this.name + ":" + this.sum);
                if (i > stopper) {
                    throw new IllegalStateException("stopper threashold over.");
                }
            }
            return new Integer(this.sum);
        }
 
    }
 
    @Test(expectedExceptions = IllegalStateException.class)
    public void hoge5() throws InterruptedException, ExecutionException, TimeoutException, Throwable {
        JobButler jb = new JobButler(Executors.newCachedThreadPool());
        JobGateway<Integer, String> jgw = jb.submitNewJob("job1", new AbnormalEndCountJob("abend-job-1", 3));
 
        try {
            Thread.sleep(5000);
        } catch (InterruptedException ignore) {
        }
        // job is already done (stopper = 3 means "After 3 seconds, throw IllegalStateException")
        // so, cancel() does not effect any more. isCancelled() returns false.
        jgw.future.cancel(true);
        assertFalse(jgw.future.isCancelled());
        assertTrue(jgw.future.isDone());
        try {
            jgw.future.get(1, TimeUnit.SECONDS);
        } catch (ExecutionException expected) {
            Throwable t = expected.getCause();
            assertEquals(t.getMessage(), "stopper threashold over.");
            throw t;
        } finally {
            assertNull(jb.getJobGateway("job1"));
            jb.shutdown();
        }
    }
 
    class TypicalMessageLoopJob implements JobHandle<String, String> {
 
        @Override
        public String main(BlockingQueue<String> mailbox) throws Exception {
            StringBuilder sb = new StringBuilder(1024);
            while (true) {
                String message = mailbox.poll();
                if ("__END__".equals(message)) {
                    break;
                }
                sb.append(message);
            }
            return sb.toString();
        }
    }
 
    @Test
    public void hoge6() throws InterruptedException, ExecutionException, TimeoutException, Throwable {
        JobButler jb = new JobButler(Executors.newCachedThreadPool());
        JobGateway<String, String> jgw = jb.submitNewJob("job1", new TypicalMessageLoopJob());
 
        jgw.mailbox.put("hello, ");
        jgw.mailbox.put("bob. ");
        jgw.mailbox.put("Good ");
        jgw.mailbox.put("Morning!");
        jgw.mailbox.put("__END__");
        jgw.mailbox.put("(this message must be ignored.");
        assertEquals(jgw.future.get(), "hello, bob. Good Morning!");
        assertFalse(jgw.future.isCancelled());
        assertTrue(jgw.future.isDone());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ignore) {}
        assertNull(jb.getJobGateway("job1"));
        jb.shutdown();
    }
 
}

BoheTest.javaの方が一応、洗練されてるつもり。


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2014-04-07 00:08:11
md5:0948c8a86b5a99e11fa87424efee12b7
sha1:04c1e2d23a48e8a6966c41a80f647a027e1acaf4

Java/JSON Schema Validation  

所有者: msakamoto-sf    作成日: 2014-02-24 01:42:21
カテゴリ: Java 

メモ書きです。
JSON Schemaを定義して、JSONの構造が正しいかチェックできる仕組みのようです。



プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2014-02-24 01:43:41
md5:8ecaaf518b6097dd1847641abcf1ba6d
sha1:039a768b2fcc7ef8d660bf59c36bd76e18fa78d6

日記/2014/02/18/JDKのCookie管理機能  

所有者: msakamoto-sf    作成日: 2014-02-18 23:44:01
カテゴリ: HTTP Java 

java.net.CookieHandler, CookieManager, CookieStore, HttpCookieなど、JDK7になって必要なインターフェイス・クラスがひと通り公開された。JDK6以前は、ここまで自由に触れなかったっぽい。

https://blogs.oracle.com/CoreJavaTechTips/entry/cookie_handling_in_java_se
http://docs.oracle.com/javase/tutorial/deployment/doingMoreWithRIA/accessingCookies.html
http://docs.oracle.com/javase/jp/7/api/java/net/CookieManager.html

JDK6時代のCookieManagerには謎の挙動やバグもあった。JDK7になって大体修正されたようだ。
http://tomott.cocolog-nifty.com/blog/2010/08/javecookie1-87d.html
http://0xc000013a.blog96.fc2.com/blog-entry-131.html
http://itpro.nikkeibp.co.jp/article/COLUMN/20070801/278817/

試しにJDK7のjava.net.HttpCookieのparse処理のコードとかを読んでみると、色々と歴史的な部分への細かい対処が詰め込まれていて、勉強になります、というか、自分で実装する気力が無くなりました。


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2014-02-18 23:46:59
md5:5d1998517d7692365f26a6014ad20aaf
sha1:994c89b661eeff618f3fd19ca528f7bd559e07a3