Monday, July 30, 2012

Alfresco勉強会#8 振り返り

皆さんこんにちは。

先日行われた第8回Alfresco勉強会のご報告です。
普段は数名が簡単な発表を行う形式でしたが、今回は趣向を変えてみました。


  1. Alfrescoで実現したいことを出し合う
  2. こうすればできる、というものがあればその場で皆で回答し合う
  3. 残った幾つかのお題に対し、解決案を考えてみる。うまく行けば実装までやる。



このように進めようと思ったのですが、さすがに時間が足りなかったです。
しかし、お題(実現したいこと)を皆で出し合うということは
次回のネタにも困らないので非常に有益でした。

実際の内容ですが、1では次のような意見が出ました。

  • プログラム連携
  • UIのカスタマイズ自由度
  • 冗長構成
  • アクセス履歴
  • ワークフロー

プログラム連携とは、外部システムとの連携を意味しています。よくある話であり、当然のごとくAfrescoのようなECMには要求されるものです。保有しているコンテンツを異なるUIで表示したり、Liferayのような他のプラットフォームソフトウェア上でユーザに見せたりしたいという要望はよくあります。
UIのカスタマイズに関しては、当日出席していた弊社メンバがv4.0以降のAlfrescoについてそれほど知見を持ち合わせていなかったので良い意見は出せなかったです。
冗長構成も企業内システムとして考える場合には当然求められるものですね。次回あたりのネタにしようかと考えています。
アクセス履歴、ワークフローに関しても企業利用の場合にはよく言われます。事故に巻き込まれたくないので、私はワークフローにはあまり近づかないようにしています。

他にも意見はあったのですが、おおよそこのようなものを出し合いました。

2では1で出されたものに誰かが簡単に説明を行う、ということをしました。
3では

  • ワークフロー
  • アクセス履歴

を取り上げようとしていたのですが、ワークフローで時間を使ってしまいアクセス履歴の話には至りませんでした。主にActivitiとJBPMに関しての話が為されていました。

全体的にまとまらない話で終わった感がありますが、
お題を皆で出し合うことには意味があったのではないかと思います。
次回は何を発表しようか...


@mryoshio



Wednesday, July 25, 2012

AlfrescoとTesseract OCR その2 (メタデータ抽出機能を使ってみた編)

こんにちは!aegifの大谷です。

以前の記事からだいぶ時間が経ってしまいましたが、AlfrescoのOCR連携について、もう少し実用的な例を紹介します。今回は、Alfrescoのメタデータ抽出機能(Metadata Extraction)を利用し、OCRの出力結果文字列をコンテンツの属性に保存し、全文検索できるようにしてみたいと思います。


メタデータ抽出機能って何?


メタデータ抽出機能とは、コンテンツ実体(ファイル)の中身を解析し、コンテンツの属性(メタデータ)にコンテンツ実体から抽出したパラメータを格納する機能です。
例えば、Microsoft Officeファイルは「ドキュメントのプロパティ」として「タイトル」「作成者」「会社名」などの情報を保持していますが、AlfrescoにMicrosoft Officeファイルをアップロードすると、自動的にファイルを解析してこれらの情報を抽出し、コンテンツのしかるべき属性にセットします。

Alfrescoにはデフォルトで多数のファイル形式に対してメタデータ抽出が設定されているので、コンテンツ登録時の属性登録が自動化され、登録の手間が省けます。
今回は、カスタムのメタデータ抽出を定義し、OCR出力文字列をコンテンツの属性にセットします。
(メタデータ抽出に関する詳しい説明はこちらを参照してください)


まずは事前準備


 カスタムのメタデータ抽出を定義する前に、OCRのセットアップを行います。今回も前回と同様、Tesseract OCRを利用します。今回は、以前の記事の手順1から3を実施しておきます。


カスタムのメタデータ抽出を実装する


では実際にカスタムのメタデータ抽出を作成していきます。実際にメタデータ抽出が行われるようにするためには、カスタムメタデータ抽出を実装し、その実装クラスをSpringビーンとしてAlfrescoに登録します。

まず、カスタムメタデータ抽出の実装を行います。メタデータ抽出用のクラスを作成するにあたっては、ベースクラスとしてAbstractMappingMetadataExtracterやTikaPoweredMetadataExtracter等が用意されていますが、今回はApache Tikaが提供するメタデータ抽出も利用するため、TikaPoweredMetadataExtracterを利用します。 拡張時のポイントは以下のとおりです。
  • SUPPORTED_MIMETYPESの設定:今回はtiffのみを対象とするため、image/tiffを設定します。
  • ocrCommand変数の追加:Alfrescoから外部コマンドを実行する仕組みであるRuntimeExecを利用してTesseract OCRをキックするために、RuntimeExec型の変数とsetterを定義します。インスタンスはSpringのDIによってセットされます(後述)。
  • getParserメソッドのOverride:Apache Tikaが提供するTiffParserを決め打ちで返すようにします。
  • extractRawメソッドのOverride:メタデータ抽出ロジックを書きます。今回はApache Tika標準のメタデータ抽出を行ったあと、OCRを実行して結果のテキストをcm:descriptionにセットします。
以下がサンプルコードになります(exceptionハンドリングとかいろいろはしょってますので適宜実装してください)。

TiffOcrMetadataExtractor.java
package jp.aegif.sample.tiffocr;

public class TiffOcrMetadataExtractor extends TikaPoweredMetadataExtracter {

  protected static Log logger = LogFactory.getLog(TiffOcrMetadataExtractor.class);

  private RuntimeExec ocrCommand;

  public static final ArrayList<string> SUPPORTED_MIMETYPES = buildSupportedMimetypes(
    new String[] {"image/tiff"},
    new TiffParser()
  );

  public TiffOcrMetadataExtractor() {
    super(SUPPORTED_MIMETYPES);
  }

  public void setOcrCommand(RuntimeExec ocrCommand) {
    this.ocrCommand = ocrCommand;
  }

  @Override
  protected Parser getParser() {
    return new TiffParser();
  }

  @Override
  protected Map<String, Serializable> extractRaw(ContentReader reader) throws Throwable {
    // Tika標準の抽出を行う
    Map<String, Serializable> rawProperties = super.extractRaw(reader);
    // OCRの出力結果テキストをcm:description属性にセットする
    putRawValue(KEY_DESCRIPTION, getText(reader), rawProperties);

    return rawProperties;
  }

  private String getText(ContentReader reader) throws Throwable {
    // OCRに渡す入出力ファイルを作成
    File sourceFile = TempFileProvider.createTempFile("_ocr", null);
    File targetFile = TempFileProvider.createTempFile("_ocr", ".txt");
    reader.getContent(sourceFile);

    // OCRコマンドに渡すパラメータを設定し、OCRを実行
    Map<String, String> properties = new HashMap<String, String>();
    properties.put("source", sourceFile.getAbsolutePath());
    properties.put("target", targetFile.getAbsolutePath());
    ExecutionResult result = ocrCommand.execute(properties);
    if (!result.getSuccess()) {
      throw new AlfrescoRuntimeException("OCR failed : " + result);
    }

    // 結果の読み出し
    BufferedReader br = null;
    try {
      br = new BufferedReader(new InputStreamReader(new FileInputStream(targetFile), "utf-8"));
      StringBuffer sb = new StringBuffer();
      String s;
      while ((s = br.readLine()) != null) {
        sb.append(s);
      }
      return sb.toString();
    } catch (Exception e) {
      throw e;
    } finally {
      if (br != null) br.close();
      sourceFile.delete();
      targetFile.delete();
    }
  }
}

また、以下のファイルを作成し、メタデータ格納先の属性を指定します。なお、このファイルは上記クラスのクラス名と同じファイル名とし、クラスファイルと同じディレクトリに配置してパッケージングする必要があります(=> TiffOcrMetadataExtractor.javaとTiffOcrMetadataExtractor.propertiesを同じパッケージ以下に作成してください)。

TiffOcrMetadataExtractor.properties
# Namespaces
namespace.prefix.cm=http://www.alfresco.org/model/content/1.0

# Mappings
author=cm:author
title=cm:title
description=cm:description
created=cm:created

上記2ファイルが作成できたら、jarパッケージを作成し、配置します。jarの配置先は、<tomcat_dir>/webapps/alfresco/WEB-INF/lib です。


カスタムメタデータ抽出の定義を追加する


次に、先ほど作成したカスタムメタデータ抽出クラスをAlfrescoに登録するための定義ファイルを作成します。登録にはSpringの仕組みを使うので、Springビーンとしての定義を行う必要があります。ポイントは以下のとおりです。
  • parentの指定:必ずbaseMetadataExtracterを指定します。
  • ocrCommandプロパティの指定:Tesseract OCRをキックするためのコマンドを指定します。
以下が定義ファイルになります。ファイル名の最後が必ず"-context.xml"となるようにします。

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


  
    
      
        
          
            
              
                C:/alfresco/ocr.bat
                ${source}
                ${target}
              
            
          
        
        
          1,2,3
        
      
    
  

定義ファイルが作成できたら、<tomcat_dir>/shared/classes/alfresco/extension にコピーします。Alfrescoは起動時に、内部的に指定されている定義ファイルを読み込むのですが、カスタム定義を簡単に登録できるように、デフォルト
でextensionディレクトリ以下に配置された*-context.xmlを読み込むよう設定されています。


実際に使ってみる


以上で設定は全て終わり、あとはAlfrescoを起動して動作確認をするだけです。
Alfrescoを起動したら、以下の手順に従って動作確認してみましょう。

1. ブラウザで http://localhost:8080/share/ にアクセスし、ログインします
2. リポジトリもしくは適当なサイトのドキュメントライブラリにアクセスします
3. テスト用のtiffファイルをアップロードします
4. 以下のように、「説明」プロパティにOCR結果の文字列がセットされていることを確認します(OCR結果がイマイチなのはTesseract OCR&日本語という組み合わせだからですね…)


5. 最後に、全文検索でtiffの内容がヒットするか確認します

以上でテスト完了です!

今回は、AlfrescoとTesseract OCRを連携し、メタデータ抽出機能を使ってOCRの結果をコンテンツのプロパティに格納するサンプルを紹介しました。連携するOCRツールが変わった場合は、ocrCommandプロパティでキックするコマンドをツールにあわせて変更するだけですので、お手持ちのOCRツールがある場合はそちらとの連携も試してみるとよいかもしれません。

Wednesday, July 18, 2012

AlfrescoでPDFファイルのプレビューができない!

こんにちは。大谷です。

Alfrescoにはコンテンツプレビュー機能があるのですが、Alfresco Community 4.0.dでPDFファイルのプレビューが表示されない!という現象に遭遇しました。


プレビューが表示されたりされなかったり…


通常ですと、コンテンツ詳細画面で以下のようなプレビュー画面が表示されます。

ところが、4.0.d以降では、一部のPDFファイルで以下のように1ページ目のサムネイルが表示されるだけになってしまうことがあります。


実は4.0.dでコンテンツ変換の仕組みに大きな変更が…


良く調べてみると、4.0.dからrepository.propertiesに以下のパラメータが追加されていました。
# pdf -> swf using Pdf2swf 1M takes about 30 seconds.
# Using a value of 1.25M (a bit larger that the txt or xlsx) used to create
# the pdf on the way to swf to avoid the second part of a transform failing
content.transformer.Pdf2swf.maxSourceSizeKBytes=1152
ちなみに、swfはAdobe Flashの再生用ファイルフォーマットで、まさにAlfrescoのプレビュー機能(Adobe Flashで実装されています)が利用しているものです。
Alfrescoのプレビュー機能は、様々なコンテンツをswf形式に変換し、それを表示しています。そのコンテンツ変換に際して、4.0.dからサイズによる制限が追加されたようです。


というわけで…


<tomcat_dir>/shared/classes/alfresco-global.properties に以下の1行を追加し、上限サイズを増やすことで、PDFファイルのプレビューを確実に行えるようにします。-1を指定すると、サイズ制限が無効になって必ずプレビュー用ファイルが生成されるよになります。
content.transformer.Pdf2swf.maxSourceSizeKBytes=1152


まとめ


上記の設定を行う事で、PDFファイルプレビューのサイズ制限を変更することができ、晴れて先ほどプレビューできなかったPDFファイルのプレビューが表示されるようになりました!
Alfrescoでは、プレビューに限らず、様々な場所でコンテンツ変換を利用しています。4.0.dでのコンテンツ変換機能の変更についての詳細や、コンテンツ変換機能自体についても今後記事にしていこうと思いますので、引き続きよろしくお願いします。

Wednesday, July 11, 2012

Activitiワークフロー:チュートリアル(パート1)

最近リリースされたAlfresco 4には新しいワークフローエンジンが入っています。「Activiti」というエンジンです。
ActivitiはAlfrescoとは独立したプロジェクトなので、他のアプリケーションと使えます。例えばLiferayでActivitiを使えます。Activitiは独立プロジェクトと言っても、実際にはAlfresco社がスポンサーとなっています。

jBPMと同じく、ActivitiはBPMN言語で書かれたビジネスプロセスを使用できます。
今週のブログポストのパート1では、一番簡単なActivitiワークフローを作る方法を説明します。

まずは、Eclipse Classicバージョン3.7(または3.7以上)をインストールしてください:http://www.eclipse.org/downloads/

そして、Eclipseの中にActivitiプラグインをインストールしてください:
・Eclipseを実行
・「ヘルプ」 → 「新規ソフトウェアのインストール」をクリック
・「追加」をクリック
・「名前」と「ロケーション」のところに、「Activiti BPMN 2.0 designer」と「http://activiti.org/designer/update/」を入力(下記の図通り)
・OKをクリックして、少し待つ
・「Activiti BPMN Designer」にチェックを付ける
・「次へ」をクリック
・依存解析を待つ
・「次へ」をクリック
・ライセンスを了承
・「完了」をクリック
・インストールが行われる
・Eclipseを再起動


では、Alfrescoでこのビジネスプロセスを使ってみましょう:
・Eclipseで、「ファイル」 → 「新規」 → 「その他」 → 「Activiti」 → 「Activiti Project」をクリック
・「次へ」をクリック
・「プロジェクト名」のところに、「nico1」を入力
・「完了」をクリック
・プロジェクトの構成が作成されました。「nico1/src/main/resources/diagrams」フォルダーを開く
・「diagrams」に右クリック、「新規」 → 「その他」 → 「Activiti」 → 「Activiti Diagram」
・「ファイル名」のところに「process1」を入力
・「次へ」をクリック
・「Yes, use a template」と「Pooled Review And Approve Activiti Process」を選択
・「完了」をクリック

4つのノードの図が表示されます。ビジネスプロセスの図です。
図の余白にクリックし、下の「プロパティー」→「処理」→「Id」のところに、「activitiReviewPooled」代わりに「process1」を入力。


これから、Alfrescoでこのビジネスプロセスを使いましょう:
・Alfresco Community 4.0d(またはそれ以上)をインストール
・「Alfresco/tomcat/shared/classes/alfresco/extension」というフォルダーを開く
・その中に、「workflows」という新しいフォルダーを作成
・この「workflows」フォルダーの中に、上記のステップで作成された「process1.bpmn」というファイルをコピー
・「Alfresco/tomcat/shared/classes/alfresco/extension」というフォルダーの中に、「activiti-adhoc-timer-workflow-context.xml.sample」というファイルを「nico1-workflow-context.xml」としてコピー
・この「nico1-workflow-context.xml」を下記のように編集:


    
                
                        
                                
                                        activiti
                                        alfresco/extension/workflows/process1.bpmn
                                        text/xml
                                        false
                                
                        
                
                
                        
                alfresco.messages.nicoWorkflow
                        
                
        



「alfresco.messages.nicoWorkflow」の部分はラベルについてです。「Alfresco/tomcat/shared/classes/alfresco/messages」というフォルダーの中に、下記の内容で「nicoWorkflow.properties」というファイルを作成。

process1.workflow.title=Process 1
process1.workflow.description=Based on pooled review

Alfrescoを再起動

ブラウザで「http://127.0.0.1:8080/share」を開いて、ログイン。
「http://localhost:8080/share/page/start-workflow」を開く。
ワークフローのリストの中に、「Process 1」が表示されています。
Alfrescoにデフォルトで登録されている「pooled
review」と同じように使用できます。

今回は、一番簡単なActivitiワークフローを作る方法を説明しました。
パート2では実践的な説明をする予定です。
Alfrescoを使わない場合は、スタンドアローンActivitiのインストールガイド使い方の記事をご覧ください。
Nicolas Raoul