【Fiori】UIアノテーションの定義を知る

##はじめに
Fiori Elementsアプリを作成するには、アノテーションを使う必要があります。やりたいことを実現するためにどんなアノテーションを使えばよいかは検索すれば出てきますが、「そもそもアノテーションがどのように定義されているのか」について知る機会は少ないのではないでしょうか。
アノテーションの構造を知っていればサンプルソースを見たときになぜそのように書くのかが理解でき、応用もきくはずです。
そこで、このシリーズでは以下のステップでアノテーションについて学んでいきたいと思います。

①アノテーションの定義を知る（今回の記事）
②WebIDEのアノテーションモデラでアノテーションをつけてみる
③CDSビューに直接つける方法を確認する

##そもそも、アノテーションとは
アノテーションとは、「このデータはどのような意味、役割を持つものなのか」をUI側に伝えるものです。データを修飾するための用語(Term)を定義した辞書のようなものをVocabularyといいます。
ODataの標準で定義されている[Vocabulary](https://www.odata.org/vocabularies/)のほか、カスタムのVocabularyを定義することもできます。Fiori Elementsで使われるVocaburaryはSAPが定義したもので、定義は以下に載っています。
https://github.com/SAP/odata-vocabularies

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/5f130e3e-5d66-07f4-9e0f-13718778c202.png)
図：OData標準のVocabularyを使ったアノテーションの例

##アノテーションの構造
ここでは、[UI Vocabulary](https://github.com/SAP/odata-vocabularies/blob/master/vocabularies/UI.md)に属するアノテーションについて見ていきます。
上記のリンク先に、UIアノテーションで使う用語の一覧が載っています。
Typeの部分を見てみると、大きく分けて3種類あることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/b4a7cb91-7a41-07ed-18d9-f23832b986d2.png)

①型(Type)として定義されているもの
②特定のTypeの集合であるもの(Collection)
③Tag

###①型(Type)として定義されているもの
TypeはABAPでいうところの構造のようなもので、複数の項目からできています。
HeaderInfoTypeの定義を見てみると、以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/428c0700-dda6-4680-27b6-17c236d1a025.png)

以下はHeaderInfoを使ったアノテーションの例です。`<Annotation Term="UI.HeaderInfo">`の配下にHeaderInfoTypeで定義された項目が配置されていることがわかります。

```xml
<Annotation Term="UI.HeaderInfo">
	<Record>
		<PropertyValue Property="TypeName" String="Product"/>
		<PropertyValue Property="TypeNamePlural" String="Products"/>
		<PropertyValue Property="ImageUrl" Path="ProductPictureURL"/>
		<PropertyValue Property="Title"
			<Record Type="UI.DataField">
				<PropertyValue Property="Value" Path="to_ProductTextInCurrentLang/Name"/>
			</Record>
		</PropertyValue>
		PropertyValue Property="Description">
			<Record Type="UI.DataField">
				<PropertyValue Property="Value" Path="Product"/>
			</Record>
		</PropertyValue>
	</Record>
</Annotation>	
```
[SAPUI5 SDK: Setting up the Object Page Header](https://sapui5.hana.ondemand.com/#/topic/cce93e6f067a4133a8430c4f5d7b8fc7.html)より

###②特定のTypeの集合であるもの(Collection)
特定のTypeの集合であるものには、FacetやLineItemなどがあります。この種類のTermは決まった型のレコードをいくつでも持つことができます。
たとえば、List ReportでおなじみのLineItemはDataFieldAbstract型のレコードを複数持ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/10bff7cc-55a9-f665-e2d7-c95840b68153.png)

以下はLineItemを使ったアノテーションの例です。DataFieldとつくレコードの集合であることがわかります。

```xml
<Annotation Term="com.sap.vocabularies.UI.v1.LineItem">
    <Collection>
        <Record Type="com.sap.vocabularies.UI.v1.DataField">
            <PropertyValue Property="Label" String="Sales Order ID"/>
            <PropertyValue Property="Value" Path="SalesOrderID"/>
        </Record>
        <Record Type="com.sap.vocabularies.UI.v1.DataField">
            <PropertyValue Property="Label" String="Customer Name"/>
            <PropertyValue Property="Value" Path="CustomerName"/>
        </Record>
        <Record Type="com.sap.vocabularies.UI.v1.DataField">
            <PropertyValue Property="Label" String="Status"/>
            <PropertyValue Property="Value" Path="Status"/>
        </Record>
        <Record Type="com.sap.vocabularies.UI.v1.DataFieldForAnnotation" Qualifier="TotalSum">
            <PropertyValue Property="Label" String="Total Sum"/>
            <PropertyValue Property="Target" AnnotationPath="@com.sap.vocabularies.UI.v1.DataPoint#TotalSum"/>
        </Record>
        <Record Type="com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation">
            <PropertyValue Property="SemanticObject" String="Action"/>
            <PropertyValue Property="Action" String="toappnavsample2"/>
            <PropertyValue Property="Label" String="SO Navigation (M)"/>
            <Annotation Term="com.sap.vocabularies.UI.v1.Importance" EnumMember="com.sap.vocabularies.UI.v1.ImportanceType/Medium"/>
        </Record>
    </Collection>
</Annotation>
```
[SAPUI5 SDK: Annotations Used in Overview Pages](https://sapui5.hana.ondemand.com/#/topic/65731e6b823240398e33133908efdaa1)より抜粋

####DataFieldAbstractとは？
Abstractとつくタイプは、オブジェクト指向における抽象クラスのようなものです。ベースとなる項目をAbstractなタイプで定義し、それを継承して個々のタイプが定義されています。
LineItemの場合、DataFieldAbstractを継承するタイプのデータを何でも持つことができます。
DataFieldAbstractを継承するタイプについては、以下を参照してください。
https://github.com/SAP/odata-vocabularies/blob/master/vocabularies/UI.md#DataFieldAbstract

###③Tag
Tagはデータ項目に意味を追加したり用途を制限する目的で使われる、boolean型の項目です。
Tagを使って項目を非表示にしたり（Hidden）、項目がURLであることを示したり（IsImageURL）することができます。

以下はHidden Tagを使ったアノテーションの例です。Tagの値は`Bool=<true/false>`で直接指定するか、`Path=<field>`でtrue/falseの値を持った項目を指定することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/5dfd358a-667a-5e15-e161-b5ba6f149eac.png)
[SAPUI5 SDK: Hiding Features Using the UI.Hidden Annotation](https://sapui5.hana.ondemand.com/#/topic/ca00ee45fe344a73998f482cb2e669bb)より


##UIアノテーションの目的
以下は私見ですが、UIアノテーションの目的には大きく2種類あると思います。

**①レイアウト・表示のためのアノテーション**
画面のどこにどんなデータを表示するのかを決める
複数のアノテーションやデータ項目を部品のように組み上げて構成する

**②データを修飾するためのアノテーション**
個々のデータ項目に対して直接修飾を行う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/b6d894a7-0f8f-99b7-5d2f-277761924ae3.png)

##まとめ

- UIアノテーションのための用語は[UI Vocabulary](https://github.com/SAP/odata-vocabularies/blob/master/vocabularies/UI.md)に定義されている
- アノテーションで使うTermの型には主に3種類ある。Type, Collection, Tag
- アノテーションの目的として、レイアウト・表示のためのアノテーションとデータを修飾するためのアノテーションがある