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としてアソシエーションが作成されます。 

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

Saturday, December 24, 2011

娘が1歳になりました!

こんにちは。大谷です。

今回は全く技術的なことに触れず、aegifという会社での働き方について紹介したいと思います。

 私事で恐縮なのですが、先日娘が1歳の誕生日を迎えました。誕生日プレゼントとしておもちゃのピアノをプレゼントしましたが、今はまだ暴力的に殴りつけるor乗っかるを繰り返しています。落ち着きが無く、いたずらっ娘で、よく癇癪をおこし、暴力的で、その割には祖父母にあまりサービスせずにがっかりさせるような娘ですが、無事1歳を迎えられたことをただただ嬉しく思います。ここまで来れたのには、妻の多大なる努力と、祖父母の協力のおかげなので、感謝の気持ちを新たにしているところです。そして、その中で自分がどれだけ貢献できたのか、少し思い返すことにしてみました。

 妻娘の退院後2週間は義母に寝泊まりしてもらい、その間自分は通常どおりの業務をしていました。その後1カ月は会社と交渉して自宅作業としてもらい、娘の世話と仕事を両立する生活でした。その後は結局通常どおりの業務に戻り、出社前に娘の世話をする程度しか関われていません。もちろん休日はできる限り家事・育児に関わり、妻娘が風邪をひいたときなどには有休や自宅作業などで家事や娘の世話をしています。

 このように書きだしてみると、ちょっと残念ですが、自分が思い描いていたよりも育児への関与が少ないような気がしています。娘はちょうど1歳になったところなので、これから加速度的に成長・変化していき、コミュニケーションもさらに取れるようになっていくでしょう。今後は今まで以上に育児に積極的に関わり、娘や妻との時間を取れるようにしていこうと考えています。そのうち親子でピアノを連弾できたらいいななど、たくさんある夢を少しでも多く実現したいと思います。もちろんそのために会社の制度をフル活用していこうと考えていますし(制度化されてないところは最大限自分に有利なように解釈しますよ)、aegifという会社はそういう関わり方を推奨している会社だと思います。

 aegifという会社はまだ小さな会社なので、整備されていない制度は必要が生じた時にその必要に応じて整備されていきます(その整備に直接関わることができます)。そして、もちろんビジネスの状況に依るところもありますが、ワークスタイルの自由を最大限尊重してくれます。このような会社でワークライフバランスを考えつつ働きたいという方がいらっしゃいましたら、是非採用に応募していただければと思います。

Friday, December 16, 2011

AlfrescoとTesseract OCR

こんにちは!aegifの大谷です。
今回は、AlfrescoのOCR連携についてお話ししたいと思います。

私自身、営業に同行してお客様から直接お話しを伺う機会が少なくないのですが、その中でOCR連携というトピックが話題にのぼり、実際にデモを行うこともあります。弊社ではOCR連携のデモ環境を構築する際に、googleが提供するオープンソースのOCRエンジンであるTesseract OCRをよく利用しています。
以下ではAlfrescoとTesseract OCRを連携させる方法の一例を紹介しますので、参考にしていただければと思います。

1. Alfrescoをインストールし、基本的な設定を行います(こちらのスライドが参考になると思います)

2. Tesseract OCRをインストールします(こちらのサイトからダウンロードできます。インストール時にjapanese language dataにチェックを入れてください)

3. Tesseract OCRをキックするためのスクリプトを作成します(以下はWindowsでtiff形式のファイルをOCR処理する例。ファイル名はocr.batとしておきます。tmpディレクトリの作成も忘れずに!)

@echo off
if "%1" == "" goto end
if "%2" == "" goto end
set tmpdir=c:\alfresco\tmp\
set ocrfilename=%tmpdir%%~n1.tif
copy /B /Y %1 "%ocrfilename%"
tesseract "%ocrfilename%" %~dpn2 -l jpn
del "%ocrfilename%"
:end

4. <tomcat_dir>/shared/classes/alfresco/extension/ に以下の内容のファイル ocrtiff-transform-context.xml を作成します

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>
  <bean id="transformer.worker.ocr.tiff" class="org.alfresco.repo.content.transform.RuntimeExecutableContentTransformerWorker">
    <property name="mimetypeService">
      <ref bean="mimetypeService" />
    </property>
    <property name="checkCommand">
      <bean class="org.alfresco.util.exec.RuntimeExec">
        <property name="commandsAndArguments">
          <map>
            <entry key=".*">
              <list>
                <value>C:/alfresco/ocr.bat</value>
              </list>
            </entry>
          </map>
        </property>
        <property name="errorCodes">
          <value>1</value>
        </property>
      </bean>
    </property>
    <property name="transformCommand">
      <bean class="org.alfresco.util.exec.RuntimeExec">
        <property name="commandsAndArguments">
          <map>
            <entry key=".*">
              <list>
                <value>C:/alfresco/ocr.bat</value>
                <value>${source}</value>
                <value>${target}</value>
              </list>
            </entry>
          </map>
        </property>
        <property name="errorCodes">
          <value>1</value>
        </property>
      </bean>
    </property>
    <property name="explicitTransformations">
      <list>
        <bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails">
          <property name="sourceMimetype"><value>image/tiff</value></property>
          <property name="targetMimetype"><value>text/plain</value></property>
        </bean>
      </list>
    </property>
  </bean>

  <bean id="transformer.ocr.tiff" class="org.alfresco.repo.content.transform.ProxyContentTransformer" parent="baseContentTransformer">
    <property name="worker">
      <ref bean="transformer.worker.ocr.tiff" />
    </property>
  </bean>
</beans>

5. Alfrescoを起動します

6.  http://<hostname>:<port>/alfresco/service/mimetypes にアクセスし、image/tiffからtext/plainへの変換が利用可能になっていることを確認します

7. 適当なフォルダを作成し、tiff画像からテキスト形式へのコンテンツ変換のルールを設定します

以上で設定は終わりです。正しく設定されていると、ルールを設定したフォルダにtiffファイルをアップロードしたタイミングでOCR処理が自動実行され、同名のテキストファイルが作成されます。


今回は、Alfrescoが用意するコンテンツ変換フレームワークと外部コマンド実行フレームワークを利用し、xmlベースの設定のみでOCRと連携するサンプルを紹介しました。ここでは詳しく説明しませんが、簡単なスクリプトを書くことで、OCRで抽出したテキストデータを元のtiffコンテンツの属性として登録するなど、さらに実用的な連携を行うことも可能です。

このように、Alfrescoはカスタマイズを容易にするために(もちろんAlfresco自体の開発を容易にするためでもありますが)様々な仕組みを用意しています。それらについては今後折を見て、具体的な例を交えつつ触れていきたいと思いますので、引き続きよろしくお願いいたします。

(2012/07/25追記:新しい記事「AlfrescoとTesseract OCR その2 (メタデータ抽出機能を使ってみた編) 」 を公開しました。こちらでは、OCRで抽出したテキストデータを元のtiffコンテンツの「説明」属性に格納するサンプルを紹介していますので、こちらも見てみてください。)

Monday, December 12, 2011

CMISとApache Chemistryと私

mryoshioです。

意味深なタイトルですが意味は無いです。
皆さんはApache ChemistryCMISという言葉をご存じでしょうか。
CMISというのはContent Management Interoperability Servicesの略であり、
コンテンツ管理システム (CMS/ECM)の標準規格です。
これを使うことで、異なるベンダのバックエンドデータへのアクセスが容易になります。
たとえば、弊社で扱っているAlfrescoはCMISインターフェースをもつため、
CMIS準拠のクライアントライブラリを使うことでAlfrescoリポジトリに対する
ドキュメントの作成や削除を簡単に行えます。

次にApache Chemistryについてですが、
これはCMISに準拠したクライアントやサーバを実装するためのJavaライブラリです。

実際にこのライブラリを使い、
JavaコンソールプログラムからAlfrescoリポジトリ内を操作してみましょう。
(Alfresco Community Edition 3.4dに対し動作確認済み)

  • リポジトリへの接続
  • SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
    Map parameter = new HashMap();
    parameter.put(SessionParameter.USER, "admin");
    parameter.put(SessionParameter.PASSWORD, "admin");
    parameter.put(SessionParameter.ATOMPUB_URL, ALFRSCO_ATOMPUB_URL);
    parameter.put(SessionParameter.BINDING_TYPE,BindingType.ATOMPUB.value());
    parameter.put(SessionParameter.REPOSITORY_ID, REPOSITORY_ID);
    session = sessionFactory.createSession(parameter);
    return session.getRootFolder();
    
  • フォルダの作成
  • Map props = new HashMap();
    props.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder");
    props.put(PropertyIds.NAME, newFolderName);
    Folder newFolder = target.createFolder(props);
    return newFolder;
    
  • ドキュメントの作成
  • Map props = new HashMap();
    props.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");
    props.put(PropertyIds.NAME, newDocName);
    System.out.println("This is a test document: " + newDocName);
    String content = "aegif Mind Share Leader Generating New Paradigms by aegif corporation.";
    byte[] buf = null;
    try {    
      buf = content.getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {    
      e.printStackTrace();
    }
    ByteArrayInputStream input = new ByteArrayInputStream(buf);
    ContentStream contentStream = session.getObjectFactory().createContentStream(
        newDocName, buf.length, "text/plain; charset=UTF-8", input);
    target.createDocument(props, contentStream, VersioningState.MAJOR);
    
  • ドキュメントの削除
  • try {    
      CmisObject object = session.getObjectByPath(target.getPath() + delDocName);    
      Document delDoc = (Document) object;    
      delDoc.delete(true);
    } catch (CmisObjectNotFoundException e) {    
      System.err.println("Document is not found: " + delDocName);
    }
    

いかがだったでしょうか。
皆さんが想像されていたものと勝手が違ったかもしれません。
しかし、同じクライアントコードを使い
異なるリポジトリ (e.g. Alfresco, SharePoint)を操作できるようになれば
そのメリットは十分にあると言えるでしょう。

今回はApache Chemistryを使いましたが、
たとえばRubyベースであれば、CMISクライアント実装のActiveCMISがあります。
もし興味を持たれた方はこちらも併せてぜひご覧ください。

なお、サンプルコードを含むJavaクラスはここにあります。


@mryoshio

Friday, December 2, 2011

Alfresco勉強会 #4

こんにちは!大谷です。

 先日開催された第4回Alfresco勉強会に参加してきましたので、今回はその内容について書きたいと思います。

「Alfresco Java Foundation API」@mryoshio (スライド)

@mryoshioによるAlfrescoのJava APIに関する発表。Alfrescoが提供するJavaのAPIであるJava Foundation APIの解説と、Web Scriptのロジック記述をJavaで行うサンプルの紹介がありました。
Web Scriptについて
Web Scriptに関する基本的な説明と、ロジックをJavaで実装するメリットについて説明がありました。APIの豊富さとパフォーマンスの点でJavaScripよりもJavaの方に分があるとのことです。
Java Foundation APIについて
Java Foundation APIの基本的な説明と提供しているサービスの例、アクセス方法についての解説がありました。Spring Beanとしてインタフェースが公開されているため、DIによって簡単にAPIを利用することができます。
[デモ] Java Foundation APIの使い方
Web Scriptのロジック記述にJavaを用いる場合の具体的な作成・設定手順について、デモを交えながらの説明がありました。コードをgithubで公開しているそうなので是非実際に動かして確認してみてください。

「Alfresco 4.0 Solr連携を試してみた!」
@_tasky (スライド)

続いては、@_taskyによるAlfresco Solr連携に関する発表。Alfresco 4.0で正式対応した全文検索アプリケーションSolrについて、簡単な説明と、これまでのデフォルト全文検索エンジンであるLuceneとの利用シーン比較、連携の設定方法について紹介がありました。
Solrについて
Solrに関する基本的な説明。SolrはLuceneのHTTPラッパのようなものだそうです(コアの全文検索エンジンにLuceneを使っています)
Solr vs Lucene
それぞれの利用シーンについての説明。スケーラビリティを求める場合はSolrを、in-transaction indexingが必要な場合はLuceneを選択した方がよいようです。
[デモ]セットアップと動作確認
Alfrescoが公開しているSolr連携用モジュールを使ったセットアップ方法の紹介。Alfrescoが提供するzipファイルの中に必要なファイルが全て入っているので、それらを用いて、Solrサーバ導入、Alfresco設定、TomcatのSSL設定を行うだけでセットアップが完了します。

今回の参加者は6名でしたが、Alfrescoを使った開発を行っている方やソリューションの候補として製品選定をされている方が参加していたため、技術的なディスカッションからビジネス的な質問まで幅広く情報交換が行われました。今後も両者バランス良く(というよりも、あまりその観点にとらわれず、自由に)やっていければと思います。 次回についてはこちらで参加登録できますので、興味がある方は是非ご参加ください。