2009年12月13日日曜日

log4j - java.util.logging bridge

log4j の出力を java.util.logging にリダイレクトするためのアペンダを書いてみた.がうまく動かなかったので,ここに捨てておく.いや,動いたには動いたのだが出力がへん. もっといいやり方としては,slf4j を間に挟む方法があるらしい.それをやってみよう.
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

public class JDKLogAppender extends AppenderSkeleton {
    static Map map = new HashMap();
    static Map levelMap = 
      new HashMap ();  
    static {
        levelMap.put(org.apache.log4j.Level.FATAL, java.util.logging.Level.SEVERE);
        levelMap.put(org.apache.log4j.Level.ERROR, java.util.logging.Level.SEVERE);
        levelMap.put(org.apache.log4j.Level.WARN, java.util.logging.Level.WARNING);
        levelMap.put(org.apache.log4j.Level.INFO, java.util.logging.Level.INFO);    
        levelMap.put(org.apache.log4j.Level.DEBUG, java.util.logging.Level.FINE);            
        levelMap.put(org.apache.log4j.Level.TRACE, java.util.logging.Level.FINER);            
    }

    private Logger getLogger(String name){
        Logger logger = map.get(name);
        if (logger != null)
            return logger;
        logger = Logger.getLogger(name);
        map.put(name, logger);
        return logger;
    }
    
    @Override
    protected void append(LoggingEvent event) {
        String loggerName = event.getLoggerName();    
        Logger logger = getLogger(loggerName);
        logger.log(levelMap.get(event.getLevel()), layout.format(event));
    }        

    @Override
    public void close() {
    }

    @Override
    public boolean requiresLayout() {
        return true;
    }
}

2009年12月12日土曜日

html parser for GAE

JavaにはHTML parser はやまほどある.一番簡単なのは,Swing に標準で含まれている javax.swing.text.html.parser.* を使う方法.だが,しかしこのパーザは,GAEでは使えない.swingが丸ごとblack listに入っているせい.実際にはグラフィックを使う部分ではないから この部分には害はないはずなのだけど.

他にもパーザはやまほどある. htmlcleanerと言うものを使ってみたが,いまいちうまくいかない. 原因は,文書内のMETAタグの中のcharsetをちゃんと読んでくれないせい. 本来,HTTPのヘッダに含まれるContent-typeに含まれているべき情報なのだけど, HTTPサーバだって各文書の文字コードのことまでは知らないので,ちゃんと設定するのはむずかしい.なので,METAタグでhttp-equivで書くのが普通. htmlcleanerに渡すReaderを適当な文字コードで作ってやれば読めるのだけど,それには,先に一度文書の中を読んで,METAタグを調べてから,htmlcleanerに食わせてやらなければならない. 面倒だ.

HTML Parser(どうでもいいが,もうすこし個体を識別できる名前をつけてほしい)は,まずは適当な仮定を持ってストリームを読み,meta tagを読み込んだ時点で,仮定と異なる文字コードだった場合には,頭からパーズし直してくれるらしい.

使ってみると確かにちゃんと読めているようだ. EUCのasahi.comもutf-8のwikipedia.jpも何も気にしないで読める. こりゃ便利.ツリーの中のノードに対して適当な条件をつけて,合致するノードだけ返す,なんてこともできる.a タグ で href があるものだけ,という条件で読んでみるとこんな感じ.

parser = new Parser(con);
Parser.getConnectionManager ().setRedirectionProcessingEnabled (true);
NodeFilter filter = 
  new AndFilter(new TagNameFilter("a"), new HasAttributeFilter("href"));
NodeList nodeList = parser.parse(filter);
for (Node node: nodeList.toNodeArray()) {
  TagNode tagNode = (TagNode)node;
  writer.println(tagNode.getAttribute("href"));
  writer.println(getText(tagNode));
}
いわゆるDomとは仕様が違うのが気になるけど,とりあえずこまらないかな.

2009年11月23日月曜日

yaml for java

いくつも実装があるようなのだが,使える物がない...
  • JYamlは,すごく単純なドキュメントでもエラーがでてパーズできない場合がある.理由は不明.最近は更新されていない.
  • JvYamlもエラーがでるらしい.これは試してない.
  • JvYamlb はJvYamlの作者が最近作っている実装らしいのだが,最後のbが示すとおり,byte列のみを扱う.つまり,Javaのオブジェクトになってからも,byte列なのだ.get("xxx") とかすることもできない.勘弁してくれ..
みんなどうしてるんだろう? いろいろためして, YAMLBEANS にたどり着いた.これはいまのところ,期待したように動いてくれているようだ...しかし,需要はありそうなのに決定版がないのが不思議.

2009年11月6日金曜日

VLAN on CentOS

vlanconfigを使う手動法ではなく,自動的にできるようにする方法. ここに詳しく書いてある.

  • /etc/sysconfig/network に下記を追記
    VLAN=yes
    VLAN_NAME_TYPE=DEV_PLUS_VID_NO_PAD
    
  • /etc/sysconfig/network-scripts/ifcfg-ethX.YYY を書く. YYYがタグ.
    DEVICE=ethX.YYY
    BOOTPROTO=static
    ONBOOT=yes
    IPADDR=192.168.100.10
    NETMASK=255.255.255.0
    

2009年10月28日水曜日

pubsubhubbub

パブサブハバブと読むらしい. ホームページ.

要するに,RSSのポーリングをノーティフィケーションに置き換える,という話で,間にブローカを置くことで,トラフィックを押さえる,というWeb Servicesの世界でもよく聞くような話.RSS Readerへの配送が早くなる,というが,Google ReaderのようなオンラインのReaderの場合だけで,ローカルなReaderだと別に早くならない.当たり前だが.

JavaFX と JAXB

混乱してきたのでまとめ.
  • JavaFX はJDK1.5 を前提としている.
  • JAXBはJDK6から取り込まれたが,1.5の場合は外部ツールが必要
  • JWSBP2.0にJAXBが含まれている.が,このJAXBも実はJDK6を必要としているようで,コンパイルは通るようになったのだが,実行すると落ちる.

JAXBは,ここからダウンロードできる.

  • JAXB の 2.2をためしてみたが,1.6用のようでだめ.
  • 1.0.6は,逆に古すぎる?のか,クラスファイルのバージョン番号がおかしいと言われてだめ.
  • 2.0.0 にしたら動いた!

これほど面倒な面倒なことになるとは...

JWSDP 2.0

JAXBをJDK5 で使うために,JWSDP2.0を導入. ここからダウンロード.Web startのダウンロードツールを強制的に使わされて不快.

shellアーカイブなのだが,実行するとすてきなインストーラが起動する.~/packages以下にインストール.

~/packages/jwdp2.0/jaxb/bin にjaxbがある.JWSDPにはいろいろ入っているが,用があるのは,JAXBだけなので,この下だけ切り出してもいいかも.

jaxbを使うときに,javaが1.5になるようにPATHを調整する必要がある.