Wednesday, January 30, 2013

Alfrescoにカスタム属性を追加する - タイプとアスペクト -

こんにちは。大谷です。
日当たりが悪いのか、うちの周りが寒いのかは分かりませんが、うちの庭には相変わらず1月14日の雪が解け残っています(1月30日現在)。今回は、そんな大谷家からAlfrescoのコンテンツにカスタム属性を追加する方法をお伝えしたいと思います。基本的にはAlfresco4.2での話ですが、コンテンツモデルの仕組み自体はAlfresco3系でもほぼ同じです(そうそう変わるもんじゃない!)。


属性って何?そもそもコンテンツって何?


コンテンツは直訳すると内容物という意味です(当たり前ですが)。なので、ファイルサーバのコンテンツはファイルであり、CMSのコンテンツはリッチテキスト(と画像などの各種メディアファイル)ということになります。では、Alfrescoを始めとするECM(企業向けコンテンツ管理)の世界ではどうかというと、この世界では「コンテンツ=ファイル実体+属性情報(メタデータ)」と定義されることが多いです。つまり、ファイル実体とそのファイルに付随する各種の情報がセットで管理されるということを意味します。

そうなると、管理すべき属性を予め定義しておきたくなると思います。例えば、そのコンテンツが契約書であれば、属性情報として契約書番号や顧客番号などを管理したいでしょうし、そのコンテンツがある製品の説明書であれば製品番号などを管理したいと思います(そもそもそのコンテンツが契約書なのか、説明書なのか、というコンテンツタイプ自体も管理したいと思います)。このように、ECM製品を利用しようとすると必ずと言っていいほど行われるのが、カスタム属性の追加というカスタマイズです。


カスタム属性を実現するための2つの方法 -タイプとアスペクト-


カスタム属性は、上記例よろしく「ある種類のコンテンツには属性Aと属性Bを、この種類のコンテンツには属性Cと属性Dを」というようにコンテンツ種別に応じて特定の属性セットを付与、管理するという要件が多いかと思います。これを実現するのがタイプになります。タイプは、事前に定義された属性セットを持つもので、Alfresco上のコンテンツを特定のタイプに指定すると、そのタイプに定義された属性が管理できるようになります。

一方で、コンテンツ種別によらず、コンテンツ種別をまたぐような形で管理したい属性もあると思います。例えば、バージョン管理を行うときのバージョン番号や、タグ付け/カテゴリ付けする際のタグやカテゴリなどです。もちろん全てのタイプにそれら利用可能性のある全ての属性セットを持たせることも可能ですが、 それはとても無駄が多いことだし、そもそも各タイプにとってみればそれらの属性は本質的には関係ない属性だったりします。

それを解決するために、Alfrescoではアスペクトと呼ばれる機能を使います。アスペクトもタイプと同様に属性セットを定義するものですが、任意のコンテンツ(=任意のタイプのコンテンツ)に対して複数のアスペクトを動的に付け外し可能である点がタイプと異なります。例えば、バージョンを管理したい任意のコンテンツに対してのみバージョン管理アスペクトを付与し、タグ付けを行いたい任意のコンテンツに対してのみタグ付け可能アスペクトを付与する、というような感じです。この機能により、Alfrescoではコンテンツ管理において無駄な属性の増殖や属性セットの体系が複雑化していくという状況(通称:属性ヘル)を避けることができます。


じゃあどうやって定義するの?


カスタム属性を追加するためには、
  1. コンテンツモデルの定義
  2. UIの設定
が必要です。1.でタイプやアスペクトなどの属性セットを定義し、2.でその属性をShare UI上に表示するように設定します。

コンテンツモデルの定義


まず、以下のファイルを作成します。このフォルダには元々custom-model-context.xml.sampleというサンプルファイルがあるので、それをリネームするだけでもOKです。
このファイルは、読み込むコンテンツモデル定義ファイルを指示するものです(以下の例ではcustomModel.xmlを読み込む)。Alfrescoはクラスパス上の*-context.xmlというファイルを自動で読み込むため、この命名規則に従う限り異なる名前でも問題ありません。

<alf_dir>/tomcat/shared/classes/alfresco/extension/custom-model-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>
    <!-- Registration of new models -->   
    <bean depends-on="dictionaryBootstrap" id="extension.dictionaryBootstrap" parent="dictionaryModelBootstrap">
        <property name="models">
            <list>
                <value>alfresco/extension/customModel.xml</value>
            </list>
        </property>
    </bean>
</beans>

次に、以下のファイルを作成します(ファイル名は前述のファイル内で指定した名前にする必要がある)。このフォルダには元々customModel.xml.sampleというサンプルファイルがあるので、それをリネームして利用しても構いません。このファイルがタイプやアスペクトなどのコンテンツモデル定義の実体となりますが、今回はアスペクトを追加してみましょう。

<alf_dir>/tomcat/shared/classes/alfresco/extension/customModel.xml
<?xml version="1.0" encoding="UTF-8"?>

<!-- Custom Model -->

<!-- Note: This model is pre-configured to load at startup of the Repository.  So, all custom -->
<!--       types and aspects added here will automatically be registered -->

<model name="custom:customModel" xmlns="http://www.alfresco.org/model/dictionary/1.0">

   <!-- Optional meta-data about the model -->   
   <description>Custom Model</description>
   <author></author>
   <version>1.0</version>

   <imports>
      <!-- Import Alfresco Dictionary Definitions -->
      <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
      <!-- Import Alfresco Content Domain Model Definitions -->
      <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
   </imports>

   <!-- Introduction of new namespaces defined by this model -->
   <!-- NOTE: The following namespace custom.model should be changed to reflect your own namespace -->
   <namespaces>
      <namespace uri="custom.model" prefix="custom"/>
   </namespaces>
   
   <aspects>
      <aspect name="custom:reviewable">
         <title>Reviewable</title>
         <properties>
            <property name="custom:reviewer">
               <type>d:text</type>
               <mandatory>false</mandatory>
            </property>
            <property name="custom:reviewDate">
               <type>d:date</type>
               <mandatory>false</mandatory>
            </property>
         </properties>
      </aspect>
   </aspects>
</model>
ここではアスペクトcustom:reviewableが定義しています。テキスト型プロパティcustom:reviewerと日付型プロパティcustom:reviewDateを持ちます。コンテンツモデルの詳細はまた別の機会に説明したいと思いますが、基本的にはData Dictionary Guide - alfrescowikiにほとんどの情報がまとまっています。

UIの設定


次に、UIの設定を行います。UIの設定は以下のファイルで行います(もしshare-config-custom.xmlが存在しない場合は、同じフォルダにあるshare-config-custom.xml.sampleをコピー・リネームして上記ファイルを作成しておきます)。

<alf_dir>/tomcat/shared/classes/alfresco/web-extension/share-config-custom.xml

このファイルに以下の設定を追加します。サンプルファイルをリネームして使う場合は、既に同じconfigセクションが定義されている場合もありますので、その場合はそのセクションに以下の設定を追記してください。
<alfresco-config>
   <config evaluator="node-type" condition="cm:content">
      <forms>
         <form>
            <field-visibility>
               <show id="custom:reviewer" />
               <show id="custom:reviewDate" />
            </field-visibility>
         </form>
      </forms>
   </config>
   <config evaluator="string-compare" condition="DocumentLibrary">
      <aspects>
         <visible>
            <aspect name="custom:reviewable" />
         </visible>
      </aspects>
   </config>
</alfresco-config>
この設定によって、コンテンツのプロパティ表示/編集画面にcustom:reviewableの2プロパティが表示され、アスペクトリストにcustom:reviewableが追加されてアスペクト管理やルールで利用できるようになります。


ためしてみよう!


では、早速カスタム属性を使ってみましょう。まずはAlfrescoを再起動します。これらの設定ファイルをいじった後は再起動が必要になります。

まずは、適当なファイルをアップロードし、コンテンツ詳細画面のアクションメニューから「アスペクト管理」をクリックします。すると以下の画面が表示され、custom:reviewableアスペクトを使えるようになっているのでこれを選択します(表示されない場合は設定に問題があるはずです。alfrescoのログを見てみてください)。


 「変更を反映」をクリックすると、custom:reviewerプロパティとcustom:reviewDateプロパティが利用可能になります。ためしに「プロパティを編集」をクリックして値を入力すると、プロパティ一覧画面にもその値が表示されます(設定が間違ってるとプロパティが表示されません)。



手動じゃちょっと…


さすがに毎回手動でアスペクト付け外しやタイプ変更をするというのは実用的ではないので、実際に使う場合には、Java APIやJavaScript APIを使ってプログラマティックに行ったり、ルール機能を使ってコンテンツ追加時に自動的に行ったりします。ルール機能の使い方は「Alfresco4の使い方 - 基礎編(2) - ルール機能を使ってみよう!」に詳しいですが、例えば以下のような設定を行うと、特定のフォルダ以下に投入されたコンテンツに自動でアスペクトを付与することができます。


今回はタイプとアスペクトを使ったカスタム属性の追加方法について説明しました。今回言及できなかった、プロパティで指定できるデータ型や制約に関することや、プロパティ名の日本語化などの話題は折を見て書いていこうかと思います。


(2013/02/10 追記) 「Alfrescoのカスタム属性(とアスペクト名、タイプ名とか)を日本語化する」を公開しました。

No comments: