Tuesday, January 31, 2012

Kakasi-java: born again

The Japanese language has several symbols, including kanji and hiragana/katakana. In software, we sometimes need to switch a text from one system to the other, and it is difficult.

Kakasi and MeCab are Open Source libraries dedicated to the problem of converting kanji to hiragana or katakana. For instance they can transform "国際財務報告基準" to "こくさいざいむほうこくきじゅん" or even to "kokusaizaimuhoukokukijun". In clear, it transforms logograms (symbols with multiple possible readings) to syllables.
That is very tricky, because for instance "経緯" can be transformed to "keii", but also to "ikisatsu" depending on the context or speaker. Kakasi sometimes gets it wrong, but usually it is not that bad. MeCab is actually better at that.

Yesterday I decided to add a "furigana" feature to my Android flashcards app. Furigana helps people read difficult kanjis, they are used a lot in mass media: books, newspapers, signs, advertisements.
Kakasi and MeCab are both conversion tools, but their internal algorithms are very different, leading to different speed/quality/simplicity characteristics. Before running to MeCab, I decided to also give Kakasi a try.

Unfortunately, Kakasi is written in C, and thus not easy to run on Android. Porting from C to Java would be possible, but before doing it I had to make sure nobody had ported it already. After multiple searches, I finally found a tar file of the blog of Kenichi Maehashi, saying "現在どこからも入手できないようです". In clear: Kakasi-java can not be found anymore on the Internet, so he uploaded the 0.4 version he miraculously found in his backups.

To make improvements and fixes possible, I took the source, compiled, tested it, wrote a little README file and created a project for it on GitHub. Code contributions are welcome :-)

The best would be a Java port of MeCab, but that does not seem to exist. MeCab has a Java binding, but it is not 100% Java, requiring JNI calls, which is not a great idea for Android.
Nicolas Raoul

2016 update: I just created Jakaroma, its kanji transliteration is much more accurate so please use it instead of Kakasi-java. It is also open source.

Monday, January 30, 2012

Templated nodes in Alfresco 4


In the new Alfresco 4, you can now easily use document templates.
Templates are convenient for forms that employees must fill often, for instance.
Another example: here at Aegif we often write new contracts, always based on the same template.
In this article I explain how to create and use a template in Alfresco.
First log in Alfresco Share as admin, and click the repository icon:

Go to the "Data dictionary" folder, then "Node templates" folder, and upload your template:


That's all!
To use it, click "Create content..." then "By Templated Node...", and you can select a template:


The template is then copied to the current folder, and you just have to rename it.

More technical details:

  • Can be used to easily create nodes with a custom content model.
  • Convenient for nodes with a particular set of aspects and properties.
  • Node templates must me created by an administrator (or someone who has access to the data dictionary), and are usable by everyone.
  • I haven't tried but I guess you can use permissions to show a particular template only to a particular group of users.
  • I will have to check whether associations are preserved or not.
  • As I reported on JIRA, folder hierarchies can not be used as templated nodes yet.
Do you know any trick with templated nodes? Let us know in the comments :-)
Nicolas Raoul

Keywords: Créer un contenu... A partir d'un modèle. Inhlat erstellen... Nach Mustervorlagen-Node. Crear contenido... Por nodo de plantilla. Crea contenuto... Per nodo modello. 親近コンテンツ… テンプレートノード

Friday, January 27, 2012

Alfresco第5回勉強会

名倉です。
 Alfresco第5回勉強会に行ってきました!

 第5回だけど実は僕は今回が初参加です。 普段は「ライフレイリアン (Liferay担当)なんで、行かないッ!」とか言ってたんですが、今回は過去最大の参加者に対して、ウチのメンバに急遽参加できない人がでちゃったんで勉強会後の懇親会で戦力が足りないってことで、徴用されてしまいました。 

さて、勉強会の内容なんですが2つ発表がありました。 

①「Alfrescoの新UIを作ってみよう」@mryohio (スライド) 

@mryoshio氏によるAlfesco+ActiveCMISでUIを作成する発表でした。
 
・CMISについて
CMISは以前のブログ記事にも書かれていますが、コンテンツ管理システム (CMS/ECM)の標準規格です。Alfresco,IBM,Liferay,Microsoft,Oracleなどが参加していて、共通のデータモデルやプロパティ、サービスなどを持っています。でも、各社独自の実装があったりだとか、該当するプロパティがないだとかまだまだ共通化しきれていないところとか、あるみたいで、今後の展開はどうなるのか要チェックらしいです。 

・ActiveCMIS について 
ActiveCMISはRubyによるCMISの実装です。AlfrescoはCMISインタフェースがあるので、ActiveCMIS を使ってAlfrescoのリポジトリにアクセスすることが可能です。 コマンドラインからアクセスする例を見せてもらいました。

[デモ]ActiveCMISとAlfrescoの連携 
今回は検索機能と探索機能を見せてもらいました。検索は、前方一致、後方一致、全文検索などができ、探索は、エクスプローラーっぽい画面で、フォルダツリーを移動していました。 ソースはここにあるらしいので、気になるひとは参考にしてください。 

②「私はいかにAlfrescoのクイックハックに失敗したか」@opaopa6969 (スライド

@opaopa6969氏によるAlfrescoを使ったのアプリケーション開発の発表でした。
文書登録編集、閲覧、検索、既読管理、通知期間設定などかなり本格的なコンテンツ管理機能を持ったアプリケーションを作られていて驚きました。 Alfrescoは認証情報の管理や、文書登録編集などで必要になるユーザ一覧の取得などで使用して、 それ以外の部分はAlfrescoの外側で作成し、必要な機能をWebスクリプトでアクセスするようにしてアプリを作られていました。 独自のテーブルを作ってSprigで管理したり、 CIFS経由でコンテンツを追加したときに、自動的にカテゴリをつけるイベントハンドラを作成したりと 実践的な内容が豊富でとても参考になりました。

今回は初めて、イージフ以外の人に発表していただけました。 後に続く人がどんどん出てきて、活発になっていったらいいなぁ、と思う次第であります。

さて次回、第6回のAlfresco勉強会は来月2/22(水)にあります! 場所は大久保の健保会館です。 ぜひ、興味のある人はぜひ参加してください!!

Friday, January 20, 2012

Spring Surf紹介 - ページの作成とページリンク -

とたにです。

  前回から間が空いてしまいましたが、今回はいよいよSpring Surfで新しいページを作成してみます。(前回予告でファイル構成について説明、と書いたのですが実際に操作しながら同時に説明することにしました) 

 Spring SurfではSpring Rooを使ってさまざな操作を行えます。せっかくなのでrooを使ってページの作成もやってみましょう。 まずは現在のページ一覧を取得してみます。
roo> surf page list
Id: calendar Path: pages/calendar/calendar.xml
Id: home Path: pages/home/home.xml
Id: products Path: pages/products/products.xml

初期に用意されるひな形サイトでは3つのページがあることが分かります。 
 ここに新しいページを作ってみましょう。
roo> surf page create --id services --template home
Created SRC_MAIN_WEBAPP/WEB-INF/pages/services
Created SRC_MAIN_WEBAPP/WEB-INF/pages/services/services.xml

引数idは文字通りページidです。templateはページを描画する際に使用されるtemplateを指しています。homeという名前のtemplateは初期から用意されているものなので、ここではそれを使うことにします。 この状態で一度surfを起動してみます。
$ mvn jetty:run

http://localhost:8180/services とすると、以下のような中身が空のページが表示されます。

ただ残念なことに http://localhost:8180/ にアクセスしても新しく作成したservicesページがタブに表示されない状態です。

次はこのタブにservicesページを追加してみましょう。 

タブに表示されるページの一覧は、ページhomeからのアソシエーションとして設定されています。ではservicesもhomeのアソシエーション先に設定していきましょう。 まずはhomeの現在のアソシエーションを表示してみます。
roo> surf page association list --sourceId home
Page: products Type: child
ではservicesにアソシエーションを設定してみましょう。
roo> surf page association create ----sourceId home --destId services      
Managed SRC_MAIN_WEBAPP/WEB-INF/pages/home/home.xml
もう一度アソシエーションを確認するとservicesが増えていることが確認できます。
roo> surf page association list --sourceId home
Page: products Type: child
Page: services Type: child
この状態でもう一度サイトにアクセスしてみましょう。
 servicesがタブに追加されていることがわかりますね。

ここでページやアソシエーションがsurf上でどのように記述されているかを確認してみます。 
まずはservicesページですが、ページの本体は src/main/webapp/WEB-INF/pages/services/services.xml にあります。 
中身は以下のようになっていると思いますが、template-instanceがhomeになっているのが作成時のパラメータと対応していることが分かると思います。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <page>
    <id>services</id>
    <title>services</title>
    <template-instance>home</template-instance>
    <authentication>none</authentication>
    <components/>
</page>

次にアソシエーションですがアソシエーションはhomeページのxmlファイル上に定義されています。

src/main/webapp/WEB-INF/pages/home/home.xml
<page>
  <id>home</id>
  <title>Home Page</title>
  <template-instance>home</template-instance>
  <authentication>none</authentication>
  <order-id>0</order-id>
  <components>
    <component>
      <region-id>main</region-id>
      <url>/home/main</url>
    </component>
    <component>
      <region-id>side</region-id>
      <url>/home/side</url>
    </component>
  </components>
  <associations>
    <page-association>
      <dest-id>products</dest-id>
      <assoc-type>child</assoc-type>
    </page-association>
    <page-association>
      <dest-id>services</dest-id>
      <assoc-type>child</assoc-type>
    </page-association>
  </associations>
</page>
productsとservicesが両方ともタイプchildのアソシエーションとして定義されていることが分かります。 実はrooのcreate page associationでtype引数を省略するとchildとしてアソシエーションが作成されます。 

 現時点ではここで定義されたアソシエーションがあるとなぜタブ上にページが表示されるのか、そもそもあのタブはどこで定義されているのか、謎は残っていますが、長くなったので今回はここまでにして、次回そのあたりを探ってみます。