2011年7月25日月曜日

Eclipseのplugin開発時にファイルを読み込むには

テンプレートからの置換とかしたいのであれば、pluginプロジェクト内に
格納している設定ファイルなんかの情報を読み込みたかったりするはず。
そのときには下記の様にかけば開発できる。Eclipse3.6上での話。
最近出た3.7とかでは未検証だし、その他のバージョンでも試して無いので
そこら辺はあしからず。

ソースコード

Bundle bundle= Platform.getBundle("pluginID");
 URL url1 = bundle.getEntry("template/sample.txt"); //ここでEclipse上で解決できるPATH
 URL url2 = FileLocator.toFileURL(url1); //ここで、絶対的なファイルパスになる。
 FileReader reader = new FileReader(url2.getPath());
 BufferedReader br = new BufferedReader(reader);
 String line = br.readLine();
 while(line != null){
   //何か処理。
 }

ファイルの構成

/  --> プロジェクトRoot: 作ったプロジェクト名。
     |__bin
     |__icons
     |__template
          |__ sample.txt //今回はこのファイルにアクセスしたかった。
     |__src
     |__plugin.xml
     |__build.properties 

export時には

必ず、template/もいれないとjarの中に入らない(これは当たり前か。。。)
いやぁ、嵌った。嵌った。。。
同じ事で嵌らなくても良いように備忘の為に書いときます。

2011年7月19日火曜日

どんな形でも返却したい。総称型の使い方の備忘

  protected  T getTransitBean(Class clz) {
    SomeType someType= (SomeType) someObj;
    return someType.getBean();
  }
基底Bean
 public class SomeType {
   private T bean;
   public void setBean(T bean) {
     this.bean= bean;
   }
   public T getBean() {
     return this.bean;
   }
 }

2011年6月16日木曜日

Prototype.jsでmixIn的なことに今更チャレンジしてみる

今回はちょぅとMongoDBを離れて、JavaScirptの話。
もっとJavaScriptをゴリゴリ書けるようにならないとなぁと思っている今日この頃。
何か微妙だよなぁと思っている所を積極的に解決してみる事にした。
共通的な機能をJavaScriptの中で持たせたい時。勿論、別のJavaScriptをゴリゴリ読むでもよいんだけど、
あまりにもそれでは保守性も可読性も悪かろうにということで、下記の様な感じ。
今回はデバック的な機能(JavaでいうtoString()的なもの)を横断的に持たせたいなぁという話。

ソースはPrototype.jsベースです。
//大元のクラス。
var Component = Class.create({
 //constructor
 initialize : function(name){
  this.name = name;
 },
 
 hello: function(){
  alert("hello," + this.name);
 },
});

//こんな感じのclosureをmixInの対象にしてみる。
var JsLog = function(){
 var log = []
 function record(message){
  log.push(message);
 }
 
 function dump(){
  alert(Object.inspect(log));
 }
 
 function clear() {
  log = [];
 }

 return {
  record : record,
  dump: dump,
  clear : clear
 }
}();

//こういう感じでmixInも出来る。
//var ComponentPlus = Class.create(Component,JsLog);
//Prototype的にはこっちを推奨。もちろん、中身は自分で連想配列的に書いてもオK。
Component.addMethods(JsLog);
なるほどなぁ、JavaScript奥深し。というかPrototype.js奥深しかもしれないけど。
もっと良い方法あれば教えて下さい。

2011年6月10日金曜日

MongoDBと戯れる その2

今回は覚書、読むだけじゃ覚えないので、書きながらサマリーしてみる。

そもそも概念がちょっと違う。

普通にデータベースを持つ

Collection

CollectionというのがRDBMSでいうところのテーブルに値する。
  db.students --> studentsというcollectionが存在する。
内部表現はJSON形式であらわすことができる。実はBSONという形式ぱっと見た感じ、JSONだけどちょっと違う。
よりオブジェクト指向的な形になっている。
 db.students
  name: 'yas',
     addressHd: {
      address: XXXXX,
      city: Edogawa,
      prefecture: Tokyo
     }

参照

例えば、別のcollectionに対して参照を持つ場合はfor_【collection名】と書けばよい。
 db.students
    name: 'yas',
    for_course:  #参照をあらわしている。

 db.course
  name: 'Biology'
参照するよりも、埋め込んだほうが早いらしい。これは非正規化して速度稼ぐのと同じ理屈。
 1:Mongo的な非正規化
  db.students
    name: 'yas'
    address: 'XXXX'
    score: 
     { name: 'biology',
     grade: 4.0},
 
 2:Mongo的な正規化
  db.students
    name: 'yas'
    score: 
      { for_cource
          grade: 4.0}
    
    db.cource
      name: 'biology'
呼び出し側を考えれば簡単
1の場合: print(student.cource)
2の場合: print(student.score[0].for_course.name)
--> 内部的には、student.scores[0].for_course = db.courses.findOne({_id:_course_id_to_find_});
こういうノリのよう。
なので、場合によって使い分けたほうが良いはず。
非正規化する際、Gridとかのデータとかは出来上がったものを持てば良いだけなので問題ない。
それ以外の属性に依存する形の場合にはちょっと考えたほうが良い。2でガツガツ呼ばれる(1000)とか来ると
といくらキャッシュとはいえ1秒以上かかってしまうので。そこら辺は良く考えて!!だそうだ。

一般的なルール

  • ノード的にトップレベルのものは独自のコレクションを持つほうが良い
  • LineItemは(要するに詳細情報とかは)埋め込んどけ。
  • Object contains A の形になる場合は埋め込んどけ。
  • Many to Many なる場合はどうしようもないので、参照で持つしかない。
  • 集計とか統計とかするのであれば埋め込んどかないと時間かかって仕方ない。
→要するに基本的には埋め込んどけ。MtoMをどうしても表現しないといけなくなったときだけ参照使え。

indexはRDBMSと同じノリで張れば大丈夫。

  • _idは勝手にindexが張られている。これはputした瞬間にMongoが突っ込んでくれる。サロゲートキー
  • sortされるところはindexはっといたほうが良い→これは要検証。

tree表現とかも使える。


結構用意されていて、treeとしても使える。
tree情報のキャッシュには良いかもしれない。

デフォルトポート

27017

シェル

Mongoがそれにあたる。JavaScriptなシェル。これ面白い

制約

32bit環境においてstorageの限界は2Gbyteまで。

ちょっと試してみた結果

環境WindowsXP 32bit CPM core2 DUO Memory:4G
使用言語MongoDBのJavaドライバー経由でJava
対象件数3万件
ローカルストレージの変遷72,920byte
実行時間5891ミリ秒
使用メモリ量70Mぐらい

実験に使ったコード

ちなみにthis.excは適当に書いてみた。ラッパー
 long t1 = System.currentTimeMillis();
    System.out.println("計測開始!!" + t1);
    for (int i = 0; i < 30000; i++) {
      DBObject doc = new BasicDBObject();
      String str = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
      doc.put("name", str);
      doc.put("name_1", str);
      doc.put("name_2", str);
      doc.put("name_3", str);
      doc.put("name_4", str);
      doc.put("name_5", str);
      doc.put("name_6", str);
      doc.put("name_7", str);
      doc.put("name_8", str);
      doc.put("name_9", str);
      doc.put("name_10", str);
      doc.put("name_12", str);
      doc.put("name_13", str);
      doc.put("name_14", str);
      doc.put("name_15", str);
      this.exc.insert(doc);
    }
    long t2 = System.currentTimeMillis();
    System.out.println("結果:" + (t2 - t1) + "milSec");
    System.out.println("レコード数" + this.exc.getCount());
まだまだわからないことだらけだ。もっと検証を進めていこう。

2011年6月9日木曜日

MongoDB覚え書き

これは良いかもしれない!jarもあるし、windows版もある。
しかも、sortも出来るし、searchもOK。尚かつ、出力形式もJSONな感じだし。
これは、僕の為に作ってくれたのか!!!ぐらい有り難いです。
というわけで、色々メモしておこう。

ノリ的にはSqlite

   //Mongoサーバに接続する。この場合はlocalhost
   Mongo mongo = new Mongo("localhost");
  //使用するdatabaseを選択する。無ければ作ってくれる。
   DB db = mongo.getDB("myDb");
  //ここで対象のカラム群を選ぶ。無くてもOK.ノリ的には、tableという感じ。
   DBCollection coll = db.getCollection("testCol");
後は、このcollに対して操作をしてくのが基本。

データをinsertする。

  //こいつがその名の通り、基本のオブジェクト。
  BasicDBObject doc = new BasicDBObject();
  //insertするのは、他のkvsとかと同じ様にputでOK。
  doc.put("name", "yas");
  doc.put("age", 30);
   //上記のままではまだ保存されていないので、保存はこんな感じ。
   DBCollection coll = db.getCollection("testCol");
   //ここでコレクションに対してinsertが走ります。
   coll.insert(doc);

データをselectする。

■一件欲しい時
           DBObject myDoc = coll.findOne();
    System.out.println(myDoc);
■全部欲しいとき
    DBCollection coll = db.getCollection("testCol");
    DBCursor cursor = coll.find();
    while(cursor.hasNext()){
          System.out.println(cursor.next());
     }
■もっと絞りたいとき
               DBCollection coll = db.getCollection("testCol");
                //ここで検索条件を作っています。
  BasicDBObject query = new BasicDBObject();
         query.put("i", new BasicDBObject("$ne",3));
    //findする引数に問い合わせ条件を伴います。
  DBCursor cursor = coll.find(query);
         while(cursor.hasNext()) {
             System.out.println(cursor.next());
         }
■ソートもしたい
         DBCollection coll = db.getCollection("testCol");
  BasicDBObject query = new BasicDBObject();
         query.put("i", new BasicDBObject("$ne",3));
  BasicDBObject orderBy = new BasicDBObject();
                //-1だとDESCになります。
  orderBy.put("i", -1);
  DBCursor cursor = coll.find(query).sort(orderBy);
         while(cursor.hasNext()) {
             System.out.println(cursor.next());
         }
と言う感じらしい。リミットもひけるのでとても良い感じだと思う。
MongoDB最強伝説が始まっちゃったかな?
明日は、もっとデータをぶち込んで実際にJSON --> HTMLにmappingするところまでやってみよう。
これならいけるぞ!これなら!!

TokyoTyrantと戯れる その弐: Javaで使う。

メインの言語はJavaです。悲しいけど。
だから、Javaで動くまでを書いてみます。
まずはライブラリを探索。ここにある。
権利関係も大事だな、こいつのライセンスはApacheLicense2.0。よし、問題ない!
というわけで、ドキュメントを読み漁っていると問題発覚。。。
てか、RDBTable使えない。。。NightlyBuild的なソースが転がってたけど、
さすがにこれは使えない。。。ごめんね、作った人。
と言うわけで、JRubyかなぁとか思って、JRubyも試してみる。
すると、こんどはJava1.6からじゃないとすっきり書けない。。。
ScriptEngineManagerっていJava1.6からしか使えないし。。。乙 :P
と言うわけで、探しまくったら
こんなの見つけた。
これはどうなんだろう?ドキュメントを読んでいくとこれはRdbTableをサポートしてくれているらしい。早速トライ!!
ってLinux上でどうしてもコンパイル出来なかった。。。
険しいなぁ、ちょっと寄り道してMongoDbでも見てみよう。

2011年6月8日水曜日

TokyoTyrantことはじめ

色々と紆余曲折があって、TokyoTyrantを試してみることになった。
もともと、rubyな人だったので、まずはrubyで試してみる。

インストール

まずはインストール、適当に用意してあったVmWare上のCentOsに放り込む
Cabinet,Tyrant,TyrantRubyをイントール。必要なライブラリが足りなかったので、下記で充当。
yum -y install zlib-devel
yum -y install bzip*
それぞれのライブラリは
configure
make
make install
でOKだった。簡単。簡単。
rubyバインディングはinstall.rbがあったので、そいつを叩けば終了。
これで、とりあえず準備は整った。
今回は、2次元のデータ構造(Grid形式のもの)を放り込みたかったので、
テーブルのタイプは、tchではなく、tctを選択することにする。
ttservctlをエディタで開いて、拡張子を変更する。(tch -> tct)
dbname="$basedir/casket.tct#bnum=1000000"
そしてサーバ再起動
 ttservctl stop
 ttservctl start
最もシンプルなコードでテスト。
 require 'tokyotyrant'
 include TokyoTyrant
 #このRDBTBLを利用する為に、拡張子をかえました。
 db = RDBTBL::new
 if !db.open('localhost',1978)
   p 'not connected'
 end
 #putの反対はout,outするとメモリ上からさようなら。
 if !db.put("row1",{"name" => "cat", "age" => "18"})
   p 'put error'
 end
 db.put("row2",{"name" => "dog", "age" => "19"})
 db.put("row3", {"name" => "lion","age" => "20"})
 qry = RDBQRY::new(db)
 #sortしてみる。
 qry.setorder("age",RDBQRY::QONUMDESC)
 #MYSQLのlimitと同じ、結果セットから1件だけ下さい。
 qry.setlimit(1)
 p qry.search
 p qry.searchcount
 if !db.close
  p 'not disconnected'
 end
結果は、
 ["row3"]
 1
よしよし、期待通り。次はJavaだな。

2011年3月9日水曜日

javascript覚書その2: 全角とか、改行とか。。。

なんだが、よくわからないエラーに出くわしたので、解析がてらメモメモ。
まずは、勝手な推論。。。
1: どうやら、全角文字列が、入っているものを要素として扱うとこけるらしい?
2: 改行が入っていると予期せぬ動作をするらしい?
というわけで、1から検証してみる。
var Exp = function(){

 function click1(){
  alert('こんにちは 世界');
 }

 return {
  click1: click1,
 }
}();
こんな適当なメソッドを用意して、実行してみる。
実行環境はIE8です。
ドキュメントモードはIE8標準。
→普通に表示される。
ドキュメントモードはQuirksモード
→【識別子、文字列または数がありません。】
どうやら、昔々モードでは動かないらしい。これには参りそうだ、IE6での検証もしてみるか。
そんでもって、改行の実験もしてみよう。下記のようなソースコード。
var Exp = function(){

 function click1(){
  alert('こんにちは
世界');
 }

 return {
  click1: click1,
 }
}();
結果はQuirksもIE8もだめ。【終了していない文字列型の定数です。】
となった。さて、どうやって直そうか?
結局、DBから呼んでいる部分にはなから改行が入っているのが問題。
取得時に改行コード、全角→半角に変換することで表示の担保は出来そう。
解決編は本当に解決したら書こうかな。

2011年2月22日火曜日

JavaScript覚書

たとえば、以下のようなテーブルがあるとする。
    
aaa bbb
function moveTen(){ $$('.col').each(function(element){ element.style.left += 10; }); } }
このテーブルをグリグリと動かしたいと思ったとき、classを入れ替えるだなんだと
すると思う。そのときに、元の座標に戻したいときの話。
何かのイベントのトリガーで座標を取っとくとかでもいいんだけど。。。
せっかく、relativeってついてるんだから、単純にelement..style.left=0と言う風にしてしまえばよい。
そうすれば、さくっと元に戻せる。こういうのって、発想の転換というか、
どっちかっていうと頭の中が無限ループな時には役に立つちょっとしたノウハウ。

2011年2月9日水曜日

つまんなねえ!って思うなら。

やってみりゃいいんだよな。
ちょっとずつ、また理想のフレームワークでも作ってみよう。
一日、1つずつ。一日、1時間ずつ。
そうやって、少しずつ大きくしていこう。
Webの未来を創るんだぁ!!

2011年2月2日水曜日

初心忘れるべからず

でっかく考える。小さくならない。これだけは忘れてはいけない!!

RFM分析と、そこに対する考察

RFM分析とは?Recency Frequency Moneratyの略。

Recency:どれぐらい新しく?
Frequency: どれぐらいの頻度で?
Monetary: いくらで?
の観点で分析を行う手法らしい。
どのサプライヤに対して、幾らでどれくらい買ったのか?という話になるのだろう。

こういうことか?

要するに、どの業者からどれぐらいの頻度でいくらで買ったのか?
そのときの分析の要になるのが、同一商品郡だろうな。
商品郡の中から、当該カテゴリにーに並ぶものを並べて出す。
しかも、特定の期間でと言うところもキーになってくるはず。

どういう切り口で集計するのか?
・月次集計(〆日の設定は必要)
・前月との比較
・次月の予測(ここは均すアルゴリズムが必要)
・年次集計(〆日の設定は必要)
・商品郡ごとの集計(決して、個別の商品ではなく、その商品についているタグをもとにする)
・サプライヤ、商品郡をキーにした集計

その他勝手に思うこと

与信情報とかにも使えそう。
新規のサプライヤを選定する際に、どのように与信情報の見際目をするのか?
ここには情報を並べて、分析する機能が必要になるかと思うが、そこはまた別か。
次のお題にでもしよう。

気持ちの整理

本当に自分が作りたいのは新しい価値。
その為に必要なものは何なんだろう?
やはり、決定的にかけてるのは業務を分析する力だ。
分析して、考えまくらないと新しい価値なんて産めない。
どうやって、何を考えまくれば良いんだろう?
目の前にヒントはあるはずなんだけど、それが掴めない。
最近、イライラしてるのもそれが原因なんだろうな。
身近な所でヒントはあるかもしれない。
嫁に相談でもしてみるか、意外なこと言ってくれるかもしれない。
ああ、悩むわー。

2011年2月1日火曜日

大きく物事を考えること、小さく物事を見つめること

上に立つものの目線ってのは、なかなかエキサイティングだと思う。
抽象的に、大きく概要と概念をまとめていくような作業だ。
自分自身、そういう汎用的な観点で物事を考えていくのは嫌いじゃない。
でも、マクロな目線でものをみることよりも、まだまだミクロでものを見ていたい。
けど、ミクロなことを見つめよう、見極めようと思うと、、、
マクロに見れないと意味が無い。
大きく物事を考える癖をつけねばならない、それはより小さなものや声なき声を聞くためにも。

2011年1月27日木曜日

Prototype1.6で嵌る。。。

IE6の時に、下記のメソッド郡は嵌るから気をつけて。。。
駄目な人たち。
var hoge = $('hoge');
hoge.setStyle('textAlign','right');
hoge.getStyle('textAlign');
hoge.addClassName('someClass');

良い人たち。
var hoge = $('hoge');
hoge.style.textAlign = 'right';
hoge.style.textAlign;
hoge.className = 'someClass'

合掌。。。

2011年1月20日木曜日

理想と現実の狭間

やっぱり皆悩むんだろうけど、今も悩んでる
。何ごとかと思うだろうけど、今、目下の悩みは自動テスト、
どうやって、実現するのか?巨大なプログラムを相手に今から果たして自動テストは導入出来るのか?
そもそも、人手によるテストに頼り続けていることが問題なんだけど、今からもずっとその様にして行くのでは、到底これからのムーブメントや、開発には耐えられない。どこかで、誰かがメスを入れなければいけないんだろうけど、どっからどのようにしていけばいいのやら。何となく、頭のなかで全体的な方針と、設計は出来つつあるけど、
これを如何にして納得させるのか?口下手な自分には厳しいところがあるから
まわりのチカラも必要だけど。どうすりゃいいんだ?完全に愚痴だけど思考の整理がてら継続的に投稿してみようと思います。
皆が幸せにするのが技術者だとおもうから、この青臭い考えを元に頑張ってみるかな。初心忘れるべからず。気合入れて仕事しよう。

2011年1月17日月曜日

interfaceとannotation

未だにTigerな半熟野郎です。
interfaceにアノテーションをつけても、実装クラスではついてることにはならない!
普通に考えれば当たり前なんだけど、軽く嵌ってしまった。。。
なさけない(T3T)

以下サンプル

public interface Hoge{
   @sampleAnno
   void fuga();
}

public HogeImpl implements Hoge{
    public void fuga(){
      //reflectionとかで@sampleAnnoを見るようにしてると、そこで落ちてしまう。。。
      System.out.println('Hello');
    }
}

2011年1月5日水曜日

謹賀新年

あけましておめでとうございます。
今年こそは、色々と発信をしようと思って、再び再起動しました。
今年は、基礎力を今更になって振り返ってみようと思います。
というわけで、当面は下記の3つのトピックでお話を進めていきます。
くだらない話と、私の備忘録になることは請け合いですが。。。
もしよければ、少しでも何かを持っていってください。
今年もよろしくお願いいたします。