Java API のベストプラクティス

Adobe Experience Manager(AEM)は、開発時に使用可能な多数の Java API を公開する豊富なオープンソースソフトウェアスタックに基づいて構築されています。この記事では、主な API、およびそれらを使用するタイミングと理由について説明します。

AEMは、4 つのプライマリ Java API セットを基に構築されています。

  • Adobe Experience Manager (AEM)

    • 製品の抽象概念(ページ、アセット、ワークフローなど)。
  • Apache Sling Web Framework

    • リソース、値マップ、HTTP 要求など、REST およびリソースベースの抽象概念。
  • JCR(Apache Jackrabbit Oak)

    • ノード、プロパティ、セッションなどのデータおよびコンテンツの抽象概念。
  • OSGi(Apache Felix)

    • OSGi アプリケーションコンテナの抽象概念 ( サービスや (OSGi) コンポーネントなど )。

Java API 環境設定「経験則」

一般的なルールとして、次の順序で API/抽象を優先します。

  1. AEM
  2. Sling
  3. JCR
  4. OSGi

AEMで API が提供されている場合は、より優先します。 Sling、JCR、OSGi の 3 つのリストが含まれます。 AEMに API がない場合は、 Sling JCR および OSGi 上で

この順序は一般的なルールで、例外が存在します。 このルールから解除する理由として許容できるものは次のとおりです。

  • 以下に説明するよく知られた例外。

  • 必要な機能は、上位レベルの API では使用できません。

  • それ自体であまり優先されない API を使用している既存のコード ( カスタムまたはAEM製品コード ) のコンテキストで動作し、新しい API に移行するためのコストは不当です。

    • 混在を作成するよりも、低レベルの API を一貫して使用する方が効果的です。

AEM API

AEM API は、製品化された使用例に固有の抽象概念と機能を提供します。

例: AEM PageManager および ページ API は以下の抽象概念を提供します。 cq:Page web ページを表すAEMのノード。

これらのノードはで使用できますが、 Sling AEM API は、リソースとして API を、ノードとして JCR API を提供し、一般的な使用例の抽象概念を提供します。 AEM API を使用すると、AEMと製品の間で、カスタマイズとAEMの拡張の間で一貫した動作がおこなわれます。

com.adobe.と com.day の比較。 API

AEM API は、パッケージ内の環境設定を持ち、次の Java パッケージで識別されます(好みの順)。

  1. com.adobe.cq
  2. com.adobe.granite
  3. com.day.cq

com.adobe.cq は製品のユースケースをサポートし、は com.adobe.granite は、ワークフローやタスクなど、製品をまたいだプラットフォームの使用例(製品全体で使用される)をサポートします。AEM Assets、サイトなど )。

com.day.cq には、「オリジナル」の API が含まれています。 これらの API は、Adobeが Day CQ. これらの API はサポートされており、回避する必要はありません ( ただし、 com.adobe.cq または com.adobe.granite (新しい)代替案を提供する。

次のような新しい抽象概念 Content Fragments および Experience Fragments は com.adobe.cq ~ではなく空間 com.day.cq 以下に説明します。

クエリ API

AEMは複数のクエリ言語をサポートしています。 3 つの主要言語は、 JCR-SQL2、XPath および AEM Query Builder.

最も重要な問題は、コードベース全体で一貫性のあるクエリ言語を維持し、理解するための複雑さとコストを軽減することです。

すべてのクエリ言語は、 Apache Oak 最終的なクエリ実行のために JCR-SQL2 にトランスパイルします。JCR-SQL2 への変換時間は、クエリ時間自体に比べて非常に短い時間です。

推奨される API は次のとおりです。 AEM Query Builder:最高レベルの抽象化で、クエリの結果を構築、実行および取得するための堅牢な API を提供し、次の機能を提供します。

注意

AEM QueryBuilder API は、ResourceResolver オブジェクトをリークします。 この漏れを軽減するには、次の手順に従います コードサンプル.

Sling API

Apache Sling は、AEMを支える RESTful Web フレームワークです。 Sling は、HTTP リクエストルーティングを提供し、JCR ノードをリソースとしてモデル化し、セキュリティコンテキストなどを提供します。

Sling API には拡張機能向けにビルドされるというメリットが追加されています。つまり、を使用してビルドされたアプリケーションの動作を容易かつ安全に拡張できます。 Sling 拡張性の低い JCR API よりも API が多い。

の一般的な使用例 Sling API

JCR API

この JCR(Java Content Repository)2.0 API は、JCR 実装の仕様の一部です (AEMの場合、 Apache Jackrabbit Oak) をクリックします。 すべての JCR 実装は、これらの API に準拠し実装する必要があります。したがって、AEMコンテンツを操作するための最も低レベルの API です。

JCR 自体は、階層/ツリーベースの NoSQL データストアAEMで、がコンテンツリポジトリとして使用します。 JCR には、コンテンツ CRUD からコンテンツのクエリまで、様々なサポートされている API が多数あります。 この堅牢な API にもかかわらず、上位レベルのAEMや Sling 抽象概念

Apache Jackrabbit Oak API よりも JCR API を常に優先します。 JCR API は、 対話 JCR リポジトリを使用し、Oak API は 実装 JCR リポジトリ。

JCR API に関する一般的な誤解

JCR はAEMコンテンツリポジトリですが、API はコンテンツを操作する際の推奨される方法ではありません。 代わりに、AEM API(ページ、アセット、タグなど)を または Sling Resource API を使用すると、より優れた抽象概念が提供されます。

注意

AEMアプリケーションでの JCR API のセッションおよびノードインターフェイスの幅広い使用は、コードスメルです。 確認 Sling 代わりに API を使用しないでください。

JCR API の一般的な使用例

OSGi API

OSGi API と上位レベルの API(AEM、 Sling、 、JCR など )、および OSGi API を使用する必要はまれで、高レベルのAEM開発専門知識が必要です。

OSGi と Apache Felix API の比較

OSGi は、すべての OSGi コンテナが実装し、準拠する必要がある仕様を定義します。 AEM OSGi 実装の Apache Felix は、独自の API もいくつか提供しています。

  • OSGi API を優先 (org.osgi) を Apache Felix API 経由 (org.apache.felix) をクリックします。

OSGi API の一般的な使用例

ルールの例外

次に、上記の規則に対する一般的な例外を示します。

OSGi API

OSGi コンポーネントプロパティでの定義や読み取りなど、低レベルの OSGi 抽象概念を扱う場合、次の方法で提供される新しい抽象概念 org.osgi は、上位レベルの Sling スクラクションよりも優先されます。 競合する Sling の抽象概念は、 @Deprecated そして、 org.osgi 代替案。

また、OSGi 設定ノードの定義の方が優先される点にも注意してください。 cfg.jsonsling:OsgiConfig 形式

AEM Asset API

  • 優先 com.day.cq.dam.api over com.adobe.granite.asset.api.

    • また、 com.day.cq Assets API には、AEM Asset Management のユースケース向けのより包括的なツールが用意されています。
    • Granite Assets API は、低レベルのアセット管理ユースケース(バージョン、関係)をサポートしています。

クエリ API

  • AEM QueryBuilder は、次のような特定のクエリ関数をサポートしていません。 候補、スペルチェックやインデックスヒントなど、一般的でない関数を示します。 これらの関数でクエリを実行する場合は、JCR-SQL2 をお勧めします。

Sling サーブレットの登録

Sling フィルター登録

便利なコードスニペット

以下は、API を使用した一般的な使用例のベストプラクティスを説明する Java コードスニペットです。 また、これらのスニペットでは、優先度の低い API からより優先度の高い API に移行する方法を説明しています。

JCR セッションの実行先 Sling ResourceResolver

Sling ResourceResolver を自動終了する

AEM 6.2 以降、 Sling ResourceResolver は AutoClosabletry-with-resources 文。 この構文を使用すると、 resourceResolver .close() は不要です。

@Reference
ResourceResolverFactory rrf;
...
Map<String, Object> authInfo = new HashMap<String, Object>();
authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_SESSION, jcrSession);

try (ResourceResolver resourceResolver = rrf.getResourceResolver(authInfo)) {
    // Do work with the resourceResolver
} catch (LoginException e) { .. }

手動で閉じた Sling ResourceResolver

ResourceResolvers は、 finally ブロック内に含める必要があります。

@Reference
ResourceResolverFactory rrf;
...
Map<String, Object> authInfo = new HashMap<String, Object>();
authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_SESSION, jcrSession);

ResourceResolver resourceResolver = null;

try {
    resourceResolver = rrf.getResourceResolver(authInfo);
    // Do work with the resourceResolver
} catch (LoginException e) {
   ...
} finally {
    if (resourceResolver != null) { resourceResolver.close(); }
}

JCR パス: Sling Resource

Resource resource = ResourceResolver.getResource("/path/to/the/resource");

JCR ノードを Sling Resource

Resource resource = resourceResolver.getResource(node.getPath());

Sling Resource アセットをAEM

推奨されるアプローチ

DamUtil.resolveToAsset(..)下のリソースを解決します。 dam:Asset 必要に応じてツリーを上に移動して、Asset オブジェクトに移動します。

Asset asset = DamUtil.resolveToAsset(resource);

別のアプローチ

リソースをアセットに適応させるには、リソース自体が dam:Asset ノード。

Asset asset = resource.adaptTo(Asset.class);

Sling リソースからAEMページ

推奨されるアプローチ

pageManager.getContainingPage(..) 下のリソースを解決します。 cq:Page 必要に応じてツリーの上に移動し、ページオブジェクトに移動します。

PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page page = pageManager.getContainingPage(resource);
Page page2 = pageManager.getContainingPage("/content/path/to/page/jcr:content/or/component");

別のアプローチ

リソースをページに適応させるには、リソース自体が cq:Page ノード。

Page page = resource.adaptTo(Page.class);

読み取りAEM Page プロパティ

Page オブジェクトの getter を使用して、よく知られているプロパティ (getTitle(), getDescription()など ) および page.getProperties() を取得する [cq:Page]/jcr:content 他のプロパティを取得するための ValueMap。

Page page = resource.adaptTo(Page.class);
String title = page.getTitle();
Calendar value = page.getProperties().get("cq:lastModified", Calendar.getInstance());

AEM Asset メタデータプロパティの読み取り

Asset API には、 [dam:Asset]/jcr:content/metadata ノード。 これは ValueMap ではなく、2 番目のパラメータ(デフォルト値、自動タイプキャスト)はサポートされていないことに注意してください。

Asset asset = resource.adaptTo(Asset.class);
String title = asset.getMetadataValue("dc:title");
Calendar lastModified = (Calendar) asset.getMetadata("cq:lastModified");

読み取り Sling Resource プロパティ

AEM API(ページ、アセット)が直接アクセスできない場所(プロパティまたは相対リソース)にプロパティが保存されている場合、 Sling リソースと値マップを使用して、データを取得できます。

ValueMap properties = resource.getValueMap();
String value = properties.get("jcr:title", "Default title");
String relativeResourceValue = properties.get("relative/propertyName", "Default value");

この場合、AEMオブジェクトを Sling Resource 目的のプロパティまたはサブリソースを効率的に見つけ出す。

AEMページ Sling Resource

Resource resource = page.adaptTo(Resource.class);

アセットのAEM先 Sling Resource

Resource resource = asset.adaptTo(Resource.class);

を使用してプロパティを書き込む Sling's ModifiableValueMap

用途 Sling's ModifiableValueMap ノードにプロパティを書き込みます。 これは、即時ノードにのみ書き込むことができます(相対プロパティパスはサポートされていません)。

への呼び出しに注意してください。 .adaptTo(ModifiableValueMap.class) にはリソースへの書き込み権限が必要です。権限がない場合は null が返されます。

ModifiableValueMap properties = resource.adaptTo(ModifiableValueMap.class);

properties.put("newPropertyName", "new value");
properties.put("propertyNameToUpdate", "updated value");
properties.remove("propertyToRemove");

resource.getResourceResolver().commit();

AEMページの作成

AEMでページを適切に定義および初期化するには、ページテンプレートを取るページを作成する場合は、必ず PageManager を使用してください。

String templatePath = "/conf/my-app/settings/wcm/templates/content-page";
boolean autoSave = true;

PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
pageManager.create("/content/parent/path", "my-new-page", templatePath, "My New Page Title", autoSave);

if (!autoSave) { resourceResolver.commit(); }

の作成 Sling リソース

ResourceResolver は、リソースを作成するための基本的な操作をサポートします。 より高いレベルの抽象概念 (AEMページ、アセット、タグなど ) を作成する場合、 それぞれの管理者が提供する方法を使用します。

resourceResolver.create(parentResource, "my-node-name", new ImmutableMap.Builder<String, Object>()
           .put("jcr:primaryType", "nt:unstructured")
           .put("jcr:title", "Hello world")
           .put("propertyName", "Other initial properties")
           .build());

resourceResolver.commit();

の削除 Sling リソース

ResourceResolver は、リソースの削除をサポートします。 上位レベルの抽象概念 (AEMページ、アセット、タグなど ) を作成する場合、 それぞれの管理者が提供する方法を使用します。

resourceResolver.delete(resource);

resourceResolver.commit();

このページ