「Clojure と slim3」の夏がやってくる (其の壱)

最近、ようやく AppEngine にというか、KVS の扱いに慣れてきたように思います。

RailsDjango では常に DRY であること要求されますが、その無言の圧力に従っていれば、自然とアプリ全体が見通しの良い構造になっていきます。
ある意味、考え無しでも、そこそこのモノができてしまいますので、実力が上がったように思いがちですが、実際はフレームワークの力によるもの、ということが往々にしてあります。

反面、GAE では製作者の技量が試されるような気がします。

ここは、規定時間内に処理が終了さえすれば、何も問われない世界です。だからと言って、何も考えずにアプローチしていては、この GAE というコースは攻略できません。
DRY ばかりを推し進めてもウマく行きません。さりとて、正規化を外しまくると管理が大変になってしまいます。とにかくバランスがとても大切で、この感覚を定着させるまでが一苦労でした。

「各種 API へのアクセスを可能な限り減らして、インスタンス内で高速にデータ処理する」というサイクルを、製作するアプリの性質ごとに最適化していくプロセスは、ちょっとしたパズルのようで、個人的には一番楽しい時間でもあります (ちなみに、一番キライなのはページ作りw)

ただ、先日発表になった新料金プランによって敷居が更に上がったような気がします。これからは、もっと妥協無く上記サイクルを徹底しないと利用料金を低く抑えられません (面倒になってしまって、手綱を緩めてしまうこと多々<涙>)

Rails のような FW とは異なり、AppEngine では、データとコードが相当なレベルで分離されていません。KVS からリスト構造を取得して、そのリストがコードに変化してユーザに届くような感じで、この感覚は正に Lisp であります。

そういう意味で、リストが扱いづらい Java への不満が募り始めたところでありました (ちなみに、Java の方がテスト環境の構築が容易であることを考慮すると、pytyon という選択肢は残念ながら有り得ません)

そこで、JVM 上の Lisp と言えば ClojureSlim3Clojure から操れないか、試してみました。


まずは、プロジェクトの作成から。Jenkins から扱いやすいよう maven で生成します。

$ mvn archetype:generate -DarchetypeCatalog=http://slim3.googlecode.com/svn/trunk/repository

(中略)
Define value for property 'groupId': : com.example
Define value for property 'artifactId': : CljTest
(以下略)


次に、pom.xml を修正して Clojure 関連ツールの導入準備をします。

(参考) Clojureでの開発環境 - in a Stream


次に、プロジェクトを mavenEclipse 化して Eclipse へインポートします。

$ mvn eclipse:eclipse


これで、Eclipse で編集できるようになりました。試してみたところ、Hot Reloading は有効のようです。

ただ、Eclipse の自動ビルドではコンパイルしてくれないので、手動でコンパイルする必要があります。

$ mvn compile (含む Java ファイル)
    or
$ mvn clojure:compile (Clojure ファイルのみ)

また、せっかくコンパイルした Clojure 由来のクラスファイルを消されてしまいますので、Eclipse の「Project メニュ → Build Automatically」のチェックを外しておきます。


さぁ、これで準備完了です。

手始めに maven が生成した IndexController を置き換えてみたいと思います。

まずは、src/main/java/com/example/controller/IndexController.java を削除します。

次に、src/main/clojure/com/example/controller/IndexController.clj と war/index.jsp を作成します。

IndexController.clj

(ns com.example.controller.IndexController
    (:gen-class :extends org.slim3.controller.Controller
    :exposes-methods {forward forwardSuper, requestScope requestScopeSuper}))


(defn -run
    "Docstring for -run."
    [this]

    (. this requestScopeSuper "msg", "OK?")
    (. this forwardSuper "index.jsp"))

;; 余談ではありますが、Java のソースと比べると圧到的に美しいですねぇ (主観 100%)

index.jsp

<!DOCTYPE HTML>
<html>
<body>
  <h1>Hello, World!! ${msg}</h1>
</body>
</html>


最後に、Eclipse の「Run メニュ → Run As → Web Application」を実行した後、

$ mvn clojure:compile

を実行して http://localhost:8888/ にアクセスしてみましょう。

Hello, World!! OK?

と表示されれば、成功です。


これで、コントローラーの Clojure 化を無事果たすことができました。
次は、サービスの Clojure 化に挑戦してみたいと思います。

生産性が求められる「今」だからこそ、Eclipse を使おう!

私と Eclipse の不幸な出会い

今から 7年ほど前まで遡りますが、そのころの私は Java ベースの WebObjects で開発を行なっておりました。開発環境は当然ながら、Xcode

しかし、私のスキルの問題も多分にあったと思うのですが、なかなか効率が上がらない WebObjects のスタイルに嫌気が差していた私は、そこから離れて PHP に鞍替えすることにしました。

問題は開発環境です。IDE に慣れていたので、PHP でもやはり同様なモノが欲しいと思っていたところ、遭遇したのが TruStudio。これが形を変えた Eclipse との出会いでした。

しかし...

Carbon 版 Eclipse は遅かった。とてつもなく遅かった

素の Eclipse に Plugin として TruStudio をインストールしても状況は改善されず、必然的に Emacs から Textmate へとテキストエディタを中心に開発環境は変遷し、Eclipse のコトは記憶の彼方に忘れ去ってしまいました。

再会もやはり不幸だった

3年ほど前に愛機を PowerBook G4 から ThinkPad (T23 → R40e → X200 → T500) に変えました。

Snow Leopard の発表を機に OSX に幻滅した私は、以前から憧れを感じていた「タイルウインドウマネージャを駆使する Linux」に移行したのです。ディストリビューションは、もちろん(笑) Gentoo/Linux

そんな中、GAE/J のデビューもあって Eclipse と二度目の邂逅を果たします。さすがに、GTK+ ベースであれば、Carbon 版のような不幸は起きないだろう、と高を括っておりました。確かに最初は幸福でした。

しかし...

ファイル数が増えると、時が経過すると、徐々に遅くなって、最後はキー入力さえ遅延してしまう

Gentoo 使いとしての私のスキルの低さも影響したと思うのですが、「何とまぁ。こうまで相性が良くないのか」と苦笑いする他ありませんでした。

三度目の出会いや如何に?

2011年も明けた早々、2年ほど前に書かれた下記記事を発見しました。

Eclipse をまともに使いこなしたコトが無い私から見ると、恥ずかしながら、とても魅力的な内容でした。

丁度、MacBookAir Late2010 の魅力に勝てず、Gentoo/Linux からの移行を終えたばかりのころでしたが、CocoaEclipse が存在していることを思い出した私は、チュートリアルがてら上記記事を試してみたのです。

すると...

何ということでしょう!まるで、テキストエディタのごとく軽快に動作するではありませんか!

上記記事の内容もさることながら、CocoaEclipse 素晴らしさに感銘を受けました。以来、常用ツールとして、とても重宝しています。

静的な型付け言語こそが生産性向上のカギ?

私の少ない経験ではありますが、PHPRubyPython と、LL言語を変遷してきた中で感じたのは「LL言語は、世間が言うほど簡単ではない」ということでしょうか。特に オブジェクト指向の皮を被った Lisp であるところの Ruby は、私にとっては難しい部類の言語でした。

確かに、LL言語の場合は、学習開始前までの敷居が低いことは事実だと思います。しかし、いつまでも初心者ではいられません。チュートリアルとは比べものにならないほど規模が大きくなる開発で活用していくためには、言語仕様の学習もさることながら、言語実装以外の周辺環境が重要になってきます。

1. デバッガ

まず、一番悩まされるのは変数の扱いでしょうか。LL言語であっても、デバッグの際は変数をトレースすることになります。しかし、その割に良いデバッガには、なかなかに巡り合いませんね。

変数の中身が見えてくると実装に内在する問題がググっと浮き上がってくるというのは、プログラミングに共通の出来事でしょう。Django のバックトレース画面には随分と助けられましたが、ああいう機能を標準で備えている方が例外です。

余談ですが、Erlang の変数には衝撃を覚えましたが、今はあのスタイルが一番良いのではないか、と思っています。

2. 補完機能

最近の LL言語であれば、ライブラリについてはまったく問題無いでしょう。むしろ重量級が多く、必要な API を覚えるだけでも一苦労です。

そこで、補完機能を備えた支援システムがクローズアップされることになるのですが、LL言語ではこの時点で一定の限界に到達するように思います。

インストール方法が複雑かつ、それでいて動作も完全に保証されている訳ではありませんので、時間を掛けてセットアップした割に動かなかった、ということは日常茶飯事です。趣味ならばともかく、仕事で使う場合は「えっ...」と絶句する瞬間ですね (苦笑


わずか二つの事例だけで優劣を論じるのは少し無理があるようにも思われますが、Eclipse などの導入しやすい IDE 文化が中心にある java には一日の長があるのでしょう。良くも悪くも、エンタープライズ市場で鍛えられてきた環境は伊達ではないのでしょう。

静的言語が一方的に効率が悪いとされた時代は過ぎたのではないか
76-コード分析ツールを利用する - やさしいデスマーチ

最近は、空気を読んでくれる Eclipse と相まって、java を見直す日々であります。

いよいよ言語仕様も古くなってきて、「いつまで使えるか? Oracle で大丈夫なのか?」などなど、その将来に多くの人が疑問符を持つ状況になっているようにも思いますが、さりとて、その代替となると、これまでの資産の継承も含めて完全にリプレース可能なキラー言語に淘汰されるのは、もうちょっと先でしょう。

個人的には、Scala をもうちょっとスリムにした、Eclipse 上で安定したプラグインが供給された、静的な型付けの関数型言語が登場しれくれれば、一番嬉しいです。

そんな夢のような日まで、java とお付き合いする日々が、どうやら続きそうです。

emerge したパッケージを定期的に晒してみることにした

不要なパッケージの見直しにもなるので、月末か月初辺りに定期的に掲載してみるのも良いと思った。

 * installed packages
app-admin/eselect-1.2.10
app-admin/eselect-ctags-1.13
app-admin/eselect-emacs-1.13
app-admin/eselect-fontconfig-1.0
app-admin/eselect-maven-0.2
app-admin/eselect-opengl-1.1.1-r2
app-admin/eselect-python-20100321
app-admin/eselect-vi-1.1.5
app-admin/eselect-wxwidgets-1.4
app-admin/eselect-xvmc-0.1
app-admin/logrotate-3.7.8
app-admin/mcelog-0.7
app-admin/perl-cleaner-1.05
app-admin/python-updater-0.8
app-admin/sudo-1.7.4_p3-r1
app-admin/syslog-ng-3.1.2
app-antivirus/clamav-0.96.1
app-arch/bzip2-1.0.6
app-arch/cabextract-1.2-r1
app-arch/cpio-2.11
app-arch/gzip-1.4
app-arch/rpm2targz-9.0.0.3g
app-arch/tar-1.23-r2
app-arch/unrar-3.9.7
app-arch/unzip-6.0-r1
app-arch/xz-utils-4.999.9_beta
app-arch/zip-3.0
app-backup/rsnapshot-1.3.1
app-crypt/truecrypt-7.0
app-dicts/mecab-ipadic-2.7.0.20070801
app-dicts/myspell-en-20081002
app-editors/emacs-23.2
app-editors/gentoo-editor-2
app-editors/nano-2.2.4
app-editors/vim-7.2.442
app-editors/vim-core-7.2.442
app-emacs/acp-1.0
app-emacs/anything-c-moccur-0.33
app-emacs/anything-c-source-other-windows-1.0
app-emacs/anything-c-yasnippet-0.6
app-emacs/anything-config-20100929
app-emacs/apel-10.7-r1
app-emacs/auto-complete-20100913
app-emacs/browse-kill-ring-1.3
app-emacs/cedet-1.0
app-emacs/color-moccur-2.66
app-emacs/css-mode-0.11
app-emacs/dabbrev-highlight-1.0
app-emacs/dabbrev-ja-1.0
app-emacs/descbinds-anything-1.05
app-emacs/dirtree-1.7
app-emacs/dropdown-list-20090814-r1
app-emacs/elib-1.0
app-emacs/emacs-common-gentoo-1.2-r1
app-emacs/ensime-0.3.0
app-emacs/espresso-9
app-emacs/fit-frame-22.0
app-emacs/flim-1.14.9-r2
app-emacs/hatena-mode-0.9.7
app-emacs/jaspace-1.1
app-emacs/jde-2.4.0.1
app-emacs/js2-mode-20080616a
app-emacs/key-chord-0.5
app-emacs/lua-mode-20071122
app-emacs/mmm-mode-0.4.8-r2
app-emacs/physical-line-3.2
app-emacs/po-mode-0.17
app-emacs/python-mode-5.1.0
app-emacs/recentf-ext-1.3
app-emacs/redo-1.02-r1
app-emacs/revive-2.19
app-emacs/scala-mode-2.7.7
app-emacs/semi-1.14.6-r2
app-emacs/session-2.2a
app-emacs/tramp-2.1.18
app-emacs/twittering-mode-0.9.0
app-emacs/wanderlust-2.14.0-r6
app-emacs/wb-line-number-1.5.5
app-emacs/windows-2.47
app-emacs/yaml-mode-20070622
app-emacs/yasnippet-0.6.1c
app-emulation/emul-linux-x86-baselibs-20100915-r1
app-emulation/emul-linux-x86-gtklibs-20100915
app-emulation/emul-linux-x86-medialibs-20100915
app-emulation/emul-linux-x86-opengl-20100915
app-emulation/emul-linux-x86-soundlibs-20100915
app-emulation/emul-linux-x86-xlibs-20100915
app-emulation/virtualbox-bin-3.2.8
app-emulation/virtualbox-modules-3.2.8
app-forensics/chkrootkit-0.49
app-i18n/kakasi-2.3.4
app-i18n/nkf-2.0.7
app-i18n/skk-jisyo-200705
app-i18n/uim-1.5.7
app-misc/ca-certificates-20090709
app-misc/fdupes-1.40-r3
app-misc/mime-types-8
app-misc/pax-utils-0.2.1
app-misc/realpath-1.15-r1
app-misc/screen-4.0.3
app-portage/eix-0.20.5
app-portage/g-cpan-0.16.2
app-portage/gentoolkit-0.2.4.6.1-r1
app-portage/layman-1.3.3
app-portage/portage-utils-0.3.1
app-shells/bash-4.0_p37
app-shells/zsh-4.3.10-r2
app-shells/zsh-completion-20080310
app-text/asciidoc-8.2.6
app-text/build-docbook-catalog-1.4
app-text/docbook-xml-dtd-4.1.2-r6
app-text/docbook-xml-dtd-4.2-r2
app-text/docbook-xml-dtd-4.3-r1
app-text/docbook-xml-dtd-4.4-r2
app-text/docbook-xsl-stylesheets-1.75.2
app-text/evince-2.30.3
app-text/ghostscript-gpl-8.71-r1
app-text/gnome-doc-utils-0.20.1
app-text/hunspell-1.2.11
app-text/libpaper-1.1.23
app-text/libspectre-0.2.5
app-text/mecab-0.97-r1
app-text/namazu-2.0.20
app-text/poppler-0.14.1
app-text/poppler-data-0.4.0
app-text/rarian-0.8.1-r1
app-text/scrollkeeper-9999-r1
app-text/scrollkeeper-dtd-1.0
app-text/sgml-common-0.6.3-r5
app-text/xmlto-0.0.22
app-vim/gentoo-syntax-20100215
dev-db/sqlite-3.6.23.1
dev-java/ant-1.8.1
dev-java/ant-antlr-1.8.1
dev-java/ant-apache-xalan2-1.8.1
dev-java/ant-contrib-1.0_beta2-r2
dev-java/ant-core-1.8.1
dev-java/ant-junit-1.8.1
dev-java/ant-nodeps-1.8.1
dev-java/ant-owanttask-1.1-r12
dev-java/ant-trax-1.8.1
dev-java/antlr-2.7.7
dev-java/asm-2.0-r1
dev-java/asm-3.2
dev-java/bcel-5.2
dev-java/bsh-2.0_beta4-r3
dev-java/commons-beanutils-1.8.0
dev-java/commons-cli-1.2
dev-java/commons-codec-1.4
dev-java/commons-collections-3.2.1
dev-java/commons-el-1.0-r2
dev-java/commons-httpclient-3.1
dev-java/commons-logging-1.1.1
dev-java/gnu-regexp-1.1.4-r2
dev-java/hamcrest-core-1.1
dev-java/icu4j-4.0.1.1
dev-java/jarjar-0.9
dev-java/java-config-2.1.11
dev-java/java-config-wrapper-0.16
dev-java/java-getopt-1.0.13
dev-java/javacup-0.11a_beta20060608
dev-java/javatoolkit-0.3.0-r4
dev-java/jline-0.9.94
dev-java/jsch-0.1.41
dev-java/junit-3.8.2-r1
dev-java/junit-4.6
dev-java/jzlib-1.0.7-r1
dev-java/libreadline-java-0.8.0-r2
dev-java/lucene-1.9.1
dev-java/lucene-analyzers-1.9.1-r1
dev-java/maven-bin-2.2.1
dev-java/qdox-1.6.3
dev-java/sat4j-core-2.2.0
dev-java/sat4j-pseudo-2.2.0
dev-java/servletapi-2.4-r5
dev-java/sun-jdk-1.6.0.20
dev-java/swt-3.5.2
dev-java/tomcat-servlet-api-6.0.26
dev-java/xalan-2.7.1
dev-java/xalan-serializer-2.7.1
dev-java/xerces-2.9.1
dev-java/xjavac-20041208-r5
dev-java/xml-commons-external-1.3.04
dev-java/xml-commons-resolver-1.2
dev-lang/lua-5.1.4-r4
dev-lang/perl-5.8.8-r8
dev-lang/python-2.6.5-r3
dev-lang/scala-2.7.7
dev-libs/adobe-air-sdk-bin-2.0.2
dev-libs/apr-1.4.2
dev-libs/apr-util-1.3.10
dev-libs/atk-1.30.0
dev-libs/dbus-glib-0.86
dev-libs/eb-4.2.2
dev-libs/eggdbus-0.6
dev-libs/eventlog-0.2.12
dev-libs/expat-2.0.1-r3
dev-libs/glib-2.24.1-r1
dev-libs/gmp-4.3.2
dev-libs/icu-4.4.1
dev-libs/libIDL-0.8.14
dev-libs/libcroco-0.6.2
dev-libs/libev-3.80-r1
dev-libs/libevent-1.4.14b
dev-libs/libffi-3.0.9
dev-libs/libgcrypt-1.4.6
dev-libs/libgpg-error-1.7
dev-libs/libnl-1.1-r1
dev-libs/libpcre-7.9-r1
dev-libs/libpthread-stubs-0.1
dev-libs/libsigc++-2.2.3
dev-libs/libtasn1-2.7
dev-libs/libusb-0.1.12-r5
dev-libs/libxdg-basedir-1.0.2
dev-libs/libxml2-2.7.7
dev-libs/libxslt-1.1.26
dev-libs/mpfr-2.4.2_p3
dev-libs/nspr-4.8.6
dev-libs/nss-3.12.7
dev-libs/openssl-1.0.0a-r3
dev-libs/pkcs11-helper-1.07
dev-libs/popt-1.16
dev-perl/Authen-SASL-2.12
dev-perl/Class-MethodMaker-2.15
dev-perl/Crypt-SSLeay-0.57
dev-perl/Digest-HMAC-1.01-r1
dev-perl/Digest-SHA1-2.12
dev-perl/Error-0.17.016
dev-perl/File-MMagic-1.27
dev-perl/HTML-Parser-3.64
dev-perl/HTML-Tagset-3.20
dev-perl/HTML-Tree-3.23
dev-perl/IO-Socket-SSL-1.33
dev-perl/Locale-gettext-1.05-r1
dev-perl/Log-Agent-0.307
dev-perl/Net-SMTP-SSL-1.01
dev-perl/Net-SSLeay-1.36
dev-perl/Shell-EnvImporter-1.07
dev-perl/TermReadKey-2.30
dev-perl/Text-Kakasi-2.04
dev-perl/URI-1.38
dev-perl/XML-LibXML-1.70
dev-perl/XML-NamespaceSupport-1.11
dev-perl/XML-Parser-2.36-r1
dev-perl/XML-SAX-0.16
dev-perl/XML-Simple-2.18
dev-perl/YAML-Tiny-1.41
dev-perl/libwww-perl-5.836
dev-perl/yaml-0.71
dev-python/docutils-0.7
dev-python/imaging-1.1.7
dev-python/pygobject-2.20.0
dev-python/pysqlite-2.6.0
dev-python/pyxml-0.8.4-r2
dev-python/setuptools-0.6.14
dev-util/android-sdk-update-manager-6-r2
dev-util/checkstyle-4.4
dev-util/cmake-2.8.1-r2
dev-util/ctags-5.7
dev-util/desktop-file-utils-0.16
dev-util/dialog-1.1.20080819
dev-util/eclipse-sdk-3.5.1-r1
dev-util/gperf-3.0.4
dev-util/gtk-doc-am-1.15
dev-util/intltool-0.41.1
dev-util/pkgconfig-0.25-r2
dev-vcs/git-1.7.2.2
dev-vcs/mercurial-1.4.1
dev-vcs/rcs-5.7-r3
dev-vcs/subversion-1.6.13
gnome-base/gconf-2.28.1
gnome-base/gnome-keyring-2.30.3
gnome-base/libgnome-keyring-2.30.1
gnome-base/librsvg-2.26.3
gnome-base/orbit-2.14.18
gnome-extra/libgsf-1.14.18
mail-mta/ssmtp-2.62-r7
media-fonts/corefonts-1-r4
media-fonts/encodings-1.0.3-r1
media-fonts/font-adobe-100dpi-1.0.1
media-fonts/font-adobe-75dpi-1.0.1
media-fonts/font-adobe-utopia-100dpi-1.0.2
media-fonts/font-adobe-utopia-75dpi-1.0.2
media-fonts/font-adobe-utopia-type1-1.0.2
media-fonts/font-alias-1.0.2
media-fonts/font-arabic-misc-1.0.1
media-fonts/font-bh-100dpi-1.0.1
media-fonts/font-bh-75dpi-1.0.1
media-fonts/font-bh-lucidatypewriter-100dpi-1.0.1
media-fonts/font-bh-lucidatypewriter-75dpi-1.0.1
media-fonts/font-bh-ttf-1.0.1
media-fonts/font-bh-type1-1.0.1
media-fonts/font-bitstream-100dpi-1.0.1
media-fonts/font-bitstream-75dpi-1.0.1
media-fonts/font-bitstream-speedo-1.0.1
media-fonts/font-bitstream-type1-1.0.1
media-fonts/font-cronyx-cyrillic-1.0.1
media-fonts/font-cursor-misc-1.0.1
media-fonts/font-daewoo-misc-1.0.1
media-fonts/font-dec-misc-1.0.1
media-fonts/font-ibm-type1-1.0.1
media-fonts/font-isas-misc-1.0.1
media-fonts/font-jis-misc-1.0.1
media-fonts/font-micro-misc-1.0.1
media-fonts/font-misc-cyrillic-1.0.1
media-fonts/font-misc-ethiopic-1.0.1-r1
media-fonts/font-misc-meltho-1.0.1
media-fonts/font-misc-misc-1.1.0
media-fonts/font-mutt-misc-1.0.1
media-fonts/font-schumacher-misc-1.1.0
media-fonts/font-screen-cyrillic-1.0.2
media-fonts/font-sony-misc-1.0.1
media-fonts/font-sun-misc-1.0.1
media-fonts/font-util-1.1.1-r1
media-fonts/font-winitzki-cyrillic-1.0.1
media-fonts/font-xfree86-type1-1.0.2
media-fonts/gnu-gs-fonts-std-8.11
media-fonts/ttf-bitstream-vera-1.10-r3
media-fonts/vlgothic-20090811
media-gfx/exiv2-0.19
media-gfx/geeqie-1.0-r1
media-gfx/gimp-2.6.8
media-gfx/imagemagick-6.6.2.5
media-libs/alsa-lib-1.0.21a
media-libs/audiofile-0.2.7
media-libs/babl-0.0.22
media-libs/fontconfig-2.8.0
media-libs/freetype-2.4.2
media-libs/gegl-0.0.22
media-libs/giflib-4.1.6-r1
media-libs/imlib2-1.4.2-r1
media-libs/jpeg-8b
media-libs/lcms-1.19
media-libs/lcms-2.0a
media-libs/libart_lgpl-2.3.21-r1
media-libs/libexif-0.6.19
media-libs/libid3tag-0.15.1b-r2
media-libs/libpng-1.2.44
media-libs/libpng-1.4.3
media-libs/libsdl-1.2.13-r1
media-libs/mesa-7.8.2
media-libs/tiff-3.9.4
media-sound/alsa-headers-1.0.21
media-sound/alsa-utils-1.0.21-r1
media-sound/mpg123-1.12.1
net-firewall/iptables-1.4.6
net-firewall/shorewall-3.4.8
net-fs/autofs-5.0.4-r5
net-ftp/lftp-4.0.9
net-libs/gnutls-2.10.1
net-libs/liblockfile-1.08
net-libs/libtorrent-0.12.6
net-libs/neon-0.29.3
net-libs/xulrunner-1.9.2.9-r1
net-mail/mailbase-1
net-misc/curl-7.20.0-r2
net-misc/dhcpcd-4.0.15
net-misc/iputils-20100418
net-misc/openntpd-3.9_p1-r1
net-misc/openssh-5.5_p1-r2
net-misc/rsync-3.0.7
net-misc/wget-1.12-r2
net-p2p/rtorrent-0.8.6-r1
net-print/cups-1.4.4-r2
net-print/cups-pdf-2.4.8
net-print/hplip-3.9.12-r1
net-wireless/iwl5000-ucode-8.24.2.12
net-wireless/wireless-tools-29
net-wireless/wpa_supplicant-0.7.2-r3
perl-core/Archive-Tar-1.54
perl-core/Compress-Raw-Bzip2-2.024
perl-core/Compress-Raw-Zlib-2.024
perl-core/Digest-MD5-2.39
perl-core/ExtUtils-CBuilder-0.27.03
perl-core/ExtUtils-ParseXS-2.22.05
perl-core/IO-Compress-2.024
perl-core/IO-Zlib-1.10
perl-core/MIME-Base64-3.08
perl-core/Module-Build-0.36.07
perl-core/Package-Constants-0.02
perl-core/Scalar-List-Utils-1.23
perl-core/Storable-2.20
perl-core/Test-Harness-3.17
perl-core/digest-base-1.16
perl-core/libnet-1.22
perl-gcpan/Lchown-1.01
sys-apps/acl-2.2.49
sys-apps/attr-2.4.43
sys-apps/baselayout-1.12.13
sys-apps/busybox-1.15.3
sys-apps/coreutils-8.5
sys-apps/dbus-1.2.24
sys-apps/debianutils-3.2.3
sys-apps/diffutils-2.8.7-r2
sys-apps/file-5.03
sys-apps/findutils-4.4.2
sys-apps/gawk-3.1.6
sys-apps/grep-2.5.4-r1
sys-apps/groff-1.20.1-r1
sys-apps/hdparm-9.20
sys-apps/help2man-1.36.4-r1
sys-apps/iproute2-2.6.31
sys-apps/kbd-1.15
sys-apps/less-436
sys-apps/man-1.6f-r4
sys-apps/man-pages-3.26
sys-apps/man-pages-posix-2003a
sys-apps/mlocate-0.22.4
sys-apps/module-init-tools-3.5
sys-apps/mtree-2007.4-r1
sys-apps/net-tools-1.60_p20090728014017-r1
sys-apps/pciutils-3.1.4
sys-apps/portage-2.1.8.3
sys-apps/sandbox-2.3-r1
sys-apps/sed-4.2
sys-apps/shadow-4.1.4.2-r5
sys-apps/smartmontools-5.38
sys-apps/sysvinit-2.88-r1
sys-apps/tcp-wrappers-7.6-r8
sys-apps/texinfo-4.13
sys-apps/usbutils-0.86-r1
sys-apps/util-linux-2.17.2
sys-apps/which-2.20
sys-auth/pambase-20100310
sys-block/open-iscsi-2.0.871-r1
sys-boot/grub-static-0.97-r9
sys-devel/autoconf-2.13
sys-devel/autoconf-2.65-r1
sys-devel/autoconf-wrapper-8
sys-devel/automake-1.10.3
sys-devel/automake-1.11.1
sys-devel/automake-wrapper-4
sys-devel/bc-1.06.95
sys-devel/binutils-2.20.1-r1
sys-devel/binutils-config-1.9-r4
sys-devel/bison-2.4.2
sys-devel/distcc-3.1-r4
sys-devel/flex-2.5.35
sys-devel/gcc-4.4.3-r2
sys-devel/gcc-config-1.4.1
sys-devel/gettext-0.18.1.1-r1
sys-devel/gnuconfig-20100122
sys-devel/libperl-5.8.8-r2
sys-devel/libtool-2.2.10
sys-devel/m4-1.4.14-r1
sys-devel/make-3.81-r2
sys-devel/patch-2.5.9
sys-fs/btrfs-progs-9999
sys-fs/dosfstools-3.0.9
sys-fs/e2fsprogs-1.41.12
sys-fs/fuse-2.8.1
sys-fs/lvm2-2.02.73-r1
sys-fs/nilfs-utils-2.0.18
sys-fs/sysfsutils-2.1.0
sys-fs/udev-151-r4
sys-kernel/gentoo-sources-2.6.34-r11
sys-kernel/linux-headers-2.6.30-r1
sys-libs/cracklib-2.8.16
sys-libs/db-4.8.30
sys-libs/e2fsprogs-libs-1.41.12
sys-libs/gdbm-1.8.3-r4
sys-libs/glibc-2.11.2
sys-libs/ncurses-5.7-r3
sys-libs/pam-1.1.1-r2
sys-libs/readline-6.1
sys-libs/timezone-data-2010l
sys-libs/zlib-1.2.3-r1
sys-power/acpid-2.0.6
sys-power/cpufrequtils-007
sys-power/hibernate-script-2.0-r2
sys-power/powermgmt-base-1.31
sys-power/powertop-1.11
sys-process/cronbase-0.3.2-r1
sys-process/procps-3.2.8
sys-process/psmisc-22.12
sys-process/vixie-cron-4.1-r10
virtual/acl-0
virtual/editor-0
virtual/emacs-23
virtual/emacs-flim-0
virtual/glu-7.0
virtual/init-0
virtual/jdk-1.6.0
virtual/jpeg-0
virtual/jre-1.6.0
virtual/libffi-0
virtual/libiconv-0
virtual/libintl-0
virtual/libusb-0
virtual/opengl-7.0
virtual/pager-0
virtual/perl-Archive-Tar-1.54
virtual/perl-Compress-Raw-Bzip2-2.024
virtual/perl-Compress-Raw-Zlib-2.024
virtual/perl-Digest-MD5-2.39
virtual/perl-ExtUtils-CBuilder-0.27.03
virtual/perl-ExtUtils-ParseXS-2.22.05
virtual/perl-IO-Compress-2.024
virtual/perl-IO-Zlib-1.10
virtual/perl-MIME-Base64-3.08
virtual/perl-Module-Build-0.36.07
virtual/perl-Package-Constants-0.02
virtual/perl-Scalar-List-Utils-1.23
virtual/perl-Storable-2.20
virtual/perl-Test-Harness-3.17
virtual/perl-digest-base-1.16
virtual/perl-libnet-1.22
virtual/ttf-fonts-1
www-client/chromium-7.0.517.24
www-client/firefox-3.6.9-r1
www-plugins/adobe-flash-10.1.82.76-r1
www-plugins/nspluginwrapper-1.3.0
x11-apps/appres-1.0.2
x11-apps/bdftopcf-1.0.2
x11-apps/bitmap-1.0.4
x11-apps/iceauth-1.0.3
x11-apps/luit-1.0.5
x11-apps/mkfontdir-1.0.5
x11-apps/mkfontscale-1.0.7
x11-apps/rgb-1.0.3
x11-apps/sessreg-1.0.6
x11-apps/setxkbmap-1.1.0
x11-apps/smproxy-1.0.3
x11-apps/x11perf-1.5.1
x11-apps/xauth-1.0.4
x11-apps/xbacklight-1.1.1
x11-apps/xcmsdb-1.0.2
x11-apps/xcursorgen-1.0.3
x11-apps/xdpyinfo-1.1.0
x11-apps/xdriinfo-1.0.3
x11-apps/xev-1.0.4
x11-apps/xf86dga-1.0.2
x11-apps/xgamma-1.0.3
x11-apps/xhost-1.0.3
x11-apps/xinit-1.2.0-r3
x11-apps/xinput-1.5.2
x11-apps/xkbcomp-1.1.1
x11-apps/xkbevd-1.1.0
x11-apps/xkbutils-1.0.2
x11-apps/xkill-1.0.2
x11-apps/xlsatoms-1.1.0
x11-apps/xlsclients-1.1.0
x11-apps/xmessage-1.0.3
x11-apps/xmodmap-1.0.4
x11-apps/xpr-1.0.3
x11-apps/xprop-1.1.0
x11-apps/xrandr-1.3.2
x11-apps/xrdb-1.0.6
x11-apps/xrefresh-1.0.3
x11-apps/xset-1.1.0
x11-apps/xsetmode-1.0.0
x11-apps/xsetroot-1.0.3
x11-apps/xvinfo-1.1.0
x11-apps/xwd-1.0.3
x11-apps/xwininfo-1.0.5
x11-apps/xwud-1.0.2
x11-base/xorg-drivers-1.7
x11-base/xorg-server-1.7.7-r1
x11-base/xorg-x11-7.4-r1
x11-drivers/xf86-input-evdev-2.4.0
x11-drivers/xf86-input-keyboard-1.4.0
x11-drivers/xf86-input-mouse-1.6.0
x11-drivers/xf86-input-synaptics-1.2.1
x11-drivers/xf86-video-intel-2.12.0
x11-drivers/xf86-video-vesa-2.3.0
x11-libs/cairo-1.8.10
x11-libs/gtk+-2.20.1-r1
x11-libs/libICE-1.0.6
x11-libs/libSM-1.1.1
x11-libs/libX11-1.3.4
x11-libs/libXScrnSaver-1.2.0
x11-libs/libXau-1.0.5
x11-libs/libXaw-1.0.7
x11-libs/libXcomposite-0.4.2
x11-libs/libXcursor-1.1.10
x11-libs/libXdamage-1.1.3
x11-libs/libXdmcp-1.0.3
x11-libs/libXext-1.1.2
x11-libs/libXfixes-4.0.5
x11-libs/libXfont-1.4.2
x11-libs/libXfontcache-1.0.5
x11-libs/libXft-2.1.14
x11-libs/libXi-1.3.1
x11-libs/libXinerama-1.1
x11-libs/libXmu-1.0.5
x11-libs/libXpm-3.5.8
x11-libs/libXrandr-1.3.0
x11-libs/libXrender-0.9.6
x11-libs/libXres-1.0.4
x11-libs/libXt-1.0.8
x11-libs/libXtst-1.1.0
x11-libs/libXv-1.0.5
x11-libs/libXvMC-1.0.5
x11-libs/libXxf86dga-1.1.1
x11-libs/libXxf86misc-1.0.2
x11-libs/libXxf86vm-1.1.0
x11-libs/libdrm-2.4.22
x11-libs/libfontenc-1.0.5
x11-libs/libpciaccess-0.11.0
x11-libs/libxcb-1.7
x11-libs/libxkbfile-1.0.6
x11-libs/libxkbui-1.0.2
x11-libs/pango-1.28.1
x11-libs/pixman-0.18.2
x11-libs/startup-notification-0.10
x11-libs/wxGTK-2.8.10.1-r5
x11-libs/xcb-util-0.3.6
x11-libs/xtrans-1.2.5
x11-misc/google-desktop-1.2.0.0088
x11-misc/gxmessage-2.6.2
x11-misc/hsetroot-1.0.2
x11-misc/icon-naming-utils-0.8.90
x11-misc/makedepend-1.0.2
x11-misc/shared-mime-info-0.71
x11-misc/slim-1.3.2-r1
x11-misc/util-macros-1.10.1
x11-misc/xbitmaps-1.1.0
x11-misc/xclip-0.12
x11-misc/xcompmgr-1.1.5
x11-misc/xdg-utils-1.0.2_p20100618
x11-misc/xkeyboard-config-1.9
x11-proto/bigreqsproto-1.1.0
x11-proto/compositeproto-0.4.1
x11-proto/damageproto-1.2.0
x11-proto/dri2proto-2.3
x11-proto/fixesproto-4.1.1
x11-proto/fontcacheproto-0.1.3
x11-proto/fontsproto-2.1.0
x11-proto/glproto-1.4.11
x11-proto/inputproto-2.0
x11-proto/kbproto-1.0.4
x11-proto/randrproto-1.3.1
x11-proto/recordproto-1.14
x11-proto/renderproto-0.11
x11-proto/resourceproto-1.1.0
x11-proto/scrnsaverproto-1.2.0
x11-proto/trapproto-3.4.3
x11-proto/videoproto-2.3.0
x11-proto/xcb-proto-1.6
x11-proto/xcmiscproto-1.2.0
x11-proto/xextproto-7.1.1
x11-proto/xf86bigfontproto-1.2.0
x11-proto/xf86dgaproto-2.1
x11-proto/xf86driproto-2.1.0
x11-proto/xf86miscproto-0.9.3
x11-proto/xf86rushproto-1.1.2
x11-proto/xf86vidmodeproto-2.3
x11-proto/xineramaproto-1.2
x11-proto/xproto-7.0.17
x11-terms/rxvt-unicode-9.07-r1
x11-themes/gnome-icon-theme-2.30.3
x11-themes/hicolor-icon-theme-0.12
x11-themes/slim-themes-1.2.3a-r6
x11-themes/xcursor-themes-1.0.2
x11-wm/awesome-3.4.4
equery list | wc -l

で 656 だった(なので、マイナス1 で 655個)。ちなみに、不要認定は以下。

app-arch/unrar
app-emacs/wb-line-number
dev-libs/adobe-air-sdk-bin
media-sound/mpg123
sys-fs/nilfs-utils
net-p2p/rtorrent

さようなり〜

ささやかな要望ですが...

XSS対策はサーバ側で対処された方がよろしいではないでしょうか。

  • サーバ側は生データのままで、js 側で html タグなどをエスケープする場合、もし js 側を改変された場合は対処方法が無く、とても危険な状態だと思います。
diff --git a/src/com/jsonengine/service/crud/CRUDRequest.java b/src/com/jsonengine/service/crud/CRUDRequest.java
index 021d657..5b6e20f 100644
--- a/src/com/jsonengine/service/crud/CRUDRequest.java
+++ b/src/com/jsonengine/service/crud/CRUDRequest.java
@@ -5,6 +5,8 @@ import java.util.Map;

 import net.arnx.jsonic.JSON;

+import org.slim3.util.HtmlUtil;
+
 import com.jsonengine.common.JERequest;
 import com.jsonengine.model.JEDoc;

@@ -57,6 +59,14 @@ public class CRUDRequest extends JERequest {
         if (jsonDoc != null) {
             // decode jsonDoc and fill it into jsonMap
             jsonMap = JSON.decode(jsonDoc, Map.class);
+
+            for (final String i : jsonMap.keySet()) {
+                final Object target = jsonMap.get(i);
+                if (target instanceof String) {
+                    jsonMap.put(i, HtmlUtil.escape((String) target));
+                }
+            }
+
             setDocId((String) jsonMap.get(JEDoc.PROP_NAME_DOCID));
         } else {
             jsonMap = null;

最低でも Google アカウントでログインしたユーザのみ put や get が実行可能にすべきではないでしょうか。

  • API に準拠していれば、どのような docType でも保存することができます。それゆえ、サーバ側で docType すべてをあらかじめ把握することはできないので、アクセスレベル設定では完全に制御できないと思います。
  • datastore は無限に無料ではないので、やはり、あらゆるアクセスが無制限に可能な状況というのは回避すべきだと思います。
  • jsonengine を使用したサービスに登録したユーザのみアクセスできる、というのが最も理想的だとは思いますが、このレベルになると汎用性の確保が難しくなるかも知れませんね。
diff --git a/src/com/jsonengine/service/crud/CRUDService.java b/src/com/jsonengine/service/crud/CRUDService.java
index 8bdb2ab..c16a010 100644
--- a/src/com/jsonengine/service/crud/CRUDService.java
+++ b/src/com/jsonengine/service/crud/CRUDService.java
@@ -169,40 +170,45 @@ public class CRUDService {
     public String put(CRUDRequest jeReq) throws JEConflictException,
             JEAccessDeniedException {
 
-        // try to find an existing JEDoc for the docId
-        final Transaction tx = Datastore.beginTransaction();
(snip)
+        if (JEUserUtils.isLoggedIn()) {
+            // try to find an existing JEDoc for the docId
+            final Transaction tx = Datastore.beginTransaction();
(snip)
-        // return the saved JSON document
-        return JSON.encode(jeDoc.getDocValues());
+            // return the saved JSON document
+            return JSON.encode(jeDoc.getDocValues());
+        } else {
+            return null;
+        }
     }
 }

データアクセスのデフォルトは、private だと嬉しいです。

  • この辺りになると、いよいよ汎用性との絡みなってくると思われますので、あくまで要望です。
diff --git a/src/com/jsonengine/service/query/QueryService.java b/src/com/jsonengine/service/query/QueryService.java
index 45af946..1cc02a1 100644
--- a/src/com/jsonengine/service/query/QueryService.java
+++ b/src/com/jsonengine/service/query/QueryService.java
@@ -41,10 +41,15 @@ public class QueryService {
         // check if this is a "private" query
         final DocTypeInfo jdti =
             (new DocTypeService()).getDocTypeInfo(queryReq.getDocType());
-        final boolean isPrivate =
-            jdti != null
-                && DocTypeService.ACCESS_LEVEL_PRIVATE.equals(jdti
+
+        boolean isPrivate;
+        if (jdti != null) {
+            isPrivate =
+                DocTypeService.ACCESS_LEVEL_PRIVATE.equals(jdti
                     .getAccessLevelForRead());
+        } else {
+            isPrivate = true;
+        }

         // build query (add in-memory filtering with createdBy if it's a private
         // query)