パッケージ同士の依存関係を抽出する

セミナー資料作成でちょっと必要になったので、調べてみた。いや、きっと世の中にはそういうツールがいっぱいありそうな気がしたんだけど、簡単にできそうなのでやってみた。Hibernateのソースから、Hibernateのパッケージ(だけ)のあいだの依存関係を、import文から読み取る。クラス単位ではないので、かなり精度は低いと思う。

grepはBorlandC++のgrepなので注意。sort/uniqのとこはCygwinで実行(めんどくさい...)

>grep -d "^import" *.java > \temp\pk1


>gawk -fpk1.awk pk1 > pk2

pk1.awk----------
/^File / {
    filename = gensub(/:/, "", "g", $2)
    referer = gensub(/\\[^\\.]*\.java$/, "", "g", filename)
    referer = gensub(/\\/, ".", "g", referer)
    next
}

/^\s*import / {
    if($2 ~ /\*;\s*/) {
        package = gensub(/\.\*;\s*/, "", "g", $2)
    } else {
        package = gensub(/\.[^\.]*;\s*/, "", "g", $2)
    }
    printf "%s %s\n", referer, package
}
                  • -
>cat pk2 | sort | uniq > pk3 >gawk -fpk2.awk pk2 > pk3 pk2.awk---------- { src = $1 dst = $2 if(src ~ /hibernate/ && dst ~ /hibernate/) { src = strip(src) dst = strip(dst) print src, dst } } function strip(package) { package = gensub(/^.*hibernate/, "", "", package) if(package == "") { package = "." } if(package ~ /^\.[^.]*\./) { package = gensub(/(\.[^.]*)\..*$/, "\\1", "", package) } return package }
                  • -
>sort < pk3 | uniq > pk4

これでやったら、依存関係が大量に(300以上)出てきた。まあ、Hibernateってクラスは1000以上、パッケージも75個あるから、しょーがないか。でもこれではあまり役に立たないなあ。