tag:blogger.com,1999:blog-32741021681398026132024-03-05T19:43:16.591+09:00aegif Labo Blogaegif-labohttp://www.blogger.com/profile/02743430411685630332noreply@blogger.comBlogger248125tag:blogger.com,1999:blog-3274102168139802613.post-45849602305862550472020-09-25T10:30:00.002+09:002022-08-17T16:56:04.595+09:00Alfrescoのプレビューで日本語が文字化けする問題<p>
こんにちは。てらしたです。今回はAlfrescoのプレビューで日本語が文字化けしてしまう問題の原因と修正方法をご紹介します。201911GAをDocker
Composeで起動した場合(やり方は<a href="http://labo-blog.aegif.jp/2020/03/alfresco-community-edition.html" target="_blank">こちらの記事</a>を参照)を例にご説明しますが、インストール方法によってはDocker
Composeを使っていなくても起こり得る問題だと思います。
</p>
<p>
まずはどのような問題なのかを見ていきます。Alfrescoに日本語を含むテキストファイルをアップロードしてドキュメントの詳細画面を開きます。すると、プレビューでこのように日本語部分が文字化けして正常に表示されません。
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8PwlqNQOquwYIqNg99Sm9k-vIcZB6fULNvy1HMJognPIEuO9IOhkRzXXdcihcZ7zQpY-yezLzPFDxEnk1BksJkzbT1F488-_QJtjLq26DnAmxxw7V9RNtMBELz-oS6MoJXTmnx9n1SLQWVMZilNwwtukLQ_uS3nsQRa-b_SLgG7IreaAEbvszSFTr/s1864/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-09-08%2022.26.30.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="708" data-original-width="1864" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8PwlqNQOquwYIqNg99Sm9k-vIcZB6fULNvy1HMJognPIEuO9IOhkRzXXdcihcZ7zQpY-yezLzPFDxEnk1BksJkzbT1F488-_QJtjLq26DnAmxxw7V9RNtMBELz-oS6MoJXTmnx9n1SLQWVMZilNwwtukLQ_uS3nsQRa-b_SLgG7IreaAEbvszSFTr/w536-h205/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-09-08%2022.26.30.png" width="536" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div>
<p>試しにPowerPointのファイルをアップロードしてみても同じです。</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMKCozilDLX-CeVgsa1CA63qdu1S-Th4M_0JtbIpG93ij_wEkVj2woGYlApkcHchfqBAbC2Yv1nZHED1oPNjVSi3oW5WrwK8A6xI4WPrt18uAvtsZRTHOiebvYkF4TtijshoUsZl7egWNKoMJ42abylvVE7yzGpKfJVn-QKgniRHj_tTF0NB5G84H0/s1864/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-09-08%2022.29.51.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1168" data-original-width="1864" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMKCozilDLX-CeVgsa1CA63qdu1S-Th4M_0JtbIpG93ij_wEkVj2woGYlApkcHchfqBAbC2Yv1nZHED1oPNjVSi3oW5WrwK8A6xI4WPrt18uAvtsZRTHOiebvYkF4TtijshoUsZl7egWNKoMJ42abylvVE7yzGpKfJVn-QKgniRHj_tTF0NB5G84H0/w384-h241/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-09-08%2022.29.51.png" width="384" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<p>
これは、LibreOfficeが実行されているコンテナに日本語フォントがインストールされていないことが原因のようです(LibreOfficeはテキストファイルやMS Officeファイルの変換に使用されています)。そのため、このコンテナに日本語フォントをインストールしてあげれば解決するはずです。
</p>
<p>
まずLibreOffice用のコンテナにroot権限で入ります(コンテナ名やコンテナIDは
docker ps で調べます)。
</p>
<pre class="brush:bash">docker exec -it docker-compose_libreoffice_1 /bin/bash
</pre>
<p>入ったらIPAフォントをインストールします。</p>
<pre class="brush:bash"> yum -y install ipa-gothic-fonts ipa-pgothic-fonts ipa-mincho-fonts ipa-pmincho-fonts
</pre>
<p>
インストールできたら、コンテナを再起動します。再起動するのはLibreOfficeコンテナだけで大丈夫です。起動したら先ほどと同じファイルをアップロードしてプレビューを確認してみます。
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaROIE660b21HPApdcZbNU5vyAwRsBGmdK_coqKlppXP5z_6sQ90hztRmsE_-XtII3iRJhVmSGUfNXLTIVX-VkdgviwuaQHYSVK-jGi-NSgwv4yh8BMHXqAMN-buRsIXl-cxTPM1EKvNn6RVyJWBwwcFTg1d5JnhfGb6yfT9_60IYfwsVCbXCdwZxh/s1864/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-09-08%2022.59.02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="716" data-original-width="1864" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaROIE660b21HPApdcZbNU5vyAwRsBGmdK_coqKlppXP5z_6sQ90hztRmsE_-XtII3iRJhVmSGUfNXLTIVX-VkdgviwuaQHYSVK-jGi-NSgwv4yh8BMHXqAMN-buRsIXl-cxTPM1EKvNn6RVyJWBwwcFTg1d5JnhfGb6yfT9_60IYfwsVCbXCdwZxh/w532-h204/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-09-08%2022.59.02.png" width="532" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div>
<p>このようにテキストファイルも、</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiNjsGZtW0J53T2bD2k73ZYHqmM_XXHm-XurZGuBzM48Nm2DsLTm0k3OtD_bIBNmDPvQVr21D_XhH-giPOxO3Ayu5qk76qDWgc_ytzoGqrU2GJhWTdw1kwb-WssQQEReDOlhwU9Dv9uNEcnEG9ozREq18oaUuzieyEkxb2GTpe0X6RGjVO1ep1PMNl/s1864/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-09-08%2023.00.53.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1178" data-original-width="1864" height="254" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiNjsGZtW0J53T2bD2k73ZYHqmM_XXHm-XurZGuBzM48Nm2DsLTm0k3OtD_bIBNmDPvQVr21D_XhH-giPOxO3Ayu5qk76qDWgc_ytzoGqrU2GJhWTdw1kwb-WssQQEReDOlhwU9Dv9uNEcnEG9ozREq18oaUuzieyEkxb2GTpe0X6RGjVO1ep1PMNl/w403-h254/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-09-08%2023.00.53.png" width="403" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div>
<p>PowerPointファイルも無事に文字化けが解消されていました。</p>
<p>
フォントをインストールすれば無事に解消できることが確認できたので、コンテナを作り直すたびに手作業でフォントをインストールしなくてもいいようにDockerfileを作ってdocker-compose.ymlをちょっと修正します。
</p>
<p>
まず、docker-compose.ymlのあるディレクトリにlibreofficeディレクトリを作成し、そこに以下の内容を記載したDockerfileを作成します。
</p>
<pre class="brush:bash">FROM alfresco/alfresco-libreoffice:2.1.0
USER root
RUN yum install -y \
ipa-gothic-fonts \
ipa-pgothic-fonts \
ipa-mincho-fonts \
ipa-pmincho-fonts \
&&yum clean all
USER libreoffice
</pre>
<p>
元のDockerfileでは最終的にlibreofficeユーザになっているのでrootに変更してフォントをインストールしたらlibreofficeユーザに戻るという操作をしています。
</p>
<p>次に、docker-compose.ymlの以下の部分を</p>
<pre class="brush:bash">libreoffice:
image: alfresco/alfresco-libreoffice:2.1.0
mem_limit: 1g
...
</pre>
<p>
このように書き換えます(image名は好きにつけてもらって大丈夫です)。
</p>
<pre class="brush:bash">libreoffice:
image: custom-alfresco-libreoffice:2.1.0
build:
dockerfile: Dockerfile
context: ./libreoffice
mem_limit: 1g
...
</pre>
<p>
修正して保存したらコンテナを作り直して動作確認をしてみます。LibreOfficeコンテナだけ作り直せばよいはずですが、キャッシュの影響等でうまく再構築してくれないとか、他の問題が絡んでくるとわかりにくくなってしまうので、ここでは docker-compose down でコンテナを一掃してから docker-compose up で起動し直しました。Alfrescoのデータは残しておきたいとか、状況によっては docker-compose down は使えないと思うので、状況に合わせてコマンドは適当に変えていただければと思います。
</p>
<p>
起動したら同様にファイルをアップロードして、プレビューが文字化けしていなかったら成功です(結果は上と同じなのでスクリーンショットは省略)。
</p>
Jun Terashitahttp://www.blogger.com/profile/09039721862238185320noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-501129192435022972020-09-07T18:00:00.009+09:002022-08-17T17:07:04.217+09:00Liferay 7とMicrosoft365(Office365)を連携させてOfficeファイルをオンライン編集する<div style="text-align: left;">こんにちは。おおたにです。</div>
<div style="text-align: left;"><br /></div>
<div style="text-align: left;">
今も昔も仕事でMicrosoft
Officeを利用しているユーザは多いと思いますが、今やその月額/年額サブスクリプションサービスであるMicrosoft
365(旧Office 365)をご利用の会社も多いかと思います。今回はそのMicrosoft
365(旧Office
365)とLiferayのドキュメントライブラリ(ファイル管理機能)の連携機能について紹介したいと思います。
</div>
<div style="text-align: left;">
なお、この機能はLiferay DXP
7.2で新しく追加された機能になります。実際に試してみたい方はLiferayDXP
7.2以降でお試しください。
</div>
<div style="text-align: left;"><br /></div>
<div style="text-align: left;">
また、LiferayはGoogle Drive/Google
Docsとの連携機能も備えており、これらのサービスを用いてOfficeファイルをオンライン編集することもできます。具体的な設定方法については別の記事<a href="http://labo-blog.aegif.jp/2020/08/liferay-7google-drive-google-docs.html" target="_blank">「Liferay 7とGoogle Drive / Google Docsを連携させる」</a>を参考にしてください。
</div>
<div style="text-align: left;"><br /></div>
<h3 style="text-align: left;">
Microsoft 365(Office365)連携機能で実現できること
</h3>
<div style="text-align: left;"><br /></div>
<div style="text-align: left;">
LiferayのドキュメントライブラリとMicrosoft
365を連携すると、ドキュメントライブラリ上のOfficeファイルをMicrosoft
365を利用してオンライン編集できるようになります。具体的には以下のことができます。
</div>
<div style="text-align: left;">
<ul style="text-align: left;">
<li>
Microsoft
365を使い、新規Wordファイル(.docx)、新規Excelファイル(.xlsx)、新規PowerPointファイル(.pptx)をブラウザ上で作成する
</li>
<li>作成したファイルをドキュメントライブラリに保存する</li>
<li>
ドキュメントライブラリ上の以下の形式のファイルをMicrosoft
365を使ってブラウザ上で編集する。
</li>
<ul>
<li>
Word/テキスト系ファイル(.doc, .docx, .docm, .dot, .dotx, .dotm, .html,
.txt, .rtf, .odt)
</li>
<li>
PowerPoint/スライド系ファイル(.ppt, .pptx, .pptm, .pps, .ppsx, .ppsm,
.pot, .potx, .potm)
</li>
<li>
Excel/シート系ファイル(.xls, .xlsx, .xlsm, .xlt, .xltx, .xltm, .ods,
.csv, .tsv, .txt, .tab)
</li>
</ul>
</ul>
</div>
<div style="text-align: left;">
なお、Microsoft
365でファイル編集を開始するとOneDrive上にファイルがコピーされ、Microsoft
365でファイル編集を終えるとOneDrive上のファイルは削除されます。詳しい説明はLiferayヘルプセンターの<a href="https://help.liferay.com/hc/ja/articles/360034856711-Integration-with-Microsoft-Office-365-" target="_blank">この記事</a>や<a href="https://help.liferay.com/hc/ja/articles/360034473812-Creating-and-Editing-Documents-and-Media-Files-with-Office-365-" target="_blank">この記事</a>をご参照ください。
</div>
<div style="text-align: left;"><br /></div>
<h3 style="text-align: left;">Azure PortalでMicrosoft 365の連携設定を行う</h3>
<div style="text-align: left;"><br /></div>
<div style="text-align: left;">
では早速設定方法を見ていきましょう。まずはAzure PortalでMicrosoft
365側の設定を行います。具体的には、Microsoft Graph
APIをLiferayが利用できるように公開し、Liferay向けにOAuth2.0クライアントIDを発行します。
</div>
<div style="text-align: left;"><br /></div>
<div style="text-align: left;">
1. <a href="https://portal.azure.com/" target="_blank">Azure Portal</a>に管理者アカウントでログインする
</div>
<div style="text-align: left;">
2. Azure Active
Directoryをクリックし、「アプリの登録」->「新規登録」をクリックする
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7lgp8yMHe7nbAD8Bv-iWQclAdVuQnai6IQ5vL_kghv51Dr_qN-KLHoygX9A3WSScNP4rVpC_McdqA_Voft0toSQ2dwNQTd16uVaCsoqkjNFObQnUtAinFdrltoFiUZJZo778f7DHKGvzCVAiFfApPayhU76lzspEKHRHGN3OrwE91sb7yebIHJSYC/s888/skitch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="599" data-original-width="888" height="287" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7lgp8yMHe7nbAD8Bv-iWQclAdVuQnai6IQ5vL_kghv51Dr_qN-KLHoygX9A3WSScNP4rVpC_McdqA_Voft0toSQ2dwNQTd16uVaCsoqkjNFObQnUtAinFdrltoFiUZJZo778f7DHKGvzCVAiFfApPayhU76lzspEKHRHGN3OrwE91sb7yebIHJSYC/w425-h287/skitch.png" width="425" /></a></div>
<div style="text-align: left;">
3.
「名前」にアプリケーション名を入力し(認証時に表示されます)、「アカウントの種類」を適宜選択して「登録」をクリックする
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjei1W9OhXfLsgflc35mDT9W5H-un7k8AkK4nD8RLbDQKUtiMws1EYjDuIJ-jFo_SHZgsImSd11mk6dkCFWcPHVrxwz3lbhEz1LnSSHGTBMiWqmxkrNcwOkpTrYLYcGfPnQGXC3hu_az7ufeUyA027ho34VjvtFMBvDIaHfCoWH0YxY9fa5GdE7J_g3/s827/skitch2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="569" data-original-width="827" height="294" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjei1W9OhXfLsgflc35mDT9W5H-un7k8AkK4nD8RLbDQKUtiMws1EYjDuIJ-jFo_SHZgsImSd11mk6dkCFWcPHVrxwz3lbhEz1LnSSHGTBMiWqmxkrNcwOkpTrYLYcGfPnQGXC3hu_az7ufeUyA027ho34VjvtFMBvDIaHfCoWH0YxY9fa5GdE7J_g3/w427-h294/skitch2.png" width="427" /></a></div>
<div style="text-align: left;">
4.
作成が完了すると以下のような画面が表示されるので、「アプリケーション(クライアント)ID」「ディレクトリ(テナント)ID」の値をコピーし、「リダイレクトURIを追加する」をクリックする
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCM9ucjmGGnpM6o9fApn_aMXfgmzrl2OTjYuzroZwAokl0S7wOHS7VQRUOezNH6oUjbTtWe-TE_KhwajgwxojXrvaY68SobHrGDzlkO4PqcgWDIHxh4BzjtatusHBZt7vL8eav9mvz_ZSS8y4N9ZPSi215PGcWQa718VhBm9uJFPmI-rfwFcg1EFy/s1077/skitch10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="552" data-original-width="1077" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCM9ucjmGGnpM6o9fApn_aMXfgmzrl2OTjYuzroZwAokl0S7wOHS7VQRUOezNH6oUjbTtWe-TE_KhwajgwxojXrvaY68SobHrGDzlkO4PqcgWDIHxh4BzjtatusHBZt7vL8eav9mvz_ZSS8y4N9ZPSi215PGcWQa718VhBm9uJFPmI-rfwFcg1EFy/w400-h205/skitch10.png" width="400" /></a></div>
<div style="text-align: left;">
5. 「プラットフォームを追加」をクリックして「Web」を選択する
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpABVAjILtXNs086L_zs6H2xvD002r3BaUUNzFKad-kEMDtYZzlwMVp2vX96ZGqeyGH96o9lnrGoCov7wCazR4jxy4sdnW9QFMyEhcNqzxKxAI3D-B-262AIApJT7J5ya3YJhg1MzSQ1P5s3NS1Kqz-14siORUPxzw5bvaPSQNXTwbIijze_DyrWgS/s1012/skitch4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="691" data-original-width="1012" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpABVAjILtXNs086L_zs6H2xvD002r3BaUUNzFKad-kEMDtYZzlwMVp2vX96ZGqeyGH96o9lnrGoCov7wCazR4jxy4sdnW9QFMyEhcNqzxKxAI3D-B-262AIApJT7J5ya3YJhg1MzSQ1P5s3NS1Kqz-14siORUPxzw5bvaPSQNXTwbIijze_DyrWgS/w400-h272/skitch4.png" width="400" /></a></div>
<div style="text-align: left;">
6. 「リダイレクト URI」に<code>http(s)://<host or
IP>:<port>/o/document_library/onedrive/oauth2</code>と入力して「構成」をクリックする
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhWF0kB_zaiGoJWgaiKd53_MY5naOjX9x44jQPDiKedPBUkK8CIwkCsmNlUv4hnZ_C1-2aWKoahgOZPwdYAvI3HajmOVZrbsRib0BSHZndFtumvEkjcb0Ku3UnndJBiLIKnfsLZNOxRuTrECNPxykJmV0D3IOlK7Sd41RxLHc61_BdO6yghzYpMX1Q/s731/skitch5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="731" data-original-width="570" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhWF0kB_zaiGoJWgaiKd53_MY5naOjX9x44jQPDiKedPBUkK8CIwkCsmNlUv4hnZ_C1-2aWKoahgOZPwdYAvI3HajmOVZrbsRib0BSHZndFtumvEkjcb0Ku3UnndJBiLIKnfsLZNOxRuTrECNPxykJmV0D3IOlK7Sd41RxLHc61_BdO6yghzYpMX1Q/w313-h400/skitch5.png" width="313" /></a></div>
<div style="text-align: left;">
7.
「証明書とシークレット」->「新しいクライアントシークレット」をクリックし、「説明」と「有効期限」を適宜入力して「追加」をクリックする
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGbbeQMIZiMdhhDqOeTzuu3o6dycoO6qqxvFjJt0efTQxD7JRjg_dZRY44kV12fNja3FfB0dZyT5xmfWuEduvuiBe6-pu_AE6tYReFdPHcS5RKUKLS_889QQE0TQT9Xcc1pQtHeiWaGig25LqhCLjRWxoqh6LiikXRBccjIF8E3So3KdvZPP-zYJW0/s1071/skitch6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="614" data-original-width="1071" height="267" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGbbeQMIZiMdhhDqOeTzuu3o6dycoO6qqxvFjJt0efTQxD7JRjg_dZRY44kV12fNja3FfB0dZyT5xmfWuEduvuiBe6-pu_AE6tYReFdPHcS5RKUKLS_889QQE0TQT9Xcc1pQtHeiWaGig25LqhCLjRWxoqh6LiikXRBccjIF8E3So3KdvZPP-zYJW0/w466-h267/skitch6.png" width="466" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<div style="text-align: left;">
8.
クライアントシークレットが登録されたら「値」欄に表示されたクライアントシークレットをコピーする
</div>
<div style="text-align: left;">
9. 続いて「APIのアクセス許可」->「アクセス許可の追加」をクリックする
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM5YLPME-oCzHAFzSlInmd0O_JYze_klB9TAckS2g_6DTBpjmkTaZ9uO0I_in_mUXuxZj9IEMJCfUmegxp_ILxGRFIdmYnc5nFeASmZ9XkJhYTTc25QlRjfNN00p1QqfX6ujyzd23wHxWMkxoRcRlWEB1YysBmoRoAgnlsJ-IOKEhkOXTbU5hGa_Ms/s1077/skitch7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="452" data-original-width="1077" height="203" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM5YLPME-oCzHAFzSlInmd0O_JYze_klB9TAckS2g_6DTBpjmkTaZ9uO0I_in_mUXuxZj9IEMJCfUmegxp_ILxGRFIdmYnc5nFeASmZ9XkJhYTTc25QlRjfNN00p1QqfX6ujyzd23wHxWMkxoRcRlWEB1YysBmoRoAgnlsJ-IOKEhkOXTbU5hGa_Ms/w485-h203/skitch7.png" width="485" /></a></div>
<div style="text-align: left;">10. 「Microsoft Graph API」をクリックする</div>
<div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSI273therlXSExoH889x65LhYEGO12b0HMVDHCwj_ap2ddSaKnaQIXFFKIxJYhNTjrIyUctnZXs79INPPr714ZB__3hlcNrXAtetMlJp1G7JG-vK2pJ2-BvlC3CSYCgIEBp6LjfcK-MzuOEDapEU32wGJd8ATksdbzWtHaiU3Iyd7VZKK1H4zLfdl/s1026/skitch8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="482" data-original-width="1026" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSI273therlXSExoH889x65LhYEGO12b0HMVDHCwj_ap2ddSaKnaQIXFFKIxJYhNTjrIyUctnZXs79INPPr714ZB__3hlcNrXAtetMlJp1G7JG-vK2pJ2-BvlC3CSYCgIEBp6LjfcK-MzuOEDapEU32wGJd8ATksdbzWtHaiU3Iyd7VZKK1H4zLfdl/w416-h195/skitch8.png" width="416" /></a></div>
</div>
<div style="text-align: left;">
11.
「委任されたアクセス許可」を選択し、<code>Files.Read.All</code>と<code>Files.ReadWrite.All</code>にチェックを入れて「アクセス許可の追加」をクリックする
</div>
<div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE6NJAK3Qp3AlvSXW1HFyJB87lViXj6lOTjAQXyniE4KzFjdcbioWBXwvpSMzM7Spimtw1JjrfgWfKEkqdydkIlGFCf5dfjsVnTDP6A1uSDbPoDz-6BXPhaikmDV2SchiyfkQpTQDs95-5-jVe8SFY0AIa131rx-cZJTmy1lM-Yx0jSWzzMnAg3QNn/s1069/skitch9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="739" data-original-width="1069" height="291" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE6NJAK3Qp3AlvSXW1HFyJB87lViXj6lOTjAQXyniE4KzFjdcbioWBXwvpSMzM7Spimtw1JjrfgWfKEkqdydkIlGFCf5dfjsVnTDP6A1uSDbPoDz-6BXPhaikmDV2SchiyfkQpTQDs95-5-jVe8SFY0AIa131rx-cZJTmy1lM-Yx0jSWzzMnAg3QNn/w421-h291/skitch9.png" width="421" /></a></div></div>
<div style="text-align: left;">以上でMicrosoft 365側の設定は終わりです。</div>
<div style="text-align: left;"><br /></div>
<h3 style="text-align: left;">Liferayの設定を行う</h3>
<div style="text-align: left;"><br /></div>
<div style="text-align: left;">続いて、Liferay側の設定を行います。</div>
<div style="text-align: left;"><br /></div>
<div style="text-align: left;">
<div>1. Liferay DXP 7.2に管理者でログインする</div>
<div>
2. 「Control Panel」->「Configuration」->「Instance
Settings」->「Documents and
Media」をクリックする(この場合、インスタンス毎の設定になります。グローバルに設定する場合は「System
Settings」->「Documents and Media」をクリックします)
</div>
</div>
<div style="text-align: left;">
<div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj63hW-TQQrlQdkmL1R5mRo3H6WauKLDxDOrFQzyaAqydSLBxht_nSnW3TUL1W9c1b_5r0hHVajUaSBDAy9wzsQkdexK4PUO85n02n6OzG15T5gkCwOt03cPzGrkA_XUb2d_fK5gBbXL7sUXmlVcSlml-6cdriGP7zzqfTvK6BynYho9yvhiTaovFc8/s1230/ScreenClip0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="421" data-original-width="1230" height="144" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj63hW-TQQrlQdkmL1R5mRo3H6WauKLDxDOrFQzyaAqydSLBxht_nSnW3TUL1W9c1b_5r0hHVajUaSBDAy9wzsQkdexK4PUO85n02n6OzG15T5gkCwOt03cPzGrkA_XUb2d_fK5gBbXL7sUXmlVcSlml-6cdriGP7zzqfTvK6BynYho9yvhiTaovFc8/w419-h144/ScreenClip0.png" width="419" /></a></div>
</div>
<div>
3. 「OneDrive」を選択し、Client
IDに「アプリケーション(クライアント)ID」、Client
Secretに「クライアントシークレット」、Tenantに「ディレクトリ(テナント)ID」を入力して「Save」をクリックする
</div>
<div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW0SuoF6HKBZ1raFaNtKsxzCh9uD1BUdREDC1RSKfFqVCONbwp3E9SEJQBZYhB4I4ZQrue_hkTPQpaMKVYrvXS_p55NTo9xs7UUgDjW-8PIdf55dUi_zxD3WJgJsIVD95uLq_9mGjXRGOh2NHAqFUl-u-NxqBt1firNrqgKFpHKgwVIEwabncUNfDE/s1250/ScreenClip.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="913" data-original-width="1250" height="294" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW0SuoF6HKBZ1raFaNtKsxzCh9uD1BUdREDC1RSKfFqVCONbwp3E9SEJQBZYhB4I4ZQrue_hkTPQpaMKVYrvXS_p55NTo9xs7UUgDjW-8PIdf55dUi_zxD3WJgJsIVD95uLq_9mGjXRGOh2NHAqFUl-u-NxqBt1firNrqgKFpHKgwVIEwabncUNfDE/w403-h294/ScreenClip.png" width="403" /></a></div><br />
</div>
<div><br /></div>
<div>以上で設定完了です。Liferay側の設定はとても簡単です。</div>
<div><br /></div>
<h3 style="text-align: left;">動作確認してみよう</h3>
<div><br /></div>
<div>
では動作確認してみましょう。ドキュメントとメディアの新規作成メニューをクリックすると、Word、PowerPoint、Excelが表示されるようになります。
</div>
<div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN5rcSdlPH-X3po2ZLh8rv5vFyqtG1a5YeFJ6ekUH5HsYlXGyGXYJyjlE4dq4UFU9dGIAsFzeQDwHiwZto44JnuhP2jf2BGva4trW-U3dVOa3BJoaVe-yhvn9m9XQZC0ua8Gj4bf_U61LUF6aYb1FZ5NxA8n9EtVWS1aFSMt80uUey_duZ_jsN9W7E/s759/skitch01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="475" data-original-width="759" height="254" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN5rcSdlPH-X3po2ZLh8rv5vFyqtG1a5YeFJ6ekUH5HsYlXGyGXYJyjlE4dq4UFU9dGIAsFzeQDwHiwZto44JnuhP2jf2BGva4trW-U3dVOa3BJoaVe-yhvn9m9XQZC0ua8Gj4bf_U61LUF6aYb1FZ5NxA8n9EtVWS1aFSMt80uUey_duZ_jsN9W7E/w406-h254/skitch01.png" width="406" /></a></div><br />
</div>
<div><br /></div>
<div>
これらをクリックしてファイル名を入力すると、Microsoft
365のログイン画面が表示されるので認証情報を入力します。初回はアクセス許可の画面が表示されるので許可します(2回目以降は表示されません)。すると、OneDrive上にファイルが生成されオンラインのOfficeアプリでファイルが編集できるようになります。ファイルを保存すると、OneDrive上のファイルをLiferayに保存し、OneDrive上のファイルは削除されます。
</div>
<div><br /></div>
<div>
また、アクションメニューの「Edit in Office
365」をクリックすると、OneDrive上にファイルをコピーしてOfficeアプリでのオンライン編集が始まります。</div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2y1cxQPguC6yaQOnSmowDDXwhZsyJMqMyq7cPL7I2xVplAa6mKbOfHWnaFitEPkaH09KuqHHJopEgLwedORX4ZKxHKCNPikIIazyzeXjR_hnBu_VkTnbD3SF8wgN54bailuIyFkNptZ-ch9PUlQDLkZ57ZwxAefOzJijxWMrb0Dl8GAYAjsi1AtxC/s967/skitch00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="611" data-original-width="967" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2y1cxQPguC6yaQOnSmowDDXwhZsyJMqMyq7cPL7I2xVplAa6mKbOfHWnaFitEPkaH09KuqHHJopEgLwedORX4ZKxHKCNPikIIazyzeXjR_hnBu_VkTnbD3SF8wgN54bailuIyFkNptZ-ch9PUlQDLkZ57ZwxAefOzJijxWMrb0Dl8GAYAjsi1AtxC/w427-h270/skitch00.png" width="427" /></a></div>
</div>
<div><br /></div>
<div>
今回の紹介は以上です。Officeファイルをオンライン編集できるメリットは大きいと思いますので、組織でMicrosoft
365をお使いであれば是非お試しください。
</div>
</div>
Tasuku Otanihttp://www.blogger.com/profile/18132336091954266906noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-73114303928897973842020-08-28T13:36:00.007+09:002022-08-17T17:28:49.566+09:00gogo shellコマンドを作ってみよう<p> とたにです。</p><p>今回は実は色々な用途に使えるgogo shellコマンドの作り方を紹介したします。</p><p>※本記事はLiferay DXP 7.1を使用していますがバージョン7.0〜7.2でも(おそらく7.3も)問題なく動くと思います。</p><h3 style="text-align: left;">そもそもgogo shellとは</h3><div>gogo shellコマンドの前にgogo shellとはなんでしょうか。LiferayはDXP(7.0)以降、アーキテクチャがOSGiベースに刷新されました。gogo shellはそのOSGiランタイムのコマンドラインシェルのことで、正しくは<a href="https://felix.apache.org/documentation/subprojects/apache-felix-gogo.html">Apache felix gogo shell</a>といいます。</div><div>Liferayにも、このgogo shellを組み込まれているためgogo shellにアクセスしてさまざまな情報を取得したりOSGiバンドルの操作をしたりすることができます。</div><div><br /></div><h3 style="text-align: left;">gogo shellへの接続方法</h3><div>gogo shellへの接続方法は大きく2通りあります。</div><div>1つ目はLiferayのコントロールパネルからgogo shellにアクセスする方法です。</div><div>コントロールパネルの設定からGogo shellをクリックすると以下のようなGogo shellコマンドをWebページから入力できます。</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq8VJ556lAcaTlVI8wN1RKneywuww6dMvcuQglNCY6gqChvPD9PHFQvHtLWG0MXEk_kvrqA_grlyPZjxeZffjj8Ud5fSWZYpX14XV3kfQrSOhuD7lI26yYvr8cMBSjQc0e9gJpyeuRZwSKcXbkzm5now_jD4N83VmsKifrS4r36CvJMhPcwFK93pDU/s1240/web-gogo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="582" data-original-width="1240" height="209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq8VJ556lAcaTlVI8wN1RKneywuww6dMvcuQglNCY6gqChvPD9PHFQvHtLWG0MXEk_kvrqA_grlyPZjxeZffjj8Ud5fSWZYpX14XV3kfQrSOhuD7lI26yYvr8cMBSjQc0e9gJpyeuRZwSKcXbkzm5now_jD4N83VmsKifrS4r36CvJMhPcwFK93pDU/w446-h209/web-gogo.png" width="446" /></a></div><br /><div><br /></div>2つ目は、telnetを使って接続する方法です。ただし7.1以降でtelnetを使って接続するためには以下の設定をportal-ext.propertiesに設定しておく必要があります。<div><br />
</div>
<pre class="brush:plain"> module.framework.properties.osgi.console=localhost:11311
</pre>
<p>
この状態でLiferayを起動すると以下のようにtelnetからgogo shellに接続することができます。
</p>
<pre class="brush:plain">$ telnet localhost 11311
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
____________________________
Welcome to Apache Felix Gogo
</pre>
<p>
gogo shellではさまざまなコマンドが標準で用意され、主にOSGiバンドルの状態確認や調査、状態変更などが行えます。helpコマンドで使用できるコマンドの一覧を確認することができるので興味のある方は確認してみてください。
</p>
<h3 style="text-align: left;">gogo shellコマンドの作成方法</h3>
<p>gogo shellでは用意されたコマンドを使うだけではなく新しくコマンドを追加することができます。<br />
今回は非常に簡単なコマンドを作成してみたいと思います。</p>
<h4 style="text-align: left;">step.1 Liferayモジュールプロジェクトの準備</h4>
<div>Liferay IDEやbladeコマンドでLiferay workspaceとコマンドを追加するためのモジュールプロジェクトを作成します。プロジェクトの種類はシンプルでよいのでactivator等を選んでおくのが簡単かと思います。</div><div><br /></div><div>今回はLiferayのサイト一覧とサイトメンバの一覧をコマンドで表示するコマンドを作ろうと思っているので、Liferayのサービスが呼び出せるようにbuild.gradleを以下のようにしておきます。</div>
<pre class="brush:plain">dependencies {
compileOnly group: "org.osgi", name: "org.osgi.core"
compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations"
compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel"
}
</pre>
<h4 style="text-align: left;">step.2 コマンドクラスの作成</h4>
<pre class="brush:java">package sample;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.model.Group;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.service.GroupLocalService;
import com.liferay.portal.kernel.service.UserLocalService;
import com.liferay.portal.kernel.util.PortalUtil;
import java.util.List;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@Component(
property = {
"osgi.command.function=listSites",
"osgi.command.function=siteMembers",
"osgi.command.scope=sample"
},
service = Object.class
)
public class SIteMemberCommand {
public void listSites() {
List>group> sites = this.groupLocalService.getGroups(QueryUtil.ALL_POS, QueryUtil.ALL_POS);
sites.stream().forEach(g -> System.out.println(g.getFriendlyURL()));
System.out.println("-- Total: " + sites.size());
}
public void siteMembers(String siteUrl) throws PortalException {
Group g = this.groupLocalService.getFriendlyURLGroup(PortalUtil.getDefaultCompanyId(), siteUrl);
List>user> users = this.userLocalService.getGroupUsers(g.getGroupId());
users.stream().forEach(u -> System.out.println(u.getScreenName() + ", " + u.getEmailAddress()));
}
@Reference
private GroupLocalService groupLocalService;
@Reference
private UserLocalService userLocalService;
}
</pre>
<div>
大した長さではないので、クラスのコードを全部はっています。
</div>
<p>
一番大切な部分は、クラスに付与されたアノテーションで、osgi.comand.functionとosgi.comnand.scopeプロパティの部分です。<br />
osgi.command.functionはコマンドの名前と対応するメソッド名を定義しています。今回の例だとlistSitesと入力するとこのクラスのlsitSitesメソッドが実行されるようになります。<br />
またosgi.command.functionは複数行記述することで複数のコマンドをひとつのクラスにまとめて定義することができます。
</p>
<p>
osgi.command.scopeはコマンドの名前空間でコマンド実行時には省略することもできますが、コマンド名が衝突しているケースで[スコープ名]:[コマンド名]のように入力することでコマンドを限定することができます。<br />
</p>
<p>
コマンドの中身はLiferayの標準サービスを使って簡単な情報を出力しているだけなので詳細は省略しますが、コマンドを実行すると以下のように動きます。<br />
</p><ul>
<li>listSitesコマンドはLiferay上のサイトのフレンドリURL一覧を出力します。</li>
<li>siteMembersコマンドはフレンドリURLを引数にとって、そのサイトの所属ユーザ一覧を出力します。</li>
</ul>
<p></p>
<h4 style="text-align: left;">step.3 結果確認</h4>
<p>
モジュールをビルドしてLiferayにデプロイしたらコマンドの動作を確認してみましょう。
</p>
<pre class="brush:plain">g! listSites
/landing1
/landing2
...
/uitest
/personal_site
/template-35187
/template-35237
/template-33896
/template-20154
/template-33875
/template-33851
/template-33862
-- Total: 115
</pre>
<p>
サイトテンプレートなどもサイトのひとつとして表示されていますが、いちおうサイトの一覧は取得できているようです。<br />
次にsiteMembersもためしてみましょう。
</p>
<pre class="brush:plain">g! siteMembers /contacttest
test, test@liferay.com
</pre>
<p>
サイトメンバが1人しかいないですが、サイトのメンバーが表示されていることがわかります。
</p>
<h3 style="text-align: left;">まとめ</h3>
<p>
Liferayのサービスと連携したgogo shellコマンドを作成しました。<br />
gogo shellコマンドはこのようにLiferayのサービスやサービスビルダで作成したサービスを呼び出すことができるので、例えば初期データの登録やサービスレイヤーのテストなどさまざまな用途に活用することができます。<br />
作成方法も簡単なのでぜひ活用してみてください。
</p>
Totanihttp://www.blogger.com/profile/05482818344212023797noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-18832622806791749822020-08-28T09:01:00.001+09:002022-08-17T17:30:29.364+09:00Alfresco 201911GAで管理ツールからユーザ検索できない問題の解決方法<p>
こんにちは。てらしたです。今回は<a href="https://hub.alfresco.com/t5/alfresco-content-services-hub/alfresco-community-edition-201911-ga-release-notes/ba-p/294411" target="_blank">Alfresco 201911GAのリリースノート</a>にKnown
Issuesとして記載されている、Shareの管理ツールからユーザ検索ができない問題の解決方法についてです。
</p>
<p>
リリースノートからもリンクが貼られている<a href="https://github.com/Alfresco/acs-community-packaging/issues/367" target="_blank">こちらのissue</a>に問題の内容と解決方法が書いてあるので、その内容のご紹介になります。どうやらEnterprise版(有償版)のための機能のバグ修正の結果として生まれた新たなバグのようです。
</p>
<p>
解決方法の前に、まずは問題の内容を確認します。Alfrescoを起動し、Shareにadminでログインしてヘッダの「管理ツール」をクリックします。次に管理ツール画面で左メニューの「ユーザー」をクリックします。本来はこのページでユーザを検索できるはずですが、検索しても「アイテム読み込み時のエラー」というエラーメッセージが表示されて検索できません。ブラウザの開発ツールで確認してみると、people-enterpriseというapiにリクエストを投げて404が返ってきていることが原因のようです(Enterprise版用のAPIだから)。</p><p><br /></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhheLOkD1deMo2TygDpwEQ4JhevYxyZBOnwNKahNW4rgKyaG73oBmQH9YV0KkdKEsBj-LDp91uZEj5m0WHbRVbGMbyVFSsgVD1EdQin34zr7c28ywhhpwoqdwuAzvidQh9Ou9KYAYPk2AVSWXEXpvA1IeOm9OHRHCFz9AtiV_naWe4QmGHwwQ0d3g5/s2555/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-08-21%2011.52.58.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1231" data-original-width="2555" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhheLOkD1deMo2TygDpwEQ4JhevYxyZBOnwNKahNW4rgKyaG73oBmQH9YV0KkdKEsBj-LDp91uZEj5m0WHbRVbGMbyVFSsgVD1EdQin34zr7c28ywhhpwoqdwuAzvidQh9Ou9KYAYPk2AVSWXEXpvA1IeOm9OHRHCFz9AtiV_naWe4QmGHwwQ0d3g5/w538-h259/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-08-21%2011.52.58.png" width="538" /></a></div><br />
</div>
<p>
上にリンクを貼ったissueによると、share-config.xmlでshow-authorization-statusというプロパティがtrueになっていることが原因のようなので、これをfalseにしてあげれば解決します。
</p>
<h3 style="text-align: left;">Alfresco SDK 4.1で修正する場合</h3>
<p>
SDKを使って修正する場合(SDK4.1の開発環境構築については<a href="http://labo-blog.aegif.jp/2020/08/alfresco-sdk-41.html" target="_blank">こちら</a>)は、share-jarプロジェクトの
[artifactId]-share/src/main/resources/META-INF/share-config-custom.xmlの<alfresco-config>タグの間の適当な場所に以下のコードを追記してリビルドすればOKです。
</p>
<pre class="brush:xml"><config evaluator="string-compare" condition="Users" replace="true">
<users>
<!-- minimum length for username and password -->
<username-min-length>2</username-min-length>
<password-min-length>3</password-min-length>
<show-authorization-status>false</show-authorization-status>
</users>
<!-- This enables/disables the Add External Users Panel on the Add Users page. -->
<enable-external-users-panel>false</enable-external-users-panel>
</config>
</pre>
<h3 style="text-align: left;">Dockerfileで修正する場合</h3>
<p>
201911GAをdocker composeを使って試用している場合(やり方については<a href="http://labo-blog.aegif.jp/2020/03/alfresco-community-edition.html" target="_blank">こちら</a>)でも、show-authorization-statusというプロパティを書き換えればいいだけなので方法はいろいろあると思いますが、手っ取り早く確認したいのであれば以下の方法が簡単なのではないかと思います。
</p>
<p>
docker-compose.ymlと同じディレクトリに以下の内容を記載したDockerfileを作成します。
</p>
<pre class="brush:bash">FROM alfresco/alfresco-share:6.2.0
ARG TOMCAT_DIR=/usr/local/tomcat
# Patch for https://github.com/Alfresco/acs-community-packaging/issues/367
RUN sed -i 's@<show-authorization-status>true</show-authorization-status>@<show-authorization-status>false</show-authorization-status>@' \
$TOMCAT_DIR/webapps/share/WEB-INF/classes/alfresco/share-config.xml
</pre>
<p>次に、docker-compose.ymlの以下の部分を</p>
<pre class="brush:plain">share:
image: alfresco/alfresco-share:6.2.0
mem_limit: 1g
environment:
...
</pre>
<p>
以下のように書き換えます。image名は既存のものと被らなければ何でもいいと思いますし、指定しなくても動くはずです。
</p>
<pre class="brush:plain">share:
image: custom-alfresco-share:development
build:
dockerfile: ./Dockerfile
context: ./
mem_limit: 1g
environment:
...
</pre>
<p>
修正した後に確認してみると、以下のようにユーザ検索が問題なく実行できると思います。
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghznO7oOiZtJGYCSfOnQRQUtI2QnzQFeKVcKIPo-simPGEBEddceajBhSk5XwrnWeU9h19KsnRNwddM87TqXceNw_APjB4yy28QO2d4d1r5lfcBgeR_AJRfKTfDTaZ0hyRtm859kk79CcD3mwYHRcigYbc-ybLN0fRjps2rtCtdXaSRUdoTtM7e0Sy/s2555/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-08-24%2017.58.33.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1231" data-original-width="2555" height="309" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghznO7oOiZtJGYCSfOnQRQUtI2QnzQFeKVcKIPo-simPGEBEddceajBhSk5XwrnWeU9h19KsnRNwddM87TqXceNw_APjB4yy28QO2d4d1r5lfcBgeR_AJRfKTfDTaZ0hyRtm859kk79CcD3mwYHRcigYbc-ybLN0fRjps2rtCtdXaSRUdoTtM7e0Sy/w640-h309/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-08-24%2017.58.33.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<p>
こんなことをしなくてもいいようにいずれ修正されるのではないかと思いますが、今のところはこのような方法で修正することが可能です。
</p>
Jun Terashitahttp://www.blogger.com/profile/09039721862238185320noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-72492319297004379092020-08-25T11:49:00.002+09:002022-08-17T17:34:22.792+09:00 Liferayテーブルを見てみよう〜サイト情報編<p>こんにちはナクラです。</p><div style="text-align: left;">前回はユーザの情報についてみましたが、<br />今回はサイトに関連する情報についてみていきましょう。<br />LiferayではいくつかのWebページをまとめてサイトを構成しています。<br />表示しているサイトに関する情報はコントロールパネルのサイトのセクションで確認できます。</div><div style="text-align: left;">サイトのセクションでは、サイトの所属するユーザの情報や、<br />サイト内のWebコンテンツやWiki、ドキュメントなどの情報を確認することができます。<br />特にサイト自体についての設定情報は<br />「設定」> 「サイトの設定」になります。</div><p>サイト設定では4つタブがあります。</p>・共通<br />・ソーシャル<br />・言語<div>・詳細設定<p>それぞれ見ていきましょう。</p><p><br /></p><p>1.<b>共通</b>タブ</p><p>共通タブの画面はこのようになっています。</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibdcOZ38ZAwxAuoFwwDXhbRrummI3DGwdIshLItj2tr3NNt_AmAKoEikI0J9JgHn5Tf-cBFcQEDpABxmQMq7eAMPKZx9DLPmDO-53T0bTBunKZ2oNLj4ZjnLkZSZu5xG1mi_1wavjxYcUz66srou1-OG56HoY-JZrN2KCt4l5PUTovmUldWxy0h-YY/s1534/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-08-25%2011.25.28.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1534" data-original-width="572" height="1313" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibdcOZ38ZAwxAuoFwwDXhbRrummI3DGwdIshLItj2tr3NNt_AmAKoEikI0J9JgHn5Tf-cBFcQEDpABxmQMq7eAMPKZx9DLPmDO-53T0bTBunKZ2oNLj4ZjnLkZSZu5xG1mi_1wavjxYcUz66srou1-OG56HoY-JZrN2KCt4l5PUTovmUldWxy0h-YY/w488-h1313/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-08-25%2011.25.28.png" width="488" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div style="text-align: left;">この画面の設定項目の大半はサイト情報のメインのデータであるGroup_テーブルに含まれている情報です。</div><div style="text-align: left;">(このテーブルも最後に"_"がついてます。)<br />サイトなのにGroup_という名前になっているので、注意してください。<br />実は、Group_テーブルには、この記事で取り扱っている"サイト"以外にも<br />いろいろな"サイト"的なものを登録するテーブルになっていて、<br />"サイト"自体は、Group_の一部という取扱いになっています。</div><div style="text-align: left;">Group_テーブルの定義は、前回でも確認しましたが、以下のようになっています。</div></div><div style="text-align: left;"><b>Group_テーブル</b></div><span style="font-family: arial;">+-------------------------------------+------------------+---------+---------+----------+-------+<br />| Field <span> </span>| Type | Null | Key | Default | Extra |<br />+-------------------------------------+------------------+---------+---------+----------+-------+<br />| mvccVersion <span> </span>| bigint(20) | NO | | 0 | |<br />| uuid_ <span> </span>| varchar(75) | YES | MUL | NULL | |<br />| groupId <span> </span>| bigint(20) | NO | PRI | NULL | |<br />| companyId <span> </span>| bigint(20) <span> </span>| YES | MUL | NULL | |<br />| creatorUserId <span> </span>| bigint(20) <span> </span>| YES | | NULL | |<br />| classNameId <span> </span>| bigint(20) <span> </span> | YES | MUL | NULL | |<br />| classPK <span> </span>| bigint(20) <span> </span> | YES | | NULL | |<br />| parentGroupId <span> </span>| bigint(20) <span> </span> | YES | | NULL | |<br />| liveGroupId <span> </span>| bigint(20) <span> </span>| YES | MUL | NULL | |<br />| treePath <span> </span>| longtext <span> </span>| YES | | NULL | |<br />| groupKey <span> </span>| varchar(150) | YES | | NULL | |<br />| name <span> </span>| longtext | YES | | NULL | |<br />| description <span> </span>| longtext <span> </span>| YES | | NULL | |<br />| type_ <span> </span>| int(11) | YES | MUL | NULL | |<br />| typeSettings <span> </span>| longtext | YES | | NULL | |<br />| manualMembership <span> </span>| tinyint(4) <span> </span>| YES | | NULL | |<br />| membershipRestriction <span> </span>| int(11) <span> </span>| YES | | NULL | |<br />| friendlyURL <span> </span>| varchar(255) | YES | | NULL | |<br />| site <span> </span><span> </span><span> </span><span> </span><span> </span><span> </span>| tinyint(4) <span> </span> | YES | | NULL | |<br />| remoteStagingGroupCount<span> </span>| int(11) | YES | | NULL | |<br />| inheritContent<span> </span><span> </span><span> </span><span> </span><span> </span><span> </span>| tinyint(4) <span> </span>| YES | | NULL | |<br />| active_ <span> </span><span> </span>| tinyint(4) <span> </span>| YES | | NULL | |</span><div><span style="font-family: arial;">+--------------------------------------+------------------+-------+----------+-----------+--------+</span><div><p>さて、共通タブの項目とデータベースでの設定値との対応についてみていきましょう。</p><div style="text-align: left;">●詳細セクション<br />・サイトID:groupIdカラム<br />この値がサイトのプライマリキーになります。 <br />・説明: descriptionカラム<br />・メンバーシップタイプ:type_カラム<br />各設定に対応する値は下記のようになります。</div><div style="text-align: left;">公開<span style="white-space: pre;"> </span>1 </div><div style="text-align: left;">制限付き<span style="white-space: pre;"> </span>2</div><div style="text-align: left;">非公開<span style="white-space: pre;"> </span>3</div></div><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"></blockquote><div><div style="text-align: left;">・手動メンバーシップ管理を許可する:manualMembershipカラム<br />対応する値は<br />はい<span style="white-space: pre;"> </span>1<br />いいえ<span style="white-space: pre;"> </span>2<br />・親サイト:parentGroupIdカラム <br />親サイトを指定した場合は親サイトのサイトID(groupIdカラムの値)が入ります。</div><p>●ページセクション</p><div style="text-align: left;">・公開ページ、非公開ページ<br />ページが存在する場合は、公開ページと非公開ページへのリンクが表示されます。<br />ページが存在しない場合は、サイトテンプレートを指定できるようになっていて、<br />それで保存すると、サイトテンプレートに従ってページが作成されます。<br />ページとサイトの関係については、後日詳しくみることにしましょう。</div><p>●カテゴリの設定セクション</p><div style="text-align: left;">・タグ<br />この設定値はAssetEntries_AssetTagsテーブルに登録されます。<br />入力したタグが生成されて、tagIdを割り当てらます。<br />サイトに対しては、アセットとしてみた場合のentryIdが割り当てられており、それを使ってタグとの関連情報が登録されます。<br /></div><div style="text-align: left;"><b>AssetEntries_AssetTags</b>テーブル</div><div style="text-align: left;"><span style="font-family: arial;">+---------------+-------------+------+-------+-----------+-------+<br />| Field | Type | Null | Key | Default | Extra |<br />+---------------+-------------+------+-------+-----------+-------+<br />| companyId | bigint(20) | NO | MUL | NULL | |<br />| entryId | bigint(20) | NO | PRI | NULL | |<br />| tagId | bigint(20) | NO | PRI | NULL | |<br />+---------------+-------------+------+-------+-----------+-------+</span></div><div style="text-align: left;">アセットの情報については<br />AssetEntryテーブルで確認できます。</div><p>●サイトURLセクション</p><div style="text-align: left;">・フレンドリURL:friendlyURLカラム<br />サイト作成時にはサイト名からfriendlyURLは自動生成されますが、<br />この設定で変更することができます。</div><div style="text-align: left;">・バーチャルホストの公開ページと非公開ページ<br />この設定値はVirtualHostテーブルに登録されます。<br /></div><div style="text-align: left;"><b>VirtualHost</b>テーブル</div><div style="text-align: left;"><span style="font-family: arial;">+-----------------+------------------+-------+------+-----------+-------+<br />| Field | Type | Null | Key | Default | Extra |<br />+-----------------+------------------+-------+------+-----------+-------+<br />| mvccVersion | bigint(20) | NO | | 0 | |<br />| virtualHostId | bigint(20) | NO | PRI | NULL | |<br />| companyId | bigint(20) | YES | MUL | NULL | |<br />| layoutSetId | bigint(20) | YES | | NULL | |<br />| hostname | varchar(200) | YES | UNI | NULL | |<br />+-----------------+------------------+-------+-------+----------+-------+</span></div><div style="text-align: left;">layoutSetIdカラムの値がサイトの公開ページセットのIDおよび非公開ページセットのIDになっており、<br />hostnameカラムに設定した値が登録されます。</div><div style="text-align: left;"><br /></div><div style="text-align: left;">以下の項目はいずれもtypeSettingsカラムで登録されます。<br />・ディレクトリのインデックスを有効にする<br />・このサイトでアセットの自動タグ付けを有効にする<br />・共有<br />それぞれの設定方法は次のとおりです。<br />directoryIndexingEnabled=false <br />assetAutoTaggingEnabled=true<br />sharingEnabled=true </div><p><br /></p><p>2.<b>ソーシャル</b>タブ</p><p>ソーシャルタブの画面はこのようになっています。</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcpbKPQZ6inby8EdrTCzZhI5AAvSdlrlug_nzGM4m0XnmQTq5-ih0G7SvElWNZejq8J0D73mPY6v9gEXWtz4FsVPRjo23nZQSIykfRmRwkjojft3Wuf_-ar2z8lvbY8Ty3UQs4-nHS3kEgmC3TEsg4i2GdlKTkWreywpC8RLBLi9X4Qk7VCr-Hn8f_/s1212/%E3%82%BD%E3%83%BC%E3%82%B7%E3%83%A3%E3%83%AB%E3%82%BF%E3%83%95%E3%82%99.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1212" data-original-width="898" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcpbKPQZ6inby8EdrTCzZhI5AAvSdlrlug_nzGM4m0XnmQTq5-ih0G7SvElWNZejq8J0D73mPY6v9gEXWtz4FsVPRjo23nZQSIykfRmRwkjojft3Wuf_-ar2z8lvbY8Ty3UQs4-nHS3kEgmC3TEsg4i2GdlKTkWreywpC8RLBLi9X4Qk7VCr-Hn8f_/w474-h640/%E3%82%BD%E3%83%BC%E3%82%B7%E3%83%A3%E3%83%AB%E3%82%BF%E3%83%95%E3%82%99.png" width="474" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><p>●評価セクション</p><div style="text-align: left;">ここでは、サイトのコンテンツの評価方法を設定できます。<br />項目とデータベースの設定値との対応は以下の様になっています。<br />「高評価」:like<br />「スター(縦方向)」:stacked-stars<br />「スター」:stars<br />「評価」:thumbs</div><div style="text-align: left;">それぞれの設定情報は<br />Group_テーブルのtypeSettingsカラムに以下のようなに登録されます。<br /></div></div></div><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div><div><div style="text-align: left;">com.liferay.blogs.model.BlogsEntry_RatingsType=stars</div></div></div><div><div><div style="text-align: left;">com.liferay.document.library.kernel.model.DLFileEntry_RatingsType=thumbs</div></div></div><div><div><div style="text-align: left;">com.liferay.journal.model.JournalArticle_RatingsType=thumbs</div></div></div><div><div><div style="text-align: left;">com.liferay.knowledge.base.model.KBArticle_RatingsType=stacked-stars</div></div></div><div><div><div style="text-align: left;">com.liferay.message.boards.model.MBDiscussion_RatingsType=like</div></div></div><div><div><div style="text-align: left;">com.liferay.wiki.model.WikiPage_RatingsType=thumbs</div></div></div></blockquote><div><p>●コメントセクション</p><div style="text-align: left;">・他ユーザーへのメンションを許可する。<br />これの設定も、typeSettingsカラムで下記のように登録されます。<br />mentionsEnabled=true</div><p><br /></p><p>3.<b>言語</b>タブ</p><p>言語タブの画面はこのようになっています。</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi99qi7wKaDkUQPaByVsjacr189gZCP1iaM_5m3ZaXeEWfMCIRXHLXgkXH54gRELlixRtXK5Efh7Wd-E28CgKTbE6to5dYOL3msnujwgN3bKPZkIN2LPKvhKiUsHDa6VIgXeyQOJnI54xBzNMjqjkFzO4GplU5HWrxoOPyI50GWltrroFqSCX4OaSNB/s1220/%E8%A8%80%E8%AA%9E%E3%82%BF%E3%83%95%E3%82%99.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1182" data-original-width="1220" height="424" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi99qi7wKaDkUQPaByVsjacr189gZCP1iaM_5m3ZaXeEWfMCIRXHLXgkXH54gRELlixRtXK5Efh7Wd-E28CgKTbE6to5dYOL3msnujwgN3bKPZkIN2LPKvhKiUsHDa6VIgXeyQOJnI54xBzNMjqjkFzO4GplU5HWrxoOPyI50GWltrroFqSCX4OaSNB/w437-h424/%E8%A8%80%E8%AA%9E%E3%82%BF%E3%83%95%E3%82%99.png" width="437" /></a></div><p><br /></p><div style="text-align: left;">ここでは、サイトのデフォルト言語と切り替え可能な言語を設定できます。<br />「デフォルト言語オプションを使用します」のラジオボタンが選択されている場合は、<br />インスタンス設定の"ローカライズ"で設定されている項目が引き継がれます。<br />「このサイトでのデフォルトの言語と指定可能な言語を定義してください」にラジオボタンを変更すると<br />デフォルト言語と選択可能が言語の設定が行えます。<br />ここの部分の設定情報でデータベースでは、<br />Group_テーブルのtypeSettingsカラムに登録されます。<br />まず、ラジオボタンの情報が<br />inheritLocales=true<br />のような形で設定されています。<br />「デフォルト言語オプションを使用します」を選択している場合は true<br />「このサイトでのデフォルトの言語と指定可能な言語を定義してください」を選択している場合は false<br />になります。<br />デフォルトの言語は<br />languageId=en_US<br />利用可能な言語は<br />locales=en_US,nl_NL,ja_JP<br />のように登録されています。<br />ただし、この設定情報は「デフォルト言語オプションを使用します」を選択すると<br />初期設定に戻ってしまうのでラジオボタンを戻したときにまた、一から選択しなおす必要があるので注意してください。</div><p><br /></p><p>4.<b>詳細設定</b>タブ</p><p>詳細設定タブの画面はこのようになっています。</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWGfwbZw930HCOkzSumgsg_hk81hl8AkOM2O1BpITwS3d7PARvL6XbpNBvqI2HwB-SPMVk5_-knuf9-arxjqWJtyWvQ8tsFoIhbpDZs3rPVDaWkTK2QpjHHnGvoHRtZivxmkP-7NrRX3uukVJ2uCKq5PXw9527YwScCENIsy7LghZhNVuO65c5k_av/s1232/%E8%A9%B3%E7%B4%B0%E3%82%BF%E3%83%95%E3%82%99.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1232" data-original-width="574" height="937" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWGfwbZw930HCOkzSumgsg_hk81hl8AkOM2O1BpITwS3d7PARvL6XbpNBvqI2HwB-SPMVk5_-knuf9-arxjqWJtyWvQ8tsFoIhbpDZs3rPVDaWkTK2QpjHHnGvoHRtZivxmkP-7NrRX3uukVJ2uCKq5PXw9527YwScCENIsy7LghZhNVuO65c5k_av/w436-h937/%E8%A9%B3%E7%B4%B0%E3%82%BF%E3%83%95%E3%82%99.png" width="436" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><div style="text-align: left;">このタブの設定項目は全てtypeSettingsカラムに登録されます。<br />項目と登録方法を一緒に確認していきましょう。</div><p>●デフォルトの関連付けセクション</p><div style="text-align: left;">・サイトロール」<br />defaultSiteRoleIds=34520<br />・チーム<br />defaultTeamIds=37534</div><p>●分析セクション</p><div style="text-align: left;">・Google アナリティクスID<br />googleAnalyticsId=XXXXXX<br />・Piwik<br />analytics_piwik=XXXXXXX<br /></div><p style="text-align: left;">●地図セクション</p><div style="text-align: left;">・OpenStreetMap<br />MAP_PROVIDER_KEY=OpenStreetMap<br />・Google マップおよび「Google Maps API キー (オプション)」<br />MAP_PROVIDER_KEY=GoogleMaps<br />googleMapsAPIKey=XXXXXXXX<br />ラジオボタンでの設定なので<br />MAP_PROVIDER_KEYはどちらか一方が登録されます。<br /></div><p style="text-align: left;">●ゴミ箱セクション</p><div style="text-align: left;">・ゴミ箱を有効にする<br />trashEnabled=true<br />・ゴミ箱内エントリーの最大保存日数<br />trashEntriesMaxAge=43200</div><p>●コンテンツセクション</p><div style="text-align: left;">・このサイトから子サイトの内容を表示できるようにする。<br />contentSharingWithChildrenEnabled=-1<br />値については以下のようになっています。<br />デフォルト値(有効):-1<br />有効:3<br />無効:0</div><div style="text-align: left;"><br /></div><h3 style="text-align: left;">まとめ</h3><div style="text-align: left;">今回はサイト設定の項目とデータベースとの対応を確認しました。<br />サイトの情報は比較的Group_テーブルにまとまって登録されています。<br />特にtypeSettingsカラムに、サイトに固有のさまざまな設定値が登録されます。</div><div style="text-align: left;">また、一部はAssetEntries_AssetTagsテーブルやVirtualHostテーブルにも登録されているデータがありました。</div><div style="text-align: left;"><br /></div><p>それではまた、次回は別の設定項目を見ていきたいと思います。</p><p><br /></p><p><br /><br /></p></div>Alkanhttp://www.blogger.com/profile/13988465687923901704noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-51647835231109784462020-08-24T12:30:00.005+09:002022-08-17T17:52:16.693+09:00Alfresco SDK 4.1を使って開発環境を構築する<p style="text-align: left;">
こんにちは。てらしたです。
今回は現時点(2020年8月)での最新のSDKである4.1を使って、Alfrescoをカスタマイズするための開発環境を構築する手順をご紹介します。
</p>
<p style="text-align: left;">
以前のSDK
3.xとは、動作確認用のAlfrescoがDockerコンテナとして起動するようになっている点が大きく異なっています。これによって、本番環境でもコンテナを使う場合は、開発環境との環境差異に起因する問題が従来より少なくなることが期待できるかもしれません。
</p>
<p style="text-align: left;">
開発環境の構築手順については3.xの時と基本的には同じです。以下のドキュメントに沿って1つずつ手順をご説明していきます。<br /><a
href="https://github.com/Alfresco/alfresco-sdk/blob/sdk-4.1/docs/getting-started.md"
target="_blank"
>Getting started with Alfresco SDK 4.1</a
>
</p>
<h3 style="text-align: left;">準備</h3>
<p style="text-align: left;">
開発用のプロジェクトを作るためには、JDK11、Maven、DockerおよびDocker
Composeのインストール/設定が必要です。
</p>
<p style="text-align: left;">
まずJDK11をインストールし、環境変数JAVA_HOMEを適切に設定します。インストールと設定が終わったら以下のコマンドで確認します。
</p>
<pre class="brush:bash">
java -version
echo $JAVA_HOME</pre
>
<p style="text-align: left;">
Mavenをインストールします(バージョンは3.3以上)。こちらも以下のコマンドでバージョンを確認します。
</p>
<pre class="brush:bash">mvn -v</pre>
<p style="text-align: left;">
Dockerをインストールします。Docker
ComposeがDockerのインストール時に一緒にインストールされていない場合は個別にインストールします。終わったら以下のコマンドで確認します。
</p>
<pre class="brush:bash">
docker -v
docker-compose -v</pre
>
<h3 style="text-align: left;">プロジェクトの作成</h3>
<p style="text-align: left;">
準備が整ったので、適当なディレクトリに移動し、以下のコマンドを実行してMaven
Archetypeからプロジェクトを作成します。
</p>
<pre class="brush:bash">mvn archetype:generate -Dfilter=org.alfresco:</pre>
<p style="text-align: left;">
ここからは対話形式で設定していきます。どのarchetypeを使用するか聞かれるので、
</p>
<ul style="text-align: left;">
<li>alfresco-allinone-archetype</li>
</ul>
<ul style="text-align: left;">
<li>alfresco-platform-jar-archetype</li>
</ul>
<ul style="text-align: left;">
<li>alfresco-share-jar-archetype</li>
</ul>
の3つ(以下の2, 4, 5)のいずれかを選択します。
<pre class="brush:bash">
Choose archetype:
1: remote -> org.alfresco.maven.archetype:activiti-jar-archetype (DEPRECATED - UNSUPPORTED - EXPERIMENTAL)
2: remote -> org.alfresco.maven.archetype:alfresco-allinone-archetype (Sample multi-module project for All-in-One development on the Alfresco platform. Includes modules for Platform/Repository JAR and Share JAR)
3: remote -> org.alfresco.maven.archetype:alfresco-amp-archetype (Sample project with full support for lifecycle and rapid development of Repository AMPs (Alfresco Module Packages))
4: remote -> org.alfresco.maven.archetype:alfresco-platform-jar-archetype (Sample project with full support for lifecycle and rapid development of Platform/Repository JARs and AMPs (Alfresco Module Packages))
5: remote -> org.alfresco.maven.archetype:alfresco-share-jar-archetype (Share project with full support for lifecycle and rapid development of JARs and AMPs (Alfresco Module Packages))
6: remote -> org.alfresco.maven.archetype:share-amp-archetype (Share project with full support for lifecycle and rapid development of AMPs (Alfresco Module Packages))
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : </pre
>
<p style="text-align: left;">
Alfresco Platformのみカスタマイズする場合は4.
alfresco-platform-jar-archetype、Shareのみカスタマイズする場合は5.
alfresco-share-jar-archetype、両方の場合は2.
alfresco-allinone-archetypeを選べばよいと思います。
</p>
<p style="text-align: left;">
次に、どのバージョンを使用するか聞かれるので4.1.0を選択します(デフォルトで選択されているはずなのでEnterを押すだけでOKです)。
</p>
<pre class="brush:bash">
Choose org.alfresco.maven.archetype:alfresco-allinone-archetype version:
1: 2.0.0-beta-1
2: 2.0.0-beta-2
3: 2.0.0-beta-3
4: 2.0.0-beta-4
5: 2.0.0
6: 2.1.0
7: 2.1.1
8: 2.2.0
9: 3.0.0
10: 3.0.1
11: 3.1.0
12: 4.0.0-beta-1
13: 4.0.0
14: 4.1.0
Choose a number: 14:</pre
>
<p style="text-align: left;">
最後に、groupIdやartifactIdといった情報の入力を求められるので適当に入力します。ここで入力したartifactIdが、プロジェクトのディレクトリ名やビルド時に作成されるJARファイルのファイル名として使用されます。
</p>
<pre class="brush:bash">
Define value for property 'groupId': jp.aegif
Define value for property 'artifactId': alfresco-allinone-test
[INFO] Using property: version = 1.0-SNAPSHOT
Define value for property 'package' jp.aegif: : jp.aegif.alfresco</pre
>
<p style="text-align: left;">
入力内容が合っているか聞かれるので、問題なければYを入力します(何も入力せずEnterでも同じです)。Y以外を入力するとgroupIdの入力からやり直すことができます。archetypeの選択からやり直したい場合はCtrl+Cで終了して最初からやり直せば大丈夫です。
</p>
<pre class="brush:bash">
Confirm properties configuration:
groupId: jp.aegif
artifactId: alfresco-allinone-test
version: 1.0-SNAPSHOT
package: jp.aegif.alfresco
Y: :</pre
>
<p style="text-align: left;">
「BUILD SUCCESS」と表示されたらプロジェクト作成完了です。
</p>
<h3 style="text-align: left;">Buildして起動</h3>
<p style="text-align: left;">
最初にmvnコマンドを実行したディレクトリにartifactIdと同名のディレクトリ(ここではalfresco-allinone-test)が作成されているはずなのでそのディレクトリに移動します。
</p>
<pre class="brush:bash">cd alfresco-allinone-test</pre>
<p style="text-align: left;">このディレクトリで、LinuxやMacでは</p>
<pre class="brush:bash">./run.sh build_start</pre>
<p style="text-align: left;">Windowsでは</p>
<pre class="brush:bash">run.bat build_start</pre>
<p style="text-align: left;">
を実行すると、カスタマイズが適用されたAlfresco(厳密に言うとAlfrescoを動かすために必要なコンテナ群)が起動します。
</p>
<p style="text-align: left;">
デフォルトではホスト側のポート8080がAlfresco
Platform、8180がShareに割り当てられるので、Shareにアクセスするためには
http://localhost:8180/share
を開く必要がある点にご注意ください。使用するポートを変更したい場合もあると思うので、その方法については下の方でご説明します。
</p>
<p style="text-align: left;">
停止したい場合はCtrl+Cでログ出力を中止して、
</p>
<pre class="brush:bash">./run.sh stop</pre>
<p style="text-align: left;">または</p>
<pre class="brush:bash"> run.bat stop</pre>
<p style="text-align: left;">で停止できます。</p>
<p style="text-align: left;">
run.shやrun.batを見ていただけるとわかるように、build_startやstop以外にもいくつかコマンドが用意されています。PlatformやShareだけを再起動するreload_acsやreload_shareは実際に開発する際に使用頻度が高そうです。
</p>
<p style="text-align: left;">
また、作成されたPlatformやShareのプロジェクトは空ではなく、それぞれサンプルの設定ファイル等が入っているので、どこにどういうファイルを置けば変更が反映されるのか確認しやすいようになっています。カスタマイズが思ったように反映されないという時にはサンプルを参考にしてみると解決するかもしれません。
</p>
<h3 style="text-align: left;">バージョンの変更</h3>
<p style="text-align: left;">
Alfrescoのバージョンを201911GAに合わせるには、run.shやrun.batがあるディレクトリのpom.xmlで以下のようにplatformのバージョンを6.2.0-gaに、shareのバージョンを6.2.0に設定してください(デフォルトではplatformが6.2.0-eaになっているはずです)。
</p>
<pre class="brush:xml">
<alfresco.platform.version>6.2.0-ga</alfresco.platform.version>
<alfresco.share.version>6.2.0</alfresco.share.version></pre
>
<p style="text-align: left;">
後で説明しますと上に書いたポートの変更方法ですが、このpom.xmlの以下の部分を書き換えると変更できます。
</p>
<pre class="brush:xml">
<share.port>8180</share.port>
...
<acs.port>8080</acs.port>
</pre>
<p style="text-align: left;">
pom.xmlを変更したら、以下のコマンドでbuildし直せば完了です(run.batの方は省略)。
</p>
<pre class="brush:bash">
./run.sh stop
./run.sh purge
./run.sh build_start</pre
>
<h3 style="text-align: left;">不要なDockerイメージの掃除</h3>
<p style="text-align: left;">
最後に注意点として、このSDK4.1ではbuildする度にDockerのimageを作るので、何度もbuildしていると以下のようにdanglingなimageが大量にできてしまいます。これらのimageを使うことはないと思うので定期的に掃除した方が良さそうです。
</p>
<pre class="brush:bash" style="text-align: left;">
REPOSITORY TAG IMAGE ID CREATED SIZE
alfresco-content-services-alfresco-allinone-test development 3182d8b5ebad 45 minutes ago 1.43GB
alfresco-share-alfresco-allinone-test development dc21bb791a51 45 minutes ago 786MB
<none> <none> 51fe77a145c1 49 minutes ago 1.43GB
<none> <none> 6cc266a96034 49 minutes ago 786MB
<none> <none> 82290779e1a0 59 minutes ago 1.43GB
<none> <none> 20aab698f49a 59 minutes ago 786MB
...
</pre>
<p style="text-align: left;">
以上、SDK4.1を使用した開発環境の作り方をご紹介しました。作成したプロジェクトをEclipseやInteliJ
IDEAといったIDEにインポートして開発したい場合は以下のドキュメントを参考に設定していただければと思います。<br />
<a
href="https://github.com/Alfresco/alfresco-sdk/blob/sdk-4.1/docs/setting-up-your-development-environment/dev-env-eclipse.md"
target="_blank"
>Setting up your development environment using Eclipse<br /></a
><a
href="https://github.com/Alfresco/alfresco-sdk/blob/sdk-4.1/docs/setting-up-your-development-environment/dev-env-intellij.md"
target="_blank"
>Setting up your development environment using Intellij IDEA</a
>
</p>
Jun Terashitahttp://www.blogger.com/profile/09039721862238185320noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-67491085000395530702020-08-20T11:51:00.005+09:002022-08-17T17:52:04.349+09:00CentOS7にApache (httpd)の最新版2.4.43をインストールする(IUSリポジトリURLが変わってて若干はまった話)<p> こんにちは。おおたにです。</p><p><br /></p><p>今回はCentOS7にApache HTTP Server (httpd)の最新版をインストールする方法を備忘代わりに書いておこうと思います。</p><p>CentOS7向けのhttpdについては、CentOSのBaseリポジトリで公開されているバージョンが2.4.6と古いため、IUSリポジトリからインストールすることが一般的です。</p><p>最記事執筆時点ではIUSリポジトリで公開されているバージョンが2.4.43、<a href="https://httpd.apache.org/" target="_blank">Apache公式</a>の最新版は2.4.46です。IUSリポジトリで公開されているよりも新しいバージョンが欲しい場合はソースコードからビルドする必要があります。</p>
<h3 style="text-align: left;">インストールされている古いhttpdの削除</h3>
<p>2.4.6等の古いhttpdがインストールされている場合はアンインストールしましょう。</p><p>まず、起動しているhttpdを停止し、systemdへのサービス登録を解除します。</p>
<pre class="brush:bash">systemctl stop httpd
systemctl disable httpd.service</pre>
<p>次に、httpdをアンインストールします。</p>
<pre class="brush:bash">yum remove httpd
yum remove httpd-tools</pre>
<h3 style="text-align: left;">yumリポジトリの追加</h3>
<p>必要なソフトウェアを入手するために、yumリポジトリEPELとIUSを追加します。</p>
<pre class="brush:bash">yum -y install epel-release
vi /etc/yum.repos.d/epel.repo
([epel]のenabledを0に変更する)
yum -y install https://repo.ius.io/ius-release-el7.rpm
vi /etc/yum.repos.d/ius.repo
([ius]のenabledを0に変更する)
</pre>
<p>これらのリポジトリをデフォルトで無効にしておくために<code>enabled=0</code>に変更しています。なお、記事によってはIUSのURLが<code>https://centos7.iuscommunity.org/ius-release.rpm</code>となっていますが、これは古いURLなので追加しようとするとエラーが出て失敗します(比較的最近リポジトリURLが変わったようです)。</p><h3 style="text-align: left;">依存ライブラリとhttpdのインストール</h3>
<p>では必要なソフトウェアをインストールしてきましょう。</p>
<pre class="brush:bash">yum -y install centos-logos.noarch mailcap openldap-devel expat-devel libdb-devel openssl perl
yum --enablerepo=epel -y install nghttp2 brotli
yum --disablerepo=base,extras,updates --enablerepo=ius -y install httpd httpd-devel mod_ssl
</pre>
<p>以上で必要なソフトウェアがインストールされました。依存ライブラリが足りないよと言われた場合は適宜インストールしてください。</p>
<h3 style="text-align: left;">サービス登録と動作確認</h3>
<p>最後にsystemdへのサービス登録を行いhttpdを起動します。</p>
<pre class="brush:bash">systemctl enable httpd.service
systemctl start httpd</pre>
<p>start実行時にエラーが出ず、ブラウザでアクセスして It works! と表示されればインストール成功です!yumでインストールした時の設定ファイルのありかは以下のとおりですので参考にしてください。</p><p></p><ul style="text-align: left;"><li>/etc/httpd/conf/httpd.conf : httpd設定</li><li>/etc/httpd/conf.d/ssl.conf : httpd設定</li><li>/etc/logrotate.d/httpd : ログローテーション設定</li></ul><p></p>Tasuku Otanihttp://www.blogger.com/profile/18132336091954266906noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-65318520283279180622020-08-07T13:05:00.007+09:002022-08-17T17:49:21.252+09:00Liferay 7とGoogle Drive / Google Docsを連携させるこんにちは。おおたにです。
<div><br /></div>
<div>
昨今のクラウドサービスの浸透に加えてコロナ禍もあり、オンラインストレージサービスやオンラインオフィスソフトウェアも一般的と言っていいまでに普及しているかと思います。今回は、これらのサービスの代表格であるGoogle
Drive / Google DocsとLiferayの連携について紹介します。
</div>
<div><br /></div>
<div>
Liferayはドキュメントライブラリと呼ばれるファイル管理の機能を持っています。Google
Drive / Google Docs連携はドキュメントライブラリとの連携を行うもので、以下の2種類の連携があります。
</div>
<div>
<ul style="text-align: left;">
<li>ドキュメントライブラリ上にGoogle Driveのファイルのリンクを作成する</li>
<li>ドキュメントライブラリ上のファイルをGoogle Docsを使ってブラウザ上で編集する(=オンライン編集)</li>
</ul>
</div>
<div>
1つ目の連携は<a href="https://web.liferay.com/ja/marketplace" target="_blank">Liferay Marketplace</a>のアプリLiferay Plugin for Google Driveで実現できます。詳しい説明は<a href="https://help.liferay.com/hc/ja/articles/360020756111-Google-Drive-%E3%81%B8%E3%81%AE%E3%83%AA%E3%83%B3%E3%82%AF" target="_blank">Google Driveへのリンク</a>を参照してください。</div><div><br /></div><div>2つ目の連携はLiferay DXP
7.2で追加された新機能になります。本記事ではこちらの機能の詳細と設定方法を説明します。なお、同様の機能を提供するOffice 365連携も新機能として追加されましたが、こちらは別の機会に紹介したいと思います。</div><div><br /></div><h3 style="text-align: left;">新しいGoogle Drive/Google Docs連携機能の紹介</h3><div><br /></div><div>前述のとおり、ドキュメントライブラリ上のファイルをGoogle Docsを使ってブラウザ上で編集することができます。具体的にできることは以下のとおりです。</div><div><ul style="text-align: left;"><li>Google Docsを使い、新規ファイル(Doc, Slide, Sheet)をブラウザ上で作成する</li><li>作成したファイルをMS Office形式(Word, PowerPoint, Excel)でドキュメントライブラリに保存する</li><li>ドキュメントライブラリ上のMS Office形式のファイルをGoogle Docsを使ってブラウザ上で編集する</li></ul></div><div>なお、Google Docsでファイル編集を開始するとGoogle Drive上にファイルがコピーされ、Google Docsでの編集を終えてファイルをLiferayに保存するとGoogle Drive上のファイルは削除されます。詳しい説明はLiferayヘルプセンターの<a href="https://help.liferay.com/hc/ja/articles/360029040811-Online-File-Creation-and-Editing-with-Google-Docs-" target="_blank">こちらの記事</a>や<a href="https://help.liferay.com/hc/ja/articles/360029040871-Creating-and-Editing-Files-with-Google-Docs-" target="_blank">こちらの記事</a>を参照してください。</div>
<div><br /></div>
<h3 style="text-align: left;">Google Cloud Platformの連携設定を行う</h3>
<div><br /></div>
<div>次に、設定方法を紹介します。Google側とLiferay側の両方に設定が必要ですが、まずはGoogle側の設定を行います。具体的には、Google Drive
APIをLiferayが利用できるように有効化し、Liferay向けにOAuth2.0クライアントIDを発行します。</div>
<div><br /></div>
<div>
1. <a href="https://console.cloud.google.com/" target="_blank">Google Cloud Platform Console</a>にアクセスし、管理ユーザでログインする
</div>
<div>
2. 適当なプロジェクトを選択する。もしくは新しいプロジェクトを作成する
</div>
<div>
3. 「APIとサービス」に移動し、「APIとサービスの有効化」をクリックする</div><div><br /></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW27BazcfAW-oSxAVjDpI8uEDQkX5WPPiYR6zkCUPGaLYW9LjmmC74XMQMAXpKKF4GxpNn8vgrRUuEdEIPr1nLjBYOc8k8kIdmaZSoRG5a7ZcZVs-CBHbU7NKIkF6dDwkrIS0JAo3gClAZViQkPmmePuTSM2v3sVQYb-WIPSrtFW9uPK_c2qzfvJKt/s667/Image.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="115" data-original-width="667" height="84" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW27BazcfAW-oSxAVjDpI8uEDQkX5WPPiYR6zkCUPGaLYW9LjmmC74XMQMAXpKKF4GxpNn8vgrRUuEdEIPr1nLjBYOc8k8kIdmaZSoRG5a7ZcZVs-CBHbU7NKIkF6dDwkrIS0JAo3gClAZViQkPmmePuTSM2v3sVQYb-WIPSrtFW9uPK_c2qzfvJKt/w490-h84/Image.png" width="490" /></a></div><br /></div>
<div>
4. Google Drive APIを検索し、「有効にする」をクリックして有効化する</div><div><br /></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSy-Ojhfp4N9Q2LZXW2MpMiZiavoTr7s2hYowlY_jrqtVzBnLm8jdIkPBrTkLhM9GRhywWSVUMWVImq4ZZxz2gX24FYLh6rhtsK1mkVS5igN51EaGCi2w1qLHWZYobHD8Gis32NEGQ_qTuOFvKsl-FXNhbpxV-pjqjxZ_iJoVgAQeodvMchZ-2um4V/s696/Image2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="311" data-original-width="696" height="235" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSy-Ojhfp4N9Q2LZXW2MpMiZiavoTr7s2hYowlY_jrqtVzBnLm8jdIkPBrTkLhM9GRhywWSVUMWVImq4ZZxz2gX24FYLh6rhtsK1mkVS5igN51EaGCi2w1qLHWZYobHD8Gis32NEGQ_qTuOFvKsl-FXNhbpxV-pjqjxZ_iJoVgAQeodvMchZ-2um4V/w526-h235/Image2.png" width="526" /></a></div><br /></div>
<div>
5. 「APIとサービス」の「OAuth同意画面」に移動して同意画面を設定する(最低限アプリケーション名を入力すればOK)
</div>
<div>6. 「APIとサービス」の「認証情報」に移動する</div>
<div>7. 「認証情報を作成」の「OAuthクライアントID」をクリックする</div><div><br /></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTSJc26HiC5VmMIEq8J-7NEZ7hyWZFhrMC_LDYt1KPEJg-PQSp2K55Zg983nUYyTLQMMLEIjHtpiti4Ik_oGzD_uP2Mw-FNMJ2LGWR9XlGZ4rLMZI9jQ7ZtCuzC1MzTHgH_bWh1Dc4R_8M-0ha__Ro6GSXBbDwN7o1Xi0NYIS7-yswocD8JZYxuEg0/s973/Image3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="468" data-original-width="973" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTSJc26HiC5VmMIEq8J-7NEZ7hyWZFhrMC_LDYt1KPEJg-PQSp2K55Zg983nUYyTLQMMLEIjHtpiti4Ik_oGzD_uP2Mw-FNMJ2LGWR9XlGZ4rLMZI9jQ7ZtCuzC1MzTHgH_bWh1Dc4R_8M-0ha__Ro6GSXBbDwN7o1Xi0NYIS7-yswocD8JZYxuEg0/w578-h278/Image3.png" width="578" /></a></div><br /></div><div>8. 以下のとおり入力して「作成」をクリックする</div><div><ul style="text-align: left;"><li>アプリケーションの種類 : ウェブアプリケーション</li><li>名前 : アプリケーション名を入力する(認証時に表示されます)</li><li>承認済みの JavaScript
生成元URI : LiferayサーバのURL(http://<host or
IP>:<port>)</li><li>承認済みのリダイレクトURI : http(s)://<host
or
IP>:<port>/o/document_library/google/oauth2</li></ul></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMx0kiDc3YHi03qc8VxcQCODDh1hARVVb0HFg29Sw8zNX17zG8k1NhoHSGeZowDR1avYIrl1ajAKKNc0diu3r2khwA1WKUfHqmrRNz9Z7_8qRThDfXwnGXg7OkaQzv8Xt2sfUuWW3Sc4tYR8jgxwtnV8drBK1tK1HVLii8C8kCKqn1xtSkLllmJ5FN/s844/Image4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="844" data-original-width="802" height="477" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMx0kiDc3YHi03qc8VxcQCODDh1hARVVb0HFg29Sw8zNX17zG8k1NhoHSGeZowDR1avYIrl1ajAKKNc0diu3r2khwA1WKUfHqmrRNz9Z7_8qRThDfXwnGXg7OkaQzv8Xt2sfUuWW3Sc4tYR8jgxwtnV8drBK1tK1HVLii8C8kCKqn1xtSkLllmJ5FN/w453-h477/Image4.png" width="453" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /></div><div>9. クライアントIDとクライアントシークレットが表示されるので、それらを手元に控える</div>
<div><br /></div><div>以上でGoogle側の設定は完了です。</div><div><br /></div><h3 style="text-align: left;">Liferayの設定を行う</h3><div><br /></div><div>続いて、Liferay側の設定を行います。</div><div><br /></div><div>1. Liferay DXP 7.2に管理者でログインする</div><div>2. 「Control Panel」->「Configuration」->「Instance Settings」->「Documents and Media」をクリックする(この場合、インスタンス毎の設定になります。グローバルに設定する場合は「System Settings」->「Documents and Media」をクリックします)</div><div><br /></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjPqq9q8e1C6S9bf1PjMpfLLvwwp6VRxT4qjCvrf6qtJrvcGelHYFRjtJ-UvCAQvhLIBf66qdcegEwgaJBw7qnSKIgvYqkWkCT0AOYm06sxr9DDUxAh6U7RebVJAISJI7FhRM1J_2d7fXRw4rGlSzo77RjYh978rymCjqg0ylglSte_hCQc4xkKvsw/s1118/Image5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="613" data-original-width="1118" height="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjPqq9q8e1C6S9bf1PjMpfLLvwwp6VRxT4qjCvrf6qtJrvcGelHYFRjtJ-UvCAQvhLIBf66qdcegEwgaJBw7qnSKIgvYqkWkCT0AOYm06sxr9DDUxAh6U7RebVJAISJI7FhRM1J_2d7fXRw4rGlSzo77RjYh978rymCjqg0ylglSte_hCQc4xkKvsw/w553-h302/Image5.png" width="553" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div></div><div>3. 「Google Drive」を選択し、Client IDとClient Secretに先ほど控えたクライアントIDとクライアントシークレットを入力して「Save」をクリックする</div><div><br /></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj91Xz9kn1a-YB-jfGHN2l1giWQli97Ee382i98VmkImjg5PNGbeYhGw0VDm-uA1zmp_A59GmjUqVDJMQE7Pf0M4lznIv1oxafZBPHDZUeq7qkPFQoDUeY-kDs96I-UGsLYcw3IRTzMDAenwQR9qGl7I9Dc_R4Wdrta9KuaJCfVpCFyjnDjIvV-nJws/s975/Image5%20%5B2%5D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="598" data-original-width="975" height="314" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj91Xz9kn1a-YB-jfGHN2l1giWQli97Ee382i98VmkImjg5PNGbeYhGw0VDm-uA1zmp_A59GmjUqVDJMQE7Pf0M4lznIv1oxafZBPHDZUeq7qkPFQoDUeY-kDs96I-UGsLYcw3IRTzMDAenwQR9qGl7I9Dc_R4Wdrta9KuaJCfVpCFyjnDjIvV-nJws/w513-h314/Image5%20%5B2%5D.png" width="513" /></a></div><br /></div><div><br /></div><div>以上です。とても簡単ですね!</div><div><br /></div><h3 style="text-align: left;">動作確認してみよう</h3><div><br /></div><div>では早速動作確認してみましょう。ドキュメントとメディア(管理者向けでもページ上に配置されたユーザ向けポートレットでもOK)で新規作成メニューをクリックすると、Google Doc、Google Slide、Google Sheetが表示されるようになります。</div><div><br /></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIHZSQMG8ywVPwNNiYe6BR9J6WwjP8q6Rew8Fw7cokAaxHMjB7v1KT8h9wy1IxHK7fZtWe85J0apWfSc_gVBx5YqXVI4s5bNlIPmY-qsd6jc_S3tor3GkulDYfQkG1SZE0WxLuRYmgawhr36yN2TPbbj9vgYbqcCfgpMexay9bcG5NAofiKAC5XVEj/s966/Image6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="602" data-original-width="966" height="348" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIHZSQMG8ywVPwNNiYe6BR9J6WwjP8q6Rew8Fw7cokAaxHMjB7v1KT8h9wy1IxHK7fZtWe85J0apWfSc_gVBx5YqXVI4s5bNlIPmY-qsd6jc_S3tor3GkulDYfQkG1SZE0WxLuRYmgawhr36yN2TPbbj9vgYbqcCfgpMexay9bcG5NAofiKAC5XVEj/w560-h348/Image6.png" width="560" /></a></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9KwmpS7mjHI2U-qBSsAidQJ-2FLigYYIS-li9PR5yB_OczIPCwFsQvy968orgSuJJlckmz9EBf_YHyle3azrka-845MND0NEi8qyguFzSVRVkpVOqVFkVpoqpryx-RKKvl5I7KmLGfUjo/s966/Image6.png" style="display: block; margin-left: 1em; margin-right: 1em; padding: 1em 0px;"><br /></a></div><div>これらをクリックするとGoogleアカウントの認証画面に遷移するので認証情報を入力します。初回はアクセス許可を行う必要があり、それが完了するとLiferayユーザとGoogleアカウントが紐づき、次回からは聞かれないようになります。そして、Google Drive上にファイルが生成されGoogle Docsでオンライン編集できるようになります。</div><div><br /></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-lwtBtCjKx9goEcBU7lfw-Aqc8MSkdv4cKcRgJJh4FcuLInbM23EZbEHtb-SBTNKPhb_aRY70bWTSWJUZ7caYJrqFBsm_COcje2z2-8CkF4gP5hMyMQeBGpQ4sit7sqqGLL84Eve4nAxNhu421UU78G9dZZ3akl6oJSCuhkux2uD3G_FZ-LJh8kr1/s1155/Image7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="335" data-original-width="1155" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-lwtBtCjKx9goEcBU7lfw-Aqc8MSkdv4cKcRgJJh4FcuLInbM23EZbEHtb-SBTNKPhb_aRY70bWTSWJUZ7caYJrqFBsm_COcje2z2-8CkF4gP5hMyMQeBGpQ4sit7sqqGLL84Eve4nAxNhu421UU78G9dZZ3akl6oJSCuhkux2uD3G_FZ-LJh8kr1/w547-h159/Image7.png" width="547" /></a></div><br /></div><div>「Save and Return to Liferay DXP」をクリックするとGoogle Drive上のファイルをLiferayに保存し、Liferayの画面に戻ります(この時Google Drive上のファイルは削除されます)。アクションメニューの「Edit in Google Docs」をクリックすると、Google DriveにファイルをコピーしてGoogle Docsでのオンライン編集が始まります。</div><div><br /></div><div class="separator" style="clear: both;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3c5qMBusnAaoZCW4Sa-g_nVYNE9EP6RprZYuX2O46SP04d7YNo4Bln8QOEOgE3Nmf7JhgN6zjO9hzQG_2eFJ6EpkvR0NNXeUmHam5ehs8Fd09DwbzAhNZcRgMDPetjvv-AIqH-CKFPmfj3CS0P0K7f0myPUd9ONBlRzN8pIGGPdYNW7ZJnp1Pl57u/s952/Image8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="481" data-original-width="952" height="290" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3c5qMBusnAaoZCW4Sa-g_nVYNE9EP6RprZYuX2O46SP04d7YNo4Bln8QOEOgE3Nmf7JhgN6zjO9hzQG_2eFJ6EpkvR0NNXeUmHam5ehs8Fd09DwbzAhNZcRgMDPetjvv-AIqH-CKFPmfj3CS0P0K7f0myPUd9ONBlRzN8pIGGPdYNW7ZJnp1Pl57u/w574-h290/Image8.png" width="574" /></a></div><br /></div><div><br /></div><div>今回の紹介は以上です。簡単な設定でGoogle Drive / Google Docsを使ったファイルのオンライン編集が実現できますので、是非みなさまも試してみてください。</div><div><br /></div>
Tasuku Otanihttp://www.blogger.com/profile/18132336091954266906noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-62945540677561456452020-08-03T16:52:00.001+09:002022-08-17T17:51:50.259+09:00Alfresco 201911GAをzipからインストールしてみよう【その3】こんにちは。たなかです。<br />
<br />
ステイホーム中に家の片付けをして粗大ゴミを出したり達成感はあるのに、階段下収納に力を入れてしまったせいで見た目のごっちゃり感が変わらない現実から目を背けている今日この頃です。<br />
<br />
<a href="http://labo-blog.aegif.jp/2020/07/alfresco-201911gazip2.html" target="_blank">前回SolrをインストールしてAlfrescoを起動するところまで紹介</a>したので、今回はAlfresco CE 201911GAをzipからインストールしてみようの最終回としてLibreOfficeやImageMagick等のインストールをご紹介します。<br />
環境等については<a href="http://labo-blog.aegif.jp/2020/07/alfresco-201911gazip1.html" target="_blank">第1回の記事</a>をご覧いただけたらと思います。<br />
<br />
先にLibreOffice_6.3.6_Linux_x86-64_rpm.tar.gzを公式サイトからダウンロードしておきます。<br />
<br />
<h3>
LibreOfficeのインストール</h3>
<br />
Alfresco CEでは、MS Officeのファイルの変換をしたり、テキストファイルをPDFファイルに変換するなどドキュメントの形式を変換したりすることができます。<br />
それらの機能を使用するためにもLibreOfficeを連携する必要があります。<br />
<br />
ダウンロードしておいたLibreOffice_6.3.6_Linux_x86-64_rpm.tar.gzを作業用ディレクトリに配置し、展開してインストールする<br />
<pre class="brush:bash">cd [作業用ディレクトリ]
tar xzvf LibreOffice_6.3.6_Linux_x86-64_rpm.tar.gz
cd LibreOffice_6.3.6.2_Linux_x86-64_rpm/RPMS/
yum localinstall *rpm
cd /opt/alfresco
rm -rf LibreOffice_6.3.6.2_Linux_x86-64_rpm
</pre>
<br />
<span style="color: #741b47;">※ 実体は以下にインストールされています</span><br />
<span style="color: #741b47;">/opt/libreoffice6.3/program/soffice</span><br />
<br />
alfresco-global.properties を編集して保存する<br />
<pre class="brush:bash">vim tomcat/shared/classes/alfresco-global.properties</pre>
<blockquote class="tr_bq">
<span style="background-color: #cfe2f3;">以下のように変更する</span><br />
jodconverter.officeHome=/opt/libreoffice6.3<br />
jodconverter.portNumbers=8101<br />
jodconverter.enabled=true </blockquote>
<div>
<br /></div>
<h3>
ImageMagickのインストール</h3>
<br />
ImageMagickはサムネイルやプレビュー画像用の画像操作等に使用されており、有効にするためにはインストールと設定が必要になります。<br />
alfresco-global.propertiesを変更することでAlfrescoと連携することができます。<br />
<div>
<br /></div>
依存性解決のためにEPELリポジトリを追加し、ImageMagickをインストールする<br />
<pre class="brush:bash">yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum install https://imagemagick.org/download/linux/CentOS/x86_64/ImageMagick-7.0.10-24.x86_64.rpm https://imagemagick.org/download/linux/CentOS/x86_64/ImageMagick-libs-7.0.10-24.x86_64.rpm
</pre>
<div>
<br />
alfresco-global.properties を編集して保存する<br />
<pre class="brush:bash">vim tomcat/shared/classes/alfresco-global.properties
</pre>
<blockquote>
<span style="background-color: #cfe2f3;">以下を追記する</span><br />
img.exe=/bin/convert</blockquote>
PDFファイル等を準備して、以下のようなコマンドでテストをすることも可能です。<br />
<pre class="brush:bash">convert test.pdf test.png</pre>
<br />
<h3>
alfresco-pdf-rendererのインストール</h3>
<br />
alfresco-pdf-rendererは、ドキュメントのサムネイルとプレビューを作成するため等に使用されています。<br />
alfresco-global.propertiesを変更することでAlfrescoと連携することができます。<br />
alfresco-pdf-rendererは、Alfrescoのzipファイルから入手できるため今回はAlfrescoインストール時に展開したものを使用しています。<br />
<br />
alfresco-pdf-rendererを展開する<br />
<pre class="brush:bash">cd /opt/alfresco
tar xzvf /[作業ディレクトリ]/alfresco-content-services-community-distribution-6.2.0-ga/alfresco-pdf-renderer/alfresco-pdf-renderer-1.1-linux.tgz
</pre>
<br />
alfresco-global.properties を編集して保存する<br />
<pre class="brush:bash">vim tomcat/shared/classes/alfresco-global.properties
</pre>
<blockquote class="tr_bq">
<span style="background-color: #cfe2f3;">以下を追記する</span><br />
alfresco-pdf-renderer.root=/opt/alfresco<br />
alfresco-pdf-renderer.exe=${alfresco-pdf-renderer.root}/alfresco-pdf-renderer </blockquote>
<blockquote class="tr_bq">
<span style="background-color: #cfe2f3;">Alfrescoインストール時にfalseにしておいた以下の設定をtrueに変更する</span><br />
legacy.transform.service.enabled=true</blockquote>
</div>
以上で『Alfresco 201911GAをzipからインストールしてみよう』完結です。<br />
ご覧いただきありがとうございました。<br />
<br />
<br />tanakahttp://www.blogger.com/profile/18160344757788711995noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-27656823480198447122020-07-28T09:55:00.003+09:002022-08-17T17:51:33.719+09:00Alfresco 201911GAをzipからインストールしてみよう【その2】こんにちは。たなかです。<br />
<br />
3月から自宅作業が続いているため買い物くらいしか外出せず目標歩数が程遠いです。<br />
意識して散歩しないとと思いつつ、つい自転車に乗ってしまう今日この頃です。<br />
<br />
<a href="http://labo-blog.aegif.jp/2020/07/alfresco-201911gazip1.html" target="_blank">前回SolrなしでAlfrescoをインストールして起動確認するところまで紹介した</a>ので、今回はAlfresco CE 201911GAをzipからインストールしてみようの第2回としてSolrのインストール手順をご紹介します。<br />
環境等については<a href="http://labo-blog.aegif.jp/2020/07/alfresco-201911gazip1.html" target="_blank">前回の記事</a>をご覧いただけたらと思います。<br />
<br />
まずはalfresco-search-services-1.4.0.zipを先にダウンロードしておき、作業用ディレクトリに置いておきます。<br />
<br />
<h3>
Solrのインストール</h3>
<br />
※ 今回はTLSの設定はしていません<br />
<br />
alfresco-search-services-1.4.0.zipを展開する<br />
<pre class="brush:bash">cd /opt/alfresco
unzip [作業用ディレクトリ]/alfresco-search-services-1.4.0.zip
cd alfresco-search-services
</pre>
<br />
検索で複数言語をサポートする設定を行うため、shared.propertiesを編集し保存する<br />
<pre class="brush:bash">vim solrhome/conf/shared.properties</pre>
<blockquote class="tr_bq">
<span style="background-color: #cfe2f3;">以下の3行のコメントを外し、設定を有効化する</span><br />
alfresco.cross.locale.datatype.0={http://www.alfresco.org/model/dictionary/1.0}text<br />
alfresco.cross.locale.datatype.1={http://www.alfresco.org/model/dictionary/1.0}content<br />
alfresco.cross.locale.datatype.2={http://www.alfresco.org/model/dictionary/1.0}mltext</blockquote>
今回はSSLなしで起動するため、以下の2つのファイルをhttpsを使わない設定に変更する<br />
<pre class="brush:bash">vim solrhome/templates/noRerank/conf/solrcore.properties
vim solrhome/templates/rerank/conf/solrcore.properties
</pre>
<blockquote class="tr_bq">
<span style="background-color: #cfe2f3;">以下の設定をhttpsからnoneに修正する</span><br />
alfresco.secureComms=none</blockquote>
以下のコマンドでSolrを起動する(全てデフォルト設定での起動)<br />
<pre class="brush:bash">solr/bin/solr start -force -a "-Dcreate.alfresco.defaults=alfresco,archive"
</pre>
<br />
<span style="color: #a64d79;">※ Solrを起動しようとするとrootユーザーで起動するのはセキュリティ上のリスクですと言うWarningが出るので、-force オプションを付けて起動していますが、</span><span style="color: #a64d79;">本番環境では起動用のユーザ(solrなど)を作って起動してください</span><br />
<br />
ブラウザで以下のURLを開き、Core Selectorドロップダウンリストにalfrescoとarchiveというコアができていることを確認する<br />
http://localhost:8983/solr<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtjLoSwXUOVkuUmjms4d_NQIdW0UKPQ1l7cxWVhTMYI3E1prSJeUstfU5jYf-UU3N5G5QqXfp7ppAtQlhhAIDGEU0YO_riIrsO4zd41t-vEioDQSralKi4mu24Ghetnt7ygjwgM4942jcrMuedSz6da_DqM4pfzocriGb7VK7o_Txu6n8X4rQ2lym3/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-07-22%2017.48.53.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="788" data-original-width="1600" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtjLoSwXUOVkuUmjms4d_NQIdW0UKPQ1l7cxWVhTMYI3E1prSJeUstfU5jYf-UU3N5G5QqXfp7ppAtQlhhAIDGEU0YO_riIrsO4zd41t-vEioDQSralKi4mu24Ghetnt7ygjwgM4942jcrMuedSz6da_DqM4pfzocriGb7VK7o_Txu6n8X4rQ2lym3/w526-h260/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-07-22%2017.48.53.png" width="526" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div>
"-Dcreate.alfresco.defaults = alfresco, archive" は、AlfrescoコアとArchiveコアを自動的に作成するためのオプションです。<br />
そのため、Solrを初めて起動するときは上記オプションを使用して起動しますが、2回目以降は -a "-Dcreate.alfresco.defaults=alfresco,archive" のオプションは不要です。<br />
<br />
Solrを停止したい場合は以下のコマンドを使用する<br />
<pre class="brush:bash">solr/bin/solr stop</pre>
<br class="Apple-interchange-newline" />
Solrのログはデフォルトで以下に保存されます。<br />
/opt/alfresco/alfresco-search-services/logs/solr.log<br />
<br />
<h3>
Alfrescoの起動と検索の確認</h3>
<br />
Tomcatを起動する<br />
<pre class="brush:bash">cd /opt/alfresco
tomcat/bin/startup.sh
</pre>
<br />
ブラウザで以下のURLを開き、admin/admin でログインする<br />
http://localhost:8080/share<br />
<br />
ヘッダ右にある検索窓から適当なキーワードで検索して検索結果が表示されることを確認する<br />
<br />
これでSolrのインストールとAlfrescoの起動確認ができました。<br />
次回は<a href="http://labo-blog.aegif.jp/2020/08/alfresco-201911gazip3.html">3回目(最終回)としてLibreOfficeやImageMagick等のインストール</a>をご紹介します。<br />
<br />tanakahttp://www.blogger.com/profile/18160344757788711995noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-54163422218796270492020-07-21T20:17:00.002+09:002022-08-17T17:57:58.567+09:00Liferayカスタマイズに欠かせないApplication Display Template(ADT)の紹介<div style="-en-clipboard: true;">
とたにです。
</div>
<div>
<br /></div>
<!--?xml version="1.0" encoding="UTF-8"?-->
<br />
<div>
今回はLiferayのカスタマイズでは欠かせないApplication Display Template(ADT)について紹介しようと思います。</div>
<div>
<br /></div>
<div>
<h3>
ADTとは</h3>
<div style="-en-clipboard: true;">
Liferayのアセットエンティティを表示する標準ポートレット(ナビゲーションメニューやアセットパブリッシャーなど)の見た目を変更するためのテンプレートのことです。
</div>
<!--?xml version="1.0" encoding="UTF-8"?-->
<br />
<div>
「見た目を変更する」と書いているのは表示対象となるエンティティ(ナビゲーションメニューの場合にはページ階層)は変えずに、表示形式のみを変更するためです。</div>
<div>
<br /></div>
<h3>
ADTに対応したポートレット</h3>
<div>
Liferay標準のポートレットでは以下がADTに対応しています。</div>
<div>
<ul>
<li>RSSアセットパブリッシャー</li>
<li>Wiki</li>
<li>アセットパブリッシャー</li>
<li>カテゴリナビゲーション</li>
<li>サイトマップ</li>
<li>タグナビゲーション</li>
<li>ナビゲーションメニュー</li>
<li>パンくずリスト</li>
<li>ブログ</li>
<li>メディアギャラリー </li>
</ul>
<h3>
実際に作ってみる</h3>
</div>
<div>
説明だけではイメージしずらいので、今回はナビゲーションメニューを使ってカード形式のナビゲーションを作ってみようと思います。<br />
<!--?xml version="1.0" encoding="UTF-8"?-->
今回はLiferay DXP 7.2を使用します。<br />
<br /></div>
<h4>
ADTの登録方法</h4>
<div>
<!--?xml version="1.0" encoding="UTF-8"?-->
サイト→サイトビルダー → アプリケーションディスプレイテンプレート をクリックします。</div>
<div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj62x5l2bvR6DvzCEJM-tmhJ4v-cY6QVviCtQyAfeu4CgQg97nTjEFi0zhNgXrWsmTcWraa5gYJkCHgn8TbQ0Y_u3yTGof1e2UQEi6W9yrEQ-0y0I3XTwTY4YtvUcxatv6RSf5WPEttdzcw1zwXQxTEBtZ_pqqJ5MQjAS70V-vs_sf2THjWWD13k6CF/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2018.07.53.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="750" data-original-width="1600" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj62x5l2bvR6DvzCEJM-tmhJ4v-cY6QVviCtQyAfeu4CgQg97nTjEFi0zhNgXrWsmTcWraa5gYJkCHgn8TbQ0Y_u3yTGof1e2UQEi6W9yrEQ-0y0I3XTwTY4YtvUcxatv6RSf5WPEttdzcw1zwXQxTEBtZ_pqqJ5MQjAS70V-vs_sf2THjWWD13k6CF/w440-h206/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2018.07.53.png" width="440" /></a></div><br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div>
<!--?xml version="1.0" encoding="UTF-8"?-->
+アイコンからナビゲーションメニューテンプレートを選択します。</div>
<div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTkjFplmjrcNUTmQYBy3ZTfsvVncTLqqbLXdCR5HKbxDltg2Za9lJ0MHcEkv2C--4Gzt3zFXRw1NmpVPCzcHabeiuowcxOaUFtdt9WRJqeAB7Gv1ofFYxzx13VJNL6CtKFolxK4_dnn5WcSIjr-QAnqFqC5jCXGyMWhAlt9NMxvsUkKUEEs_HD5IH9/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2018.10.07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="654" data-original-width="1600" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTkjFplmjrcNUTmQYBy3ZTfsvVncTLqqbLXdCR5HKbxDltg2Za9lJ0MHcEkv2C--4Gzt3zFXRw1NmpVPCzcHabeiuowcxOaUFtdt9WRJqeAB7Gv1ofFYxzx13VJNL6CtKFolxK4_dnn5WcSIjr-QAnqFqC5jCXGyMWhAlt9NMxvsUkKUEEs_HD5IH9/w429-h176/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2018.10.07.png" width="429" /></a></div></div>
<div>
<br /></div>
<div>
以下のように入力して保存します。</div>
<div>
<!--?xml version="1.0" encoding="UTF-8"?-->
<br />
<ul>
<li>名前: card menu ADT</li>
<li>詳細はデフォルトままでOKです。(フォーマットはFreeMarkerが選択されます)<br />
</li>
<li>スクリプトとして以下を記述して保存します。</li>
</ul>
</div>
</div>
<pre class="brush: plain;"><#if preview>
<div class="alert alert-info">
<@liferay.language key="there-are-no-pages-to-display-for-the-current-page-level" />
</div>
</#if>
<#else>
<#assign
portletDisplay = themeDisplay.getPortletDisplay()
navbarId = "navbar_" + portletDisplay.getId()
/>
<div id="${navbarId}">
<ul aria-label=<@liferay.language key="site-pages" />" class="display-style-icon list-unstyled row navigation-menu-portlet" role="menubar">
<h1 class="hide-accessible"><@liferay.language key="navigation" /></h1>
<#assign navItems = entries />
<#list navItems as navItem>
<#assign showChildren = (displayDepth != 1) && navItem.hasBrowsableChildren() />
<#if navItem.isBrowsable() || showChildren>
<#assign
nav_item_attr_selected = ""
/>
<#if navItem.isSelected()>
<#assign
nav_item_attr_selected = "aria-selected='true'"
/>
</#if>
<li class="entry-card lfr-asset-item" id="layout_${navItem.getLayoutId()}" ${nav_item_attr_selected} role="presentation">
<div class="card">
<div class="card-header" style="background-color: #ececec;">
<a href=${navItem.getURL()} ${navItem.getTarget()}>${navItem.getName()}</a>
</div>
<div class="card-body" >
<p class="card-text" style="background-image: url('${navItem.iconURL()}');
background-position:center center; background-repeat: no-repeat;background-size:cover; min-height: 200px;">
</p>
</div>
</div>
</li>
</#if>
</#list>
</ul>
</div>
</#if>
</pre>
<h4>
ADTの適用 </h4>
<div>
<!--?xml version="1.0" encoding="UTF-8"?-->
<br />
<div>
準備として、サイトページにナビゲーションメニューを配置します。(ウィジェットからナビゲーションメニューをドラッグ&ドロップします。)
</div>
<div>
ここでは適当にトップページと同レベルに複数ページを作成しておきました。</div>
</div>
<!--?xml version="1.0" encoding="UTF-8"?--><div><div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXS0ErQS2FbNyMOF6U1FqDSNAQW78-TYbyuQTwehRNOaYITf5FMyFAGvbDXwzrNETRKM1uvxtuCF6L-kjSS1PSh2h67HtU4eJDqMUyRl0Y9Imskq4ZruMsRK6ciCmQXeTyNm3P-18SERY6nfH5O0GEKcUy1OrEwZ3jiwwEbxEG_8KZ1Fi0d_y5MKLY/s926/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.11.30.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="328" data-original-width="926" height="113" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXS0ErQS2FbNyMOF6U1FqDSNAQW78-TYbyuQTwehRNOaYITf5FMyFAGvbDXwzrNETRKM1uvxtuCF6L-kjSS1PSh2h67HtU4eJDqMUyRl0Y9Imskq4ZruMsRK6ciCmQXeTyNm3P-18SERY6nfH5O0GEKcUy1OrEwZ3jiwwEbxEG_8KZ1Fi0d_y5MKLY/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.11.30.png" width="320" /></a></div><br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
初期状態は上記のようになっているはずです。<br />
<br />
適用されているADTを変更するには、ポートレットメニューから設定をクリックします。<br />
テンプレートを表示する、をクリックして先ほど作成したcard menu ADTを選択します。<br />
<div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhazSkoElOCr9evSBmWJ_RCWFzjyZR0kd-F_gjqMlHIP_9jUc70N9NHPxwXEbIzU8E_3ih3z4Qgyu5pafQBc3LB_VzCY1pxBHunDGD66UIOTY6IzWnQsLoRf3-ziuNjbqk4D9fxoG1IE6lIMCWjaoKsCy6_Ej5lT69AJGZeodwUuBhaLhrsmkj3GwN2/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.13.19.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1344" data-original-width="1600" height="269" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhazSkoElOCr9evSBmWJ_RCWFzjyZR0kd-F_gjqMlHIP_9jUc70N9NHPxwXEbIzU8E_3ih3z4Qgyu5pafQBc3LB_VzCY1pxBHunDGD66UIOTY6IzWnQsLoRf3-ziuNjbqk4D9fxoG1IE6lIMCWjaoKsCy6_Ej5lT69AJGZeodwUuBhaLhrsmkj3GwN2/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.13.19.png" width="320" /></a></div><a href="about:invalid#zClosurez" style="margin-left: 1em; margin-right: 1em;"></a></div>
<br />
保存後にページを参照すると以下のようにナビゲーションメニューの見た目が変更されていることがわかります。<br />
<div style="text-align: center;">
<a href="about:invalid#zClosurez" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqcE-c89bmd8J_54Phd9Tl0YU65hS2OlAlbTEC2vawCKiJJNtNmRGvUFQ6fCI2Kv5tMI9llv7anAXHHzfJuTshVa7IvdPVlddxO3SqWFFQig7jWKgLuDo5IaD8BhsSQt6UygPFe6hZrjXSI7UHFf0dX8UQkDrSyUSyVCf59iWjfeJ9UnugzlIGtGL-/s1758/%E3%82%BF%E3%82%99%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%88%E3%82%99.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="870" data-original-width="1758" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqcE-c89bmd8J_54Phd9Tl0YU65hS2OlAlbTEC2vawCKiJJNtNmRGvUFQ6fCI2Kv5tMI9llv7anAXHHzfJuTshVa7IvdPVlddxO3SqWFFQig7jWKgLuDo5IaD8BhsSQt6UygPFe6hZrjXSI7UHFf0dX8UQkDrSyUSyVCf59iWjfeJ9UnugzlIGtGL-/w375-h185/%E3%82%BF%E3%82%99%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%88%E3%82%99.png" width="375" /></a></div><br />
今回はカードの中身にページに設定できるアイコンを表示できるように作成したので、ページにアイコンを設定してみると以下のように表示されます。<br />
<div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI__1WVifGRXHsZtRlGhu2uWN31owQN9jIeW79Ra3fMtlqHhdQxpw4LMyQSr3TDlfSw8xB8NcJItF7FgWXz7uLrQQjreIxmNOj-tUr57Yv53Ozu546Wkq6tBxSNce9NAmrx_a0EmK8lRqCLCBS9bBTORqoyIIxlNURCZn1RT9ZBXcjsUsBAlcMCqqF/s1232/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.20.12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="794" data-original-width="1232" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI__1WVifGRXHsZtRlGhu2uWN31owQN9jIeW79Ra3fMtlqHhdQxpw4LMyQSr3TDlfSw8xB8NcJItF7FgWXz7uLrQQjreIxmNOj-tUr57Yv53Ozu546Wkq6tBxSNce9NAmrx_a0EmK8lRqCLCBS9bBTORqoyIIxlNURCZn1RT9ZBXcjsUsBAlcMCqqF/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.20.12.png" width="320" /></a></div></div>
<h3>
</h3>
<h3>
まとめ</h3>
<div style="-en-clipboard: true;">
今回はナビゲーションポートレットにADTを適用して簡単なカード形式メニューを作ってみました。
</div>
<div>
<br /></div>
<div>
ADTを使いこなすには、表示対象であるアセットエンティティ(今回の例であればページ)について
</div>
<div>
どのような属性がありどのような値が格納されているか、を把握しておく必要がありますが、
</div>
<div>
簡単なテンプレートを定義するだけで劇的に見た目をカスタマイズできるとても強力なツールです。
</div>
<div>
<br /></div>
<!--?xml version="1.0" encoding="UTF-8"?-->
<br />
<div>
すべてゼロベースでポートレットを作るよりも簡単にLiferayをカスタマイズできるので、積極的に活用してみてください。 </div>
<br /></div>
<!--?xml version="1.0" encoding="UTF-8"?-->
Totanihttp://www.blogger.com/profile/05482818344212023797noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-34272426499589535602020-07-21T14:06:00.002+09:002022-08-17T18:03:37.442+09:00Alfresco 201911GAをzipからインストールしてみよう【その1】こんにちは。たなかです。<br />
<br />
ステイホーム中にぬか漬けはじめました。<br />
茄子の色をもう少しキレイに出したくて試行錯誤の日々です。<br />
<br />
今回はAlfresco CE 201911GAをzipからインストールしてみようの第1回目としてAlfresco起動までの手順をご紹介します。<br />
<br />
6.xからインストーラがなくなったので、Dockerが使えない場合や使いたくない環境で簡単にインストールして試すことが難しくなってしまいました。<br />
Dockerが使える環境であれば、<a href="http://labo-blog.aegif.jp/2020/03/alfresco-community-edition.html" target="_blank">以前紹介</a>したとおり、GitHubのプロジェクトをcloneして docker-compose up と言うコマンドで起動することができます。<br />
<br />
今回ご紹介するのは動作確認のためのインストール手順となっており、本番環境で使うことを想定したセキュリティやパフォーマンスを考慮したものではありませんのでご注意いただければと思います。<br />
基本的には<a href="https://docs.alfresco.com/community/concepts/install-community-intro.html" target="_blank">Alfrescoの公式ドキュメント</a>に沿った手順になっておりますが、分かりにくい部分を補足したり、動作確認のため必要最低限の手順に削ったりしている部分もあります。<br />
<br />
今回使用している環境については以下になります。<br />
CentOS 7.8<br />
OpenJDK 11.0.7<br />
PostgreSQL 11.8<br />
Tomcat 8.5.56<br />
Alfresco Community Edition 201911GA<br />
ActiveMQ 5.15.13<br />
<br />
OS、DBやJava等は<a href="https://docs.alfresco.com/6.2/concepts/supported-platforms-ACS.html" target="_blank">有償版のSupported Platform</a>に掲載されているものであれば使い慣れたものを使用しても大丈夫です。<br />
有償版は製品としては無償のCommunity版をベースに管理者向けのツールやクラスタリングのための機構等が追加されたものなので、有償版のSupported Platformに載っている(そのPlatformで動作確認が行われている)という情報はCommunity版でも参考になります。<br />
バージョンが完全に一致していなくても、メジャーバージョンが同じで新しいバージョンのものを使えば問題は起こりにくいのではないかと思われます。<br />
<br />
※ 環境によってはOpenJDKのインストールやPostgreSQLでDBを作成するまでの手順等で、異なる箇所があるかもしれません。<br />
<br />
Alfresco CE 201911GAは先にダウンロードしておきます。<br />
<br />
<h3>
OpenJDK 11 をインストール</h3>
<div>
<br /></div>
yumコマンドでインストールする<br />
<pre class="brush:bash">yum install java-11-openjdk</pre>
<br />
<span style="background-color: white;">新規ファイルを作成しJAVA_HOMEを設定し保存する</span><br />
<pre class="brush:bash">vim /etc/profile.d/java.sh</pre>
<br />
<h3>
PostgreSQL11をインストール</h3>
<br />
yumコマンドでインストールし設定、起動する<br />
<pre class="brush:bash">yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
yum install postgresql11-server
/usr/pgsql-11/bin/postgresql-11-setup initdb
systemctl enable postgresql-11
systemctl start postgresql-11
</pre>
<br />
<br />
<h3>
Alfresco用DBを作成</h3>
<br />
psqlを実行する<br />
<pre class="brush:bash">su - postgres
psql
</pre>
<br />
<br />
以下のSQLを実行してDB作成、ロール作成、パスワード設定を行う<br />
<pre class="brush:sql">CREATE DATABASE alfresco ENCODING 'utf8';
CREATE ROLE alfresco LOGIN PASSWORD 'alfresco';
GRANT ALL ON DATABASE alfresco TO alfresco;
</pre>
<br />
後で認証方法をmd5認証(パスワード認証)に変えるため、postgresロールにパスワードを設定しておく<br />
<pre class="brush:sql">ALTER USER postgres WITH ENCRYPTED PASSWORD ‘postgres’;
</pre>
<br />
local:allとIPv4、IPv6のlocalからの認証をmd5に変更して保存する<br />
<pre class="brush:bash">systemctl stop postgresql-11.service
vim /var/lib/pgsql/11/data/pg_hba.conf
</pre>
<br />
PostgreSQLを起動し、接続できることを確認する<br />
<pre class="brush:bash">systemctl start postgresql-11.service
psql -U alfresco -d alfresco
</pre>
<br />
<br />
<h3>
Tomcatのダウンロードと設定</h3>
<br />
Alfrescoインストールディレクトリを作成する<br />
<pre class="brush:bash">mkdir -p /opt/alfresco
</pre>
<br />
<br />
公式サイトからTomcatをダウンロードして/opt/alfrescoに配置し、展開する<br />
<pre class="brush:bash">cd /opt/alfresco
tar xzvf apache-tomcat-8.5.56.tar.gz
rm apache-tomcat-8.5.56.tar.gz
</pre>
<br />
<br />
ディレクトリ名を分かりやすくシンプルに変更する<br />
<pre class="brush:bash">mv apache-tomcat-8.5.56 tomcat
</pre>
<br />
<br />
shared/classesディレクトリを作成し、Tomcatのcatalina.propertiesを編集してshared/classesを読み込むように設定する<br />
<pre class="brush:bash">mkdir -p tomcat/shared/classes
vim tomcat/conf/catalina.properties
</pre>
<blockquote class="tr_bq">
<span style="background-color: #cfe2f3;">catalina.propertiesを以下のように変更して保存する</span><br />
shared.loader=${catalina.base}/shared/classes</blockquote>
<span style="color: #3d85c6;">※ 今回はSolr用のTLS設定は行いません</span><br />
<br />
<h3>
Alfrescoのインストール</h3>
<br />
作業用のディレクトリ(どこでもOKです)に移動する<br />
<pre class="brush:bash">cd [作業用ディレクトリ]
</pre>
<br />
※ ダウンロードしておいたAlfrescoを配置しておく<br />
<br />
Alfrescoのzipファイルを展開する<br />
<pre class="brush:bash">unzip alfresco-content-services-community-distribution-6.2.0-ga.zip
cd alfresco-content-services-community-distribution-6.2.0-ga
</pre>
<br />
<br />
warファイルとJDBCドライバをTomcat配下にコピーする<br />
<pre class="brush:bash">cp web-server/webapps/* /opt/alfresco/tomcat/webapps/
cp web-server/lib/postgresql-42.2.6.jar /opt/alfresco/tomcat/lib/
</pre>
<br />
<br />
Tomcatにもともと入っていたwebapps配下のディレクトリを削除する<br />
<pre class="brush:bash">cd /opt/alfresco/tomcat/webapps
rm -rf ROOT
rm -rf docs
rm -rf examples
rm -rf host-manager
rm -rf manager
</pre>
<br />
<br />
alfresco-global.propertiesを以下のように編集して保存する<br />
<pre class="brush:bash">cd /opt/alfresco/tomcat/shared/classes/
cp [作業用ディレクトリ]/alfresco-content-services-community-distribution-6.2.0-ga/web-server/shared/classes/alfresco-global.properties.sample ./
mv alfresco-global.properties.sample alfresco-global.properties
vim alfresco-global.properties</pre>
<br />
<blockquote class="tr_bq" style="text-align: left;">
<span style="background-color: #cfe2f3;">以下の設定のコメントを外して値を変更する</span></blockquote>
<blockquote class="tr_bq" style="text-align: left;">
dir.root=/opt/alfresco/alf_data<br />
db.username=alfresco<br />
db.password=alfresco<br />
jodconverter.enabled=false<br />
db.driver=org.postgresql.Driver<br />
db.url=jdbc:postgresql://localhost:5432/alfresco</blockquote>
<br />
<blockquote class="tr_bq" style="text-align: left;">
<span style="background-color: #cfe2f3;">以下を追記する</span></blockquote>
<blockquote class="tr_bq" style="text-align: left;">
index.subsystem.name=solr6<br />
solr.secureComms=none<br />
solr.port=8983<br />
transform.service.enabled=false<br />
local.transform.service.enabled=false<br />
legacy.transform.service.enabled=false</blockquote>
<br />
alfresco.warにalfresco-share-services.ampを適用する<br />
<pre class="brush:bash">cd /opt/alfresco
cp -a [作業用ディレクトリ]/alfresco-content-services-community-distribution-6.2.0-ga/bin ./
cp -a [作業用ディレクトリ]/alfresco-content-services-community-distribution-6.2.0-ga/amps ./
cd bin
chmod +x apply_amps.sh
./apply_amps.sh
</pre>
<br />
<br />
alfresco.warが更新されていることを確認する<br />
<span style="color: #3d85c6;">※ AMPが正常に適用されると、元のalfresco.warがalfresco.war-xxxxxxxxxxxxx.bakとリネームされて新しいalfresco.warが作られるのでbakを確認する</span><br />
<pre class="brush:bash">cd /opt/alfresco
ls -la tomcat/webapps
</pre>
<br />
<br />
<h3>
ActiveMQのインストール</h3>
<br />
ActiveMQをダウンロードして展開し、起動する<br />
<pre class="brush:bash">tar xzvf apache-activemq-5.15.13-bin.tar.gz
rm apache-activemq-5.15.13-bin.tar.gz
cd apache-activemq-5.15.13/bin
./activemq start
</pre>
<br />
<br />
<h3>
Alfrescoの起動確認</h3>
ここまでの手順が正しくできているかどうかの確認のため、一度Alfrescoを起動します。<br />
<br />
<br />
Tomcatを起動する<br />
<pre class="brush:bash">cd /opt/alfresco
tomcat/bin/startup.sh
</pre>
<br />
<br />
tomcat/logs/catalina.out を監視する<br />
<pre class="brush:bash">tail -f tomcat/logs/catalina.out
</pre>
<span style="color: #a64d79;">※ Server startup in 47069 ms のようなログが出ることを確認する</span><br />
<span style="color: #a64d79;">※ </span><span style="color: #a64d79;">まだ検索に使うSolrはインストールしていないため、ログにSolr関連のエラーが出力されるかと思いますが、現段階では気にしなくて大丈夫です。</span><br />
<span style="color: #a64d79;">Solrのインストールはその2としてご紹介します。</span><br />
<br />
<div>
</div>
ブラウザから以下のURLにアクセスして、admin/adminでログインできるか確認する<br />
http://localhost:8080/share<br />
<br />
Tomcatを停止する場合は以下のコマンドを使用する<br />
<pre class="brush:bash">tomcat/bin/shutdown.sh
</pre>
<br />
<span style="color: #a64d79;">※ 停止できないことがあるのでその場合はプロセスIDを調べてkillコマンドで停止します</span><br />
<div>
<br />
今回はSolrなしでAlfrescoを起動してみるところまでをご紹介しました。<br />
次回は<a href="http://labo-blog.aegif.jp/2020/07/alfresco-201911gazip2.html">SolrをインストールしAlfrescoを起動する方法</a>をご紹介します。</div>
<pre class="code highlight js-syntax-highlight shell white" lang="shell" v-pre="true"><h3>
</h3>
</pre>
tanakahttp://www.blogger.com/profile/18160344757788711995noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-86778556553427173062020-07-17T14:34:00.002+09:002022-08-17T18:15:09.878+09:00Liferayの表示ページテンプレートを使ってみようこんにちは、かわべです。<br />
最近は家の周りでやたらと工事が行われており、Web会議に参加すると騒音に驚かれることしばしばです。<br />
<br />
この記事ではLiferay DXP 7.1から追加された表示ページテンプレート(Display Page Templates)の使い方を紹介します。表示ページテンプレートはコンポーネントやセクションなどのページフラグメントを使ってコンテンツページを作るのと同じ要領で、特定のコンテンツ種別の個々の表示ページを作ることができるという機能です。<br />
これはDXP 7.0までのバージョンではFreeMarkerでWebコンテンツテンプレートを記述しなければ実現できなかったことです。FreeMarkerで思い通りの画面を作るにはコーディング知識が必要になってくるので、開発知識がなくても簡単にコンテンツを表示するためのページが作れるようになったのは画期的です!<br />
<br />
それでは使い方を順を追って見てみましょう。Liferayを利用する旅行会社が旅行の目的地をWebコンテンツとして作成し、それを表示するための個別ページを作りたい、という単純なシナリオに沿ってやっていきたいと思います。<br />
利用バージョンはLiferay DXP 7.2 SP2です(少し前のバージョンだと落とし穴がありました…それは最後に書きます)。<br />
<br />
<h3>
1. 表示させるコンテンツタイプ(エンティティ)の作成</h3>
表示ページテンプレートを適用可能なのは、デフォルトで<br />
<br />
<ul>
<li>Webコンテンツ</li>
<li>ドキュメント</li>
<li>ブログのエントリ</li>
</ul>
<br />
の3種類のコンテンツです。<br />
今回は旅行の目的地を取り扱いやすいように、専用のWebコンテンツストラクチャーを新規で作成します。<br />
管理者としてログインし、コントロールパネル→コンテンツ→Webコンテンツ→ストラクチャに移動し、追加ボタンから「旅行目的地」という名前で以下のストラクチャーを追加します。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOMsbZbNthtwYVo3J9sHC2Z7uqwhg5XoRw0-emCaRkkWa6z64w3fh6HJNaBFtJwbD5CM-g_AmYXKmPKVooYHjXKeWncoky5GVjdAWIXxAxO7ej-vqcoqOlwjQXV7nJV660oOYuIOwXvhwXTeoxlbZ-Iv01qXQxakEAOTPDzwTWwcd6_BrpK1Jpc2yP/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2017.33.21.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="976" data-original-width="1600" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOMsbZbNthtwYVo3J9sHC2Z7uqwhg5XoRw0-emCaRkkWa6z64w3fh6HJNaBFtJwbD5CM-g_AmYXKmPKVooYHjXKeWncoky5GVjdAWIXxAxO7ej-vqcoqOlwjQXV7nJV660oOYuIOwXvhwXTeoxlbZ-Iv01qXQxakEAOTPDzwTWwcd6_BrpK1Jpc2yP/w437-h266/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2017.33.21.png" width="437" /></a></div></div>
<br />
さて、これまではWebコンテンツのストラクチャを作成したらもれなくペアとしてWebコンテンツテンプレートを作成していたのですが…今回はWebコンテンツテンプレートは作らずに、表示ページテンプレートの作成に進みます。<br />
(Liferayを使っていると何種類かの〇〇テンプレートが出てくるので、混乱しないように気をつけてくださいね)<br />
<br />
<h3>
2. 表示ページテンプレートの作成</h3>
コントロールパネルからサイトビルダー→サイトページを開き、表示ページテンプレートタブを開きます。<br />
<br />
[+]ボタンで新規追加画面を出して、名前を「旅行先表示」と入力し、コンテンツ種類としてWebコンテンツ、サブタイプに旅行目的地を選んで保存します。<br /><div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWK_VpZwgZjTfp0JinxTzQ29AbVI30NHo12t32b0mQlVLOJUhqjJmzcewjz2t0n_O4VQ_XhXXi-G2cILXLZgUX8svYyGXIxy5ujDN9PS622KEGrPm-_7TG2gvOSIrQRFM_de22Y_ANbo8C_cID0ECt28J4fkml2AMAkBv5LvUdbc_BLPWRzyfIwbjd/s1164/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.39.30.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="892" data-original-width="1164" height="245" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWK_VpZwgZjTfp0JinxTzQ29AbVI30NHo12t32b0mQlVLOJUhqjJmzcewjz2t0n_O4VQ_XhXXi-G2cILXLZgUX8svYyGXIxy5ujDN9PS622KEGrPm-_7TG2gvOSIrQRFM_de22Y_ANbo8C_cID0ECt28J4fkml2AMAkBv5LvUdbc_BLPWRzyfIwbjd/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.39.30.png" width="320" /></a></div></div>
<br />
すると、フラグメントを利用したコンテンツページ作成とほぼ同じ編集画面が開きます。<br />
まずは、セクション配下の基本セクションからバナー(中央)を編集中のページに配置してみましょう。<br /><div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvhMtzaDLbru48q1tEKJrGtLZtsFv-jNK50EOtX3-w-NpPFmVWlUOfs8v286uF_n0qV5hInIcwx9AiAAy0Xn2PVkHDozxWnlA7Vus0HlsIfOxUJICLhOEypcGMOt2XOqBR1bHt887Y-v-6Sw9DiQhuLsKgLZMjIROgEB7zsedfWs8M_ogbQeK9MrLQ/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.43.15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1063" data-original-width="1600" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvhMtzaDLbru48q1tEKJrGtLZtsFv-jNK50EOtX3-w-NpPFmVWlUOfs8v286uF_n0qV5hInIcwx9AiAAy0Xn2PVkHDozxWnlA7Vus0HlsIfOxUJICLhOEypcGMOt2XOqBR1bHt887Y-v-6Sw9DiQhuLsKgLZMjIROgEB7zsedfWs8M_ogbQeK9MrLQ/w402-h268/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.43.15.png" width="402" /></a></div></div>
<br />
<br />
コンテンツページ作成でお馴染みですが、セクションやコンポーネントで編集可能となっているエリアは自由にテキストなどの編集が可能です。<br />
<div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXRNza-nK10VlIeYURbd1eFLoO4FdOKbrRpFBhVW5rlNV7xxO7UVHySifrZh-bvPq9uaQDyp2PClyBHh6SyHs4EgJds7UiznJsYnQ6yqlSROzPrMSdU_ENOEa_xGmvZnEEazb4gsJoNaBThDEiErF_FHoBwcvN22QY_q1kfqi9rs3Dh06kZVwv3JJb/s1012/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2018.30.20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="506" data-original-width="1012" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXRNza-nK10VlIeYURbd1eFLoO4FdOKbrRpFBhVW5rlNV7xxO7UVHySifrZh-bvPq9uaQDyp2PClyBHh6SyHs4EgJds7UiznJsYnQ6yqlSROzPrMSdU_ENOEa_xGmvZnEEazb4gsJoNaBThDEiErF_FHoBwcvN22QY_q1kfqi9rs3Dh06kZVwv3JJb/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2018.30.20.png" width="320" /></a><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz1N3h_CnQWQOZB1N6-HVYJKSUW92hMeigOkJHLAKnlFvREXl43CEHCOIu4ToMXIb9XYT32AxT8egGMidqutgMgnUlVfeegRi6XhPwoW_mip5vitK6zI0bGiYUGAr-JgSoyuZmTUnMiZGfrNVcgAoydR4Vldi5X13b-HERXKifGbSbLM6ZYoFrxWcx/s1004/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2018.30.52.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="490" data-original-width="1004" height="156" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz1N3h_CnQWQOZB1N6-HVYJKSUW92hMeigOkJHLAKnlFvREXl43CEHCOIu4ToMXIb9XYT32AxT8egGMidqutgMgnUlVfeegRi6XhPwoW_mip5vitK6zI0bGiYUGAr-JgSoyuZmTUnMiZGfrNVcgAoydR4Vldi5X13b-HERXKifGbSbLM6ZYoFrxWcx/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2018.30.52.png" width="320" /></a></div></div></div>
<br />
(バナータイトルの編集部分を「自由にタイトルを入力」に変えてみました)<br />
<br />
しかしそれだけではなく、コンテンツ表示ページテンプレートでは表示対象のコンテンツが持つ要素を編集可能エリアにマッピングすることができるのです。<br />
<br />
左の「編集」アイコンではなく右の「マッピング」(翻訳がおかしいですが…)アイコンを選ぶと、<div><br /><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih_qWnFbPhz4TOO7SwTe7ynbS6glJLzBJGV6PU7oUQNTIbR2JjemF-qPunrnkfCg3Uc0clwdUmS13CsNXl9zLFVV10plsyAuQ6pwFDXpinwSC6J65qNbhNFjS4EN9ZbNMMC5jCDP5fzbmFtU4sGy00tXPogolcvHQ79YPnDmOKk7yHhcl-qWSpxmWR/s988/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2018.30.59.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="476" data-original-width="988" height="154" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih_qWnFbPhz4TOO7SwTe7ynbS6glJLzBJGV6PU7oUQNTIbR2JjemF-qPunrnkfCg3Uc0clwdUmS13CsNXl9zLFVV10plsyAuQ6pwFDXpinwSC6J65qNbhNFjS4EN9ZbNMMC5jCDP5fzbmFtU4sGy00tXPogolcvHQ79YPnDmOKk7yHhcl-qWSpxmWR/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2018.30.59.png" width="320" /></a></div></div>
<br />
表示対象のコンテンツ(今回の場合は先程作成した「旅行目的地」)が持つマッピング可能な要素が選択できます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKXUzuHaopfvgCs6axMkOGWU36AepIOvc20YlWRnwd5p8Xr29W8F16UqCLk0EDliZ3GO8aE6HInr1QKDgl52yKgxdJgkjlwUsNIcZPju0mWrdczIBKpPlch7SYIAiSSs8QNV17JNUGoj7iN4EW2QGKfBIJ5JQz0FFUpPTYq6EVZyKx9b7QX-xsJipj/s970/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2018.31.14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="568" data-original-width="970" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKXUzuHaopfvgCs6axMkOGWU36AepIOvc20YlWRnwd5p8Xr29W8F16UqCLk0EDliZ3GO8aE6HInr1QKDgl52yKgxdJgkjlwUsNIcZPju0mWrdczIBKpPlch7SYIAiSSs8QNV17JNUGoj7iN4EW2QGKfBIJ5JQz0FFUpPTYq6EVZyKx9b7QX-xsJipj/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2018.31.14.png" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrbzxQN33ZPpuA9icA2Thbo1GlfbkTRXF3XstZP71qnQ5wBFEw7jlSTxh2n0HXdypOOUUI22dGqvE5eRUDnuH4JaF9ToRszWcEKz0AQkD3RePny8JuYSHc0JdI9zqD8gcALtACVbhk6XNDJXl0HFZdXobxPxmNTDzXx7WM42pIOTZQYBZIynpUxf1Q/s528/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.49.49.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="528" data-original-width="524" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrbzxQN33ZPpuA9icA2Thbo1GlfbkTRXF3XstZP71qnQ5wBFEw7jlSTxh2n0HXdypOOUUI22dGqvE5eRUDnuH4JaF9ToRszWcEKz0AQkD3RePny8JuYSHc0JdI9zqD8gcALtACVbhk6XNDJXl0HFZdXobxPxmNTDzXx7WM42pIOTZQYBZIynpUxf1Q/w239-h241/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.49.49.png" width="239" /></a></div></div>
<br />
下の方にある「名前」と「説明」がWebコンテンツストラクチャに定義した要素ですね。今回は上部のタイトル部分に「名前」、その下の文章部分に「説明」をマッピングします。そして背景画像には同じ要領で「画像」をマッピングしてみます。<br />
<br />
マッピングが設定された部分は薄紫色で囲われます。<br />
<div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizWSpbyZ8xPf6f_DKi-jiRwz6cg4lOYuOXq5OZx2qSLNDWZTMEZUTJQJt7XcWpvF2RLFCLT9Eznnms6eeH94hoWh3tyJGKP0UuP1S5t11KGRcGKxwmms6YKjU-pYDQEFERnVrWd4jUVt51xrKW0VBtBdTLlAAKYN94Eh3Y-GC7mdv3PTs0EF0qwR01/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.51.49.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1070" data-original-width="1600" height="279" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizWSpbyZ8xPf6f_DKi-jiRwz6cg4lOYuOXq5OZx2qSLNDWZTMEZUTJQJt7XcWpvF2RLFCLT9Eznnms6eeH94hoWh3tyJGKP0UuP1S5t11KGRcGKxwmms6YKjU-pYDQEFERnVrWd4jUVt51xrKW0VBtBdTLlAAKYN94Eh3Y-GC7mdv3PTs0EF0qwR01/w417-h279/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2019.51.49.png" width="417" /></a></div></div><br />
(リンクボタン部分は、今回はストラクチャにリンクURLを要素として持たせるのを忘れたので、ひとまず表示文言だけ編集して「詳しく見る」に変えておきました。)<br />
<br />
これでコンテンツのマッピングは完了です。その他はコンテンツページと同じ要領で、作りたいページやデザインに応じて適宜ウィジェットやコンポーネント、セクションなどを配置して編集・設定してください。<br />
<br />
<h3>
3. コンテンツの作成</h3>
それでは「旅行目的地」コンテンツを追加し、表示ページテンプレートを使って表示されるように設定してみましょう。<br />
コントロールパネル→コンテンツ→Webコンテンツに移動し、[+]から「旅行目的地」を追加する画面を開きます。<br />
タイトル、名前、説明に適当に入力し、画像をアップロードします。<br /><div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8hzbUy1Na4YwUbFDSl060TWxi1cFuLtAtFEM-jMl-Fz8ZnmU3IRyOagz0UV_guA4s5moNMaIPgVkBZdkfUep82Ea-VA4GfPbLQzDHJTO-6Wtp9yfsQur_fbxn4pCWbShqwFF875XCiRYJWJ1i2r8-M0pUCECskuKh2Z7rXetejt2xj3g9xM2OkF0p/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2020.07.06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1112" data-original-width="1600" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8hzbUy1Na4YwUbFDSl060TWxi1cFuLtAtFEM-jMl-Fz8ZnmU3IRyOagz0UV_guA4s5moNMaIPgVkBZdkfUep82Ea-VA4GfPbLQzDHJTO-6Wtp9yfsQur_fbxn4pCWbShqwFF875XCiRYJWJ1i2r8-M0pUCECskuKh2Z7rXetejt2xj3g9xM2OkF0p/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2020.07.06.png" width="320" /></a></div></div>
<br />
そして右側の設定ペインの「表示ページテンプレート」で「特定の表示ページテンプレート」をプルダウンで選択し、選択をクリックすると開くポップアップ画面で先程作成した「旅行先表示」を選択します。</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCssQz-zlAWTY0f6oglwoVvNJnV3WBi4oJldMZCrRITGrgroAdNsnuZt_ahj0VVEbVW5gEYyjgIqdBWhu1wpNgh3cq9Xd4M4pOtRAy621vuWHoh2faAA2GT_EgbSSEhXL5LUZVGoaR_Sz_viFemGwocbYmFOMB0rtoZwTCFuo3G0slnnKorl-OqY5f/s624/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2020.07.33.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="200" data-original-width="624" height="103" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCssQz-zlAWTY0f6oglwoVvNJnV3WBi4oJldMZCrRITGrgroAdNsnuZt_ahj0VVEbVW5gEYyjgIqdBWhu1wpNgh3cq9Xd4M4pOtRAy621vuWHoh2faAA2GT_EgbSSEhXL5LUZVGoaR_Sz_viFemGwocbYmFOMB0rtoZwTCFuo3G0slnnKorl-OqY5f/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2020.07.33.png" width="320" /></a></div><br /><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAaIuu3FJUH1SmarOPeerHLNyi1kB-VikEP4xXKA3TjKDFMFnbfbNAVrVyMNA4OLnTjAlr_Ar255uB36mN_zLL4kzSVW1wIcBI21XVS-ijPp6-rwMJqEykVBDt_285mbCQroDcRoERaCaUykZi7A7bGzjQeJPc8fySg7IMAWC6eUGmBPf8v0Y4osOo/s818/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2020.07.47.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="818" data-original-width="714" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAaIuu3FJUH1SmarOPeerHLNyi1kB-VikEP4xXKA3TjKDFMFnbfbNAVrVyMNA4OLnTjAlr_Ar255uB36mN_zLL4kzSVW1wIcBI21XVS-ijPp6-rwMJqEykVBDt_285mbCQroDcRoERaCaUykZi7A7bGzjQeJPc8fySg7IMAWC6eUGmBPf8v0Y4osOo/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2020.07.47.png" width="279" /></a></div>
<br />
そしてフレンドリURLはデフォルトだとタイトルに引きずられるので、URLとしてわかりやすい英数字にしておきます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5LjJfmEoqQTCTUg1poGq48GeFqhEEworCJMwkVbiQn6S-zevkMdjlBBaan8le6WfbZ5YoDEJ6DFD9DonlL1YRGTM70Y42mGK5MYR4WNb13jRRcm_qsPdeg13aFAPczIVo4xu9O35e3lPFgaXjGBzFhsVwEYdQzGCBD7TuqJKoaZScDIyEU97THSOa/s616/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2020.07.50.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="248" data-original-width="616" height="129" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5LjJfmEoqQTCTUg1poGq48GeFqhEEworCJMwkVbiQn6S-zevkMdjlBBaan8le6WfbZ5YoDEJ6DFD9DonlL1YRGTM70Y42mGK5MYR4WNb13jRRcm_qsPdeg13aFAPczIVo4xu9O35e3lPFgaXjGBzFhsVwEYdQzGCBD7TuqJKoaZScDIyEU97THSOa/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2020.07.50.png" width="320" /></a></div>
<br />
このURLは全体をメモしておきましょう。<br />
ここまで入力できたら保存(公開)します。<br />
<br />
<h3>
4. コンテンツ表示の確認</h3>
先ほどメモしたURLをアドレスバーに貼り付けて移動してみると、<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtbQIzC4YKrrytxdTHn3-aNK34bZ95UPRID5NZ5AV24_gcozYn9AwIsk3TsKSjrpABTVmBjXDsfH8MiZMblS4xGakux-Ztzj1YJXVT2NKm_kOuN5R3CMVTUI5HDVpaA3a0aUeLSLm8nfDciNlIBQPfmGc3b5vCCoXircCzsGlNcpJq4GEr3U_2_FVE/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2020.51.10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="868" data-original-width="1600" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtbQIzC4YKrrytxdTHn3-aNK34bZ95UPRID5NZ5AV24_gcozYn9AwIsk3TsKSjrpABTVmBjXDsfH8MiZMblS4xGakux-Ztzj1YJXVT2NKm_kOuN5R3CMVTUI5HDVpaA3a0aUeLSLm8nfDciNlIBQPfmGc3b5vCCoXircCzsGlNcpJq4GEr3U_2_FVE/w463-h251/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2020.51.10.png" width="463" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<br />
設定通り、画像を背景にして名前と説明を載せたページとしてコンテンツが表示されました!<br />
テンプレート言語を一切記述していないのにこのようにコンテンツをレンダーして表示することができるなんて、昔のバージョンから知っている者としては感慨深いものがありますね。<br />
<br />
今はアドレス直打ちで移動しましたが、従来のようにアセットパブリッシャーで集約表示した一覧をクリックしてコンテンツを全表示するときにも利用できます。その場合、アセットパブリッシャーの設定でアセットリンクの振る舞いを「コンテキストの参照」にしてください。「全内容の表示」にするとこのように<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLL2eegTP7FnLGA-68U241IF0XYlJbpyyJmQMIIrU-3MWZcLpD5UTiOMWsGjKinCDKLoA9sqUMlX7gzGNwLjWq3vIsNlVCSajPhagDpXi36Jnw6wmwNeA_6j27XqKjuQLeaTCRc7vjys2uAsV7_AC74YOdAKbiB8zuosJjpdBBzG2dTC11Hwkjnm1z/s1344/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2020.14.32.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1344" data-original-width="1264" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLL2eegTP7FnLGA-68U241IF0XYlJbpyyJmQMIIrU-3MWZcLpD5UTiOMWsGjKinCDKLoA9sqUMlX7gzGNwLjWq3vIsNlVCSajPhagDpXi36Jnw6wmwNeA_6j27XqKjuQLeaTCRc7vjys2uAsV7_AC74YOdAKbiB8zuosJjpdBBzG2dTC11Hwkjnm1z/w369-h392/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-30%2020.14.32.png" width="369" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<br />
Webコンテンツのテンプレートを使ってレンダーされたコンテンツが表示されます。今回はWebコンテンツテンプレートを作っていないので、項目が箇条書きで表示されています。<br />
<br />
従来のようにデフォルトアセットパブリッシャーを配置したページをWebコンテンツの表示ページに指定する機能も残っているので、そちらがお好みの場合は引き続き利用可能です。アップグレードも問題なさそうですね。<br />
<br />
<h3>
5. まとめ</h3>
表示ページテンプレートにコンテンツをマッピングして表示ページをつくる方法について説明しました。テンプレート言語なしでも自由度の高いページ作成が可能なので、対応しているエンティティを利用する場合はぜひ利用を検討してみてください。<br />
<br />
<h3>
ちなみに古いバージョンだと…</h3>
DXP 7.2の少し古いバージョン(GA1かな?)だと、表示ページテンプレートを使う部分がすべて非公開ページ扱いとなり、Guestで見ようとすると以下のようにログインを求められるという悲しいことになりました…</div><div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPYwtk5HVusXQ5QbciqB6jdqjC6huqfYjwaw2gY4ojHBMfs7Q8twWfWvyg-AofATOL7Q6BLVgbhNlaaZtZv3GvqEcBPeqrtGH12LIFwpVbP3R9TQQCxq6tzB4CEQtdynDwdccQAj4LYZCnCwqp328yAzGdBj2ak4MQe1aXSLjNHZIRa9rS_LU0IbHX/s1048/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2018.57.49.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="734" data-original-width="1048" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPYwtk5HVusXQ5QbciqB6jdqjC6huqfYjwaw2gY4ojHBMfs7Q8twWfWvyg-AofATOL7Q6BLVgbhNlaaZtZv3GvqEcBPeqrtGH12LIFwpVbP3R9TQQCxq6tzB4CEQtdynDwdccQAj4LYZCnCwqp328yAzGdBj2ak4MQe1aXSLjNHZIRa9rS_LU0IbHX/w360-h252/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-06-29%2018.57.49.png" width="360" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<br />
SP2を触る限り修正されていたので、安心してくださいね。</div>Tomomi Kawabehttp://www.blogger.com/profile/15294287020047889401noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-56846566331460563252020-07-15T09:04:00.001+09:002022-08-17T18:29:58.434+09:00Liferayで成功メッセージを画面上部に表示するこんにちは。おおたにです。<br />
<br />
今回は、ユーザフィードバックのメッセージ表示位置に関するTIPSを紹介します。なお、以下のサンプルスナップショットやコードはLiferay DXP 7.1でのものです。<br />
<br />
<h3>
成功メッセージとエラーメッセージ</h3>
<br />
Liferay上で何かしらの処理を実行した場合、ユーザフィードバックとしてメッセージが表示されます。例えば処理が成功した場合は、以下のような成功メッセージが表示され、<br /><div class="separator" style="clear: both; text-align: center;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGi11UJIAo2sDv2q30oYvkLEWNIjlTx7ASnk1AFnvNxqdKowfpl6MWHWgY7H-M6Eb1iB8roHKdZ2Go3YJlWwMBN3iCKhnVTXC5lbahRyP9HqB6DHUgY22AIJ_QXCpjG1Q3IfxYp6RoqggBH2BbIll3eXHdwW2naMDajBP5Hy-EdAJUM0IJ5tFuAyTe/s1028/image1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="478" data-original-width="1028" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGi11UJIAo2sDv2q30oYvkLEWNIjlTx7ASnk1AFnvNxqdKowfpl6MWHWgY7H-M6Eb1iB8roHKdZ2Go3YJlWwMBN3iCKhnVTXC5lbahRyP9HqB6DHUgY22AIJ_QXCpjG1Q3IfxYp6RoqggBH2BbIll3eXHdwW2naMDajBP5Hy-EdAJUM0IJ5tFuAyTe/w395-h184/image1.png" width="395" /></a></div><br /></div>
<br />
処理が失敗した場合は、以下のようにエラーメッセージが表示されます(併せて汎用エラーメッセージ「処理に失敗しました。」が画面左下に表示されることもあります)。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-4nAyV2KpgqXeihZvUTNnF3g0KSmPpYrHzLXbeu3Dsk6pQacVsKNBXAmlFh1ZYzQtj1o35P7jbn1Rh7cYc8ULUY17nt2NaE0ecOhkuMTudEJ0NJRm--cUVqU4-nBu8cNKs_MDjh5xOgnf_Gp8HdkysoSuqBLNyBqyoKVI5Qy_gGGZPOKAySSzKYOp/s1023/image2%20(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="392" data-original-width="1023" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-4nAyV2KpgqXeihZvUTNnF3g0KSmPpYrHzLXbeu3Dsk6pQacVsKNBXAmlFh1ZYzQtj1o35P7jbn1Rh7cYc8ULUY17nt2NaE0ecOhkuMTudEJ0NJRm--cUVqU4-nBu8cNKs_MDjh5xOgnf_Gp8HdkysoSuqBLNyBqyoKVI5Qy_gGGZPOKAySSzKYOp/w393-h151/image2%20(1).png" width="393" /></a></div>
<br />
画面左下の表示はトースト(toast)と呼ばれる自動的に消えるメッセージで、画面上部の表示は自動的に消えない画面埋め込み(embed)のメッセージです。通知の目的が処理の状況や成否を通知することだけなのか、それ以上の具体的なメッセージをユーザに伝えることなのかに応じて使い分けることが多いです。<br />
Liferayではこれらのメッセージの実装に<code><liferay-ui:success></code>や<code><liferay-ui:error></code>を使いますが、普通に実装すると前者がトースト、後者が埋め込みとなります。<br />
<br />
<h3>
成功メッセージを埋め込みで表示したい</h3>
<br />
メッセージの表示形式は<code>embed</code>属性でコントロールできます。例えば、成功メッセージを埋め込みで表示する場合はこのように指定します。<br />
<br />
<pre class="brush:xml"><liferay-ui:success key="success_message_key" message="msg.success" embed="<%=true %>" />
</pre>
<br />
成功メッセージの表示は以下のようになり、成功メッセージとエラーメッセージを同様のUIで提供するような要件に応えることができます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiTJsWQO2fYd0UIxn3RbiGC26I5CaB5DyEMs4lozUXeoDlu7qQc2XBe6INGmRy9YJaXsoAEYIpgatRE52_yHtcSXkA8DEEBFncA0UXpXFr3rIiZfogmXtA8IYptQj1Qv2RW3JiwEoxO04o8LdzmOfOiOw40dTg1V87iHXg7PZelQ2nLFBKOcZYVO76/s711/image3%20(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="256" data-original-width="711" height="149" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiTJsWQO2fYd0UIxn3RbiGC26I5CaB5DyEMs4lozUXeoDlu7qQc2XBe6INGmRy9YJaXsoAEYIpgatRE52_yHtcSXkA8DEEBFncA0UXpXFr3rIiZfogmXtA8IYptQj1Qv2RW3JiwEoxO04o8LdzmOfOiOw40dTg1V87iHXg7PZelQ2nLFBKOcZYVO76/w415-h149/image3%20(1).png" width="415" /></a></div>
<br />
この他にも<code><liferay-ui:success></code>と<code><liferay-ui:error></code>には表示をコントロールする属性がいくつか定義されていますので、<a href="https://docs.liferay.com/portal/7.1-latest/taglibs/util-taglib/liferay-ui/success.html" target="_blank">こちら</a>や<a href="https://docs.liferay.com/portal/7.1-latest/taglibs/util-taglib/liferay-ui/error.html" target="_blank">こちら</a>のドキュメントを参考に色々と試してみてください。Tasuku Otanihttp://www.blogger.com/profile/18132336091954266906noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-61243130663066148102020-07-07T10:23:00.001+09:002022-08-17T18:33:19.996+09:00Liferay 7をインストールしてみようこんにちは。おおたにです。<br />
<br />
今回はLiferay 7のインストール方法について紹介します。<br />
<br />
本ブログでもたびたび取り上げているLiferayは、オープンソースのデジタルエクスペリエンスプラットフォーム(DXP)製品です。従来はエンタープライズ向け情報ポータル(Enterprise Information Portal)と呼ばれていたジャンルですが、よりユーザ体験や顧客体験にフォーカスするために現在はDXPと呼ばれています。<br />
<br />
企業のインターネット向けサイトやイントラネット向けサイト、代理店/販売店ポータルなどに代表される組織/企業間、コミュニティポータルなどに代表されるユーザ同士など、様々な形での情報発信/情報共有の場を構築することに利用されています。さらにはバックエンドにあるシステムの情報や他のサービスを通して得られる情報を統合し、B2B/B2C、パブリック/プライベート問わず様々なWebサイト上で最適なユーザ体験を提供することができるプラットフォームです。<br />
<br />
エンタープライズ向けと銘打たれているのでインストールの敷居も高いのではないかと思われるかもしれませんが、そんなことはありません。もちろん実運用を考えると諸々の設定やチューニングを行う必要がありますが、とりあえずインストールして使ってみようという限りではとても簡単にセットアップすることができます。<br />
<br />
<h3>
CE(Community Edition)とDXP(Digital Experience Platform)</h3>
<br />
LiferayにはCE(Community Edition)とDXP(Digital Experience Platform)の2つのエディションがあります。<br />
<br />
<b>CE</b> : 無償利用できるけどLiferay社のサポートが受けられないバージョンです。記事執筆時点ではLiferay Portal 7.3.2 CE GA3が最新のバージョンです。<br />
<br />
<b>DXP</b> : 有償のサブスクリプションが必要だけどLiferay社のサポートを受けられるバージョンです。セキュリティ関連を含む修正パッチの提供が受けられる他、クラスタリングやAudit等の構成/運用面で助けとなる機能が提供されます。記事執筆時点ではLiferay DXP 7.2 SP2が最新のバージョンです。<br />
<br />
なお、DXPをご検討中の方やご質問/ご相談のある方は<a href="https://aegif.jp/liferay/contact.html" target="_blank">こちらのフォーム</a>から弊社までご連絡ください。<br />
<br />
<h3>
Javaのインストール</h3>
<br />
Liferayの動作にはJavaが必要です。CEは<a href="https://liferay.dev/blogs/-/blogs/liferay-portal-7-3-ce-ga3-release" target="_blank">こちら</a>、DXPは<a href="https://www.liferay.com/ja/compatibility-matrix" target="_blank">Compatibility Matrix</a>で必要なJavaのバージョンが確認できます。<br />
Liferay Portal 7.3 CEやLiferay DXP 7.2であればOracle JDK 8が必要です。<a href="https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html" target="_blank">こちら</a>からダウンロードしてインストールしてください。<br />
<br />
<h3>
Liferayのダウンロード</h3>
<br />
CEは<a href="https://www.liferay.com/downloads-community" target="_blank">Liferay Community Downloads</a>の「Liferay Portal」から、DXPは<a href="https://help.liferay.com/hc/ja" target="_blank">Liferay Help Center</a>からダウンロードできます。Bundled with Tomcat (tar.gz)もしくはBundled with Tomcat (7-Zip)を選択してダウンロードします。<br />
Apache Tomcatが同梱されて必要最低限の設定も行われているため、さくっと動かすにはこのパッケージがお勧めです。<br />
<br />
<h3>
Liferayのインストール</h3>
<br />
次に、先ほどダウンロードしたLiferayのファイルを展開します。<code>liferay-ce-portal-7.xxxx</code>もしくは<code>liferay-dxp-7.xxxx</code>というフォルダが作成され、その中に必要なファイルがコピーされます。なお、このフォルダは<code><LIFERAY_HOME></code>と呼ばれ、Liferayの設定や運用に際して重要なフォルダとなります。<br />
<br />
以上でLiferayのインストールは終わりです。簡単!<br />
<br />
なお、実運用を考えると別途データベースを用意したりJVMをチューニングしたりなどの設定が必要ですが、ひとまず動けばOKということであればデフォルトのままで十分です。<br />
<br />
<h3>
[DXPのみ] ライセンスファイルのコピー</h3>
<br />
DXPの場合はLiferay社から提供されるライセンスファイルを<code><LIFERAY_HOME>/deploy</code>フォルダにコピーします。Liferay起動時にライセンスファイルが読み込まれ、認証をパスして初めてLiferayが使えるようになります。<br />
<br />
<h3>
Liferayの起動と初期設定</h3>
<br />
では、早速Liferayを起動してみましょう。Liferayを起動するためには、以下のTomcat起動スクリプトを実行します。<br />
<br />
Windows : <code><LIFERAY_HOME>/tomcat-xxxx/bin/startup.bat</code><br />
Linux (or Mac OS X) : <code><LIFERAY_HOME>/tomcat-xxxx/bin/startup.sh</code><br />
<br />
Liferayが正常に起動すると、ブラウザが自動的に起動して<code>http://localhost:8080</code>にアクセスします。起動しない場合はブラウザを起動して先のURLにアクセスしてみてください。以下のような画面が表示されればOKです。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj025_3YwaKBxQu-wL7Oalck9McrjQZw539svjlI8_bdyf4waUfqiJBd-4Zz12Q8GOHh3Vozt-1pb8V05fG1mWlHBevCdp0-UJt215zMvy9my4Tr6JMo43C6KRPVJuGMVgHEwpmdg6h5jKDvAd5YK5WXRvhz7FatbADiNE0rxrxJ_zgF-WGtsM5mCAB/s1015/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="731" data-original-width="1015" height="289" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj025_3YwaKBxQu-wL7Oalck9McrjQZw539svjlI8_bdyf4waUfqiJBd-4Zz12Q8GOHh3Vozt-1pb8V05fG1mWlHBevCdp0-UJt215zMvy9my4Tr6JMo43C6KRPVJuGMVgHEwpmdg6h5jKDvAd5YK5WXRvhz7FatbADiNE0rxrxJ_zgF-WGtsM5mCAB/w402-h289/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB02.png" width="402" /></a></div>
<br />
これは初回起動時のみ表示される設定画面で、ポータルの名称やデフォルト言語、管理者ユーザの情報、データベース接続を設定することができます。デフォルトでは組込みDBのHypersonicが使われますが、お試し用途であればこのままでOKです。<br />
Email欄に管理者のメールアドレスを入力して「Finish Configuration」をクリックします。しばらく待つと設定が完了して利用規約が表示されるので、「I Agree」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijTFBEurS0KmBY09wCrLWw0LBf0uDiHFS_YBr2fiWe8-UtUg_Jl-Qxi589iw8X3ExaLPF_sVktXx0z9ZccXHATSxD7lyBDtWuKR29SbN9tZhaMXqZwxsrNp7CfZTGd_uCJrnR31x9uQ0OQwwe7_F2vipEZSQdbpw4Ih8qQNPMlRZzrwPqvnLRA7nIH/s1021/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="471" data-original-width="1021" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijTFBEurS0KmBY09wCrLWw0LBf0uDiHFS_YBr2fiWe8-UtUg_Jl-Qxi589iw8X3ExaLPF_sVktXx0z9ZccXHATSxD7lyBDtWuKR29SbN9tZhaMXqZwxsrNp7CfZTGd_uCJrnR31x9uQ0OQwwe7_F2vipEZSQdbpw4Ih8qQNPMlRZzrwPqvnLRA7nIH/w424-h196/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB03.png" width="424" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<br />
続いて管理者ユーザのパスワードを入力して「Save」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_LHVWRd_2JBwek6vCkKaJJB4HGJsIY-owKuXQkxIC4A17gCqnigudZ40F78oykEs7u-vo3Xd_VFofPIPdXhW8ggH0hCoXVRmaOmBavp1qSaWOW9Rgo2BkneswFFBbHUFJ1R3s4ZG0ISjVdjlA9NLULcDgNFBcuR2rq2RjV89B71lPVXTp0aGr6Bzw/s1027/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="523" data-original-width="1027" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_LHVWRd_2JBwek6vCkKaJJB4HGJsIY-owKuXQkxIC4A17gCqnigudZ40F78oykEs7u-vo3Xd_VFofPIPdXhW8ggH0hCoXVRmaOmBavp1qSaWOW9Rgo2BkneswFFBbHUFJ1R3s4ZG0ISjVdjlA9NLULcDgNFBcuR2rq2RjV89B71lPVXTp0aGr6Bzw/w384-h196/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB04.png" width="384" /></a></div>
<br />
最後にパスワードリマインダ(パスワードを忘れた時の秘密の質問)を入力して「Save」をクリックします。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNffkcg5blDMkXQ148uxiaJUGXrJzYl34CSSgVuhEN0NMJ4sAEAC0qqyEXupj0g9LcKOfB4wJjRbLkNvv3P5L78e26mmFZH9Gl4ayzuGqe0glHFuIHPnO5lvRjX-p8UCBhF9IWgPGz6PBRIxlFX-2qoPheCJPJ1OlAsnvJUmds5p5pwh0AdrtGFu3X/s1018/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="517" data-original-width="1018" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNffkcg5blDMkXQ148uxiaJUGXrJzYl34CSSgVuhEN0NMJ4sAEAC0qqyEXupj0g9LcKOfB4wJjRbLkNvv3P5L78e26mmFZH9Gl4ayzuGqe0glHFuIHPnO5lvRjX-p8UCBhF9IWgPGz6PBRIxlFX-2qoPheCJPJ1OlAsnvJUmds5p5pwh0AdrtGFu3X/w375-h191/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB05.png" width="375" /></a></div>
<br />
設定が完了すると、以下のランディングページが表示されます(上がLiferay DXP 7.2、下がLiferay Portal 7.3 CE)。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTPLgMBfANPbf4xZ4KWiKH6lbcfRs0bFyFlMyxInYIOI3Djz6AKT301Pal_EVig57hs97t6ac1vbw75ZDTYPhRuax1rHBmdFTStod3q5CH3cj7-KCSq5Xquu2hOJVgmZABMIp5A7QO3G7ysX6yvy_P9iUd_0w42Q7Ep2Q2PF1ZVzKWAHSCQzqJjBam/s1246/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="625" data-original-width="1246" height="189" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTPLgMBfANPbf4xZ4KWiKH6lbcfRs0bFyFlMyxInYIOI3Djz6AKT301Pal_EVig57hs97t6ac1vbw75ZDTYPhRuax1rHBmdFTStod3q5CH3cj7-KCSq5Xquu2hOJVgmZABMIp5A7QO3G7ysX6yvy_P9iUd_0w42Q7Ep2Q2PF1ZVzKWAHSCQzqJjBam/w375-h189/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB06.png" width="375" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEoDwVaSqTqj2z15jqnW10PqCk_sPIjhVoQR_k0z0yH9eS0SBoAr9I3oPp2ed2HiUHK0A3E2etcHh-wjgqWQl6ezqcAyHbw1zwZxNNE_NLN0vwN5ybILjUYewAlDa_PgrsGKEk6XvnKQe2kc0JQEXYObEP_6IExJmlsBftSEBy34DE3msaCdl5qRuc/s1253/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="569" data-original-width="1253" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEoDwVaSqTqj2z15jqnW10PqCk_sPIjhVoQR_k0z0yH9eS0SBoAr9I3oPp2ed2HiUHK0A3E2etcHh-wjgqWQl6ezqcAyHbw1zwZxNNE_NLN0vwN5ybILjUYewAlDa_PgrsGKEk6XvnKQe2kc0JQEXYObEP_6IExJmlsBftSEBy34DE3msaCdl5qRuc/w378-h171/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB07.png" width="378" /></a></div>
<br />
以上でLiferayが使える状態になったかと思います。みなさまも是非Liferayをインストールして実際に触ってみてください!<br />
<br />
<h3>
トラブルシューティング</h3>
<br />
Liferayが正常に起動しない場合は、以下のログの内容を確認してみてください。<br />
<br />
<code><LIFERAY_HOME>/logs/liferay.xxxx-xx-xx.log</code><br />
<code><LIFERAY_HOME>/tomcat-xxxx/logs/catalina.xxxx-xx-xx.log</code><br />
<br />
また、LiferayをインストールしたPCのメモリも確認してください。Liferayはデフォルトでヒープに2.5GB、MetaSpaceに768MB使う設定となっています。PCのメモリは4GBだと厳しいかもしれません。少なくとも6GBは欲しいところです。Tasuku Otanihttp://www.blogger.com/profile/18132336091954266906noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-77225018902950473182020-06-29T09:56:00.001+09:002022-08-17T18:36:50.136+09:00Liferayテーブルを見てみよう〜ユーザ情報編<div class="separator" style="clear: both; text-align: left;">
こんにちはナクラです。</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
暑くなったり、少しすごしやすくなったりと気候がころころ変わるこの頃ですが、</div>
<div class="separator" style="clear: both; text-align: left;">
徐々に真夏に近づいているのを実感する毎日ですね。</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
さて、今日はLiferayのデータベースのテーブルについて書きたいと思います。</div>
<div class="separator" style="clear: both; text-align: left;">
Liferayでは253ものデータベーステーブルが用意されています。</div>
<div class="separator" style="clear: both; text-align: left;">
なので、全体にたいしてER図を描くのはあまり現実的ではないのです。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
また、ユーザインタフェース上の設定項目が実際にはどのテーブルに登録されているのかをまとまって見られる資料もなかなか良いものがないので、</div>
<div class="separator" style="clear: both;">
ここで、個別に確認していってみようと思います。</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both;">
今回はユーザの設定画面について確認していくことにしましょう。</div>
<div class="separator" style="clear: both;">
ユーザの情報はコントロールパネルの</div>
<div class="separator" style="clear: both;">
[ユーザ] > [ユーザと組織] の項目から確認できます。</div>
<div class="separator" style="clear: both;">
個別のユーザの情報を見ると</div>
<div class="separator" style="clear: both;">
次の図のようになっています。</div>
<div class="separator" style="clear: both;"><br /></div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj81njLXh8IAMD2aAJstvxaS1AXSfdjaaXYpQpmOwBtjbYTD6zJCIurHMUE09f_NHVIYBFQCvM4ltpXoXgxt4g1D5PPuNo0fr9NrdrLsVAKnZkLUYR_0gEkzrXY3YJSw_B1jdIi3AFqhVOePlVeI9dBtIgipIKci1q_f56FBsNVW8fxzxdyoT4sD2qS/s1600/blogimage02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="808" height="608" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj81njLXh8IAMD2aAJstvxaS1AXSfdjaaXYpQpmOwBtjbYTD6zJCIurHMUE09f_NHVIYBFQCvM4ltpXoXgxt4g1D5PPuNo0fr9NrdrLsVAKnZkLUYR_0gEkzrXY3YJSw_B1jdIi3AFqhVOePlVeI9dBtIgipIKci1q_f56FBsNVW8fxzxdyoT4sD2qS/w308-h608/blogimage02.png" width="308" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
ユーザ情報の画面では、このように</div>
<div class="separator" style="clear: both;">
・共通タブ</div>
<div class="separator" style="clear: both;">
・連絡先タブ</div>
<div class="separator" style="clear: both;">
・表示設定タブ</div>
<div class="separator" style="clear: both;">
の3つのタブがありますので、一つづつ見ていきましょう。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
<br /></div>
<h3 style="clear: both;">
共通タブ</h3>
<div class="separator" style="clear: both;">
まず共通タブから見ていきます。</div>
<div class="separator" style="clear: both;">
共通タブの中にもいくつかの項目があります。</div>
<div class="separator" style="clear: both;">
</div>
<ul>
<li>情報</li>
<li>組織</li>
<li>メンバーシップ</li>
<li>ロール</li>
<li>プロフィールとダッシュボード</li>
<li>パスワード</li>
<li>アプリ</li>
</ul>
<br />
<div>
それぞれを見ていきましょう。</div>
<div>
<br /></div>
<div>
<div>
【情報】</div>
<div>
この画面の設定項目の大半は</div>
<div>
ユーザ情報のメインのデータである<b>User_</b>テーブルに含まれている情報です。</div>
</div>
<div>
(<b>User_</b>テーブルは最後に"_"がついているのに注意してくだあい。</div>
<div>
よくつけ忘れてテーブルがない!と慌ててしまうことがあります。)</div>
<div>
<br /></div>
<div class="separator" style="clear: both;">
ただし、</div>
<div class="separator" style="clear: both;">
性別、生年月日、サフィックスについては</div>
<div class="separator" style="clear: both;">
<b>Contact_</b>テーブルに含まれる情報になっています。(これも"_"がついています)</div>
<div class="separator" style="clear: both;">
また、</div>
<div class="separator" style="clear: both;">
詳細情報のセクションについては各設定項目でテーブルが違っています。</div>
<div class="separator" style="clear: both;">
カテゴリについては</div>
<div class="separator" style="clear: both;">
<b>AssetEntryAssetCategoryRel</b>テーブル</div>
<blockquote class="tr_bq" style="clear: both;">
<span face="Trebuchet MS, sans-serif">+--------------------------------------+-------------+------+-------+-----------+-------+<br />| Field | Type | Null | Key | Default | Extra |<br />+--------------------------------------+-------------+------+-------+-----------+-------+<br />| mvccVersion | bigint(20) | NO | | 0 | |<br />| assetEntryAssetCategoryRelId | bigint(20) | NO | PRI | NULL | |<br />| assetEntryId | bigint(20) | YES | MUL | NULL | |<br />| assetCategoryId | bigint(20) | YES | MUL | NULL | |<br />| priority | int(11) | YES | | NULL | |<br />+-------------------------------------+--------------+------+--------+----------+-------+</span></blockquote>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
タブについては</div>
<div class="separator" style="clear: both;">
<b>AssetEntries_AssetTags</b>テーブル</div>
<blockquote class="tr_bq" style="clear: both;">
<span face="Trebuchet MS, sans-serif">+---------------+------------+-------+-------+-----------+-------+<br />| Field | Type | Null | Key | Default | Extra |<br />+---------------+------------+-------+-------+-----------+-------+<br />| companyId | bigint(20) | NO | MUL | NULL | |<br />| entryId | bigint(20) | NO | PRI | NULL | |<br />| tagId | bigint(20) | NO | PRI | NULL | |<br />+---------------+------------+-------+-------+-----------+-------+</span></blockquote>
<div class="separator" style="clear: both;">
に情報が登録されます。</div>
<div class="separator" style="clear: both;">
ユーザのuserIdの値が</div>
<div class="separator" style="clear: both;">
<b>AssetEntryAssetCategoryRel</b>ではassetEntryIdのカラムに</div>
<div class="separator" style="clear: both;">
<b>AssetEntries_AssetTags</b>ではentryIdのカラムに</div>
<div class="separator" style="clear: both;">
設定されます。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
カルタムフィールドについては<b><i>Expando</i></b>という機構を利用していますが、</div>
<div class="separator" style="clear: both;">
これについては別の機会にお話したいと思います。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
【組織】</div>
<div class="separator" style="clear: both;">
ユーザが所属する組織の情報については</div>
<div class="separator" style="clear: both;">
<b>Users_Orgs</b>テーブル</div>
<blockquote class="tr_bq" style="clear: both;">
<span face="Trebuchet MS, sans-serif">+-------------------+-------------+-------+------+-----------+-------+<br />| Field | Type | Null | Key | Default | Extra |<br />+-------------------+-------------+-------+------+-----------+-------+<br />| companyId | bigint(20) | NO | MUL | NULL | |<br />| organizationId | bigint(20) | NO | PRI | NULL | |<br />| userId | bigint(20) | NO | PRI | NULL | |<br />+--------------------+------------+------+--------+----------+-------+</span></blockquote>
<div class="separator" style="clear: both;">
に設定されています。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
【メンバーシップ】</div>
<div class="separator" style="clear: both;">
ユーザが所属するサイトの情報については</div>
<div class="separator" style="clear: both;">
<b>Users_Groups</b>テーブル</div>
<blockquote class="tr_bq" style="clear: both;">
<span face="Trebuchet MS, sans-serif">+---------------+--------------+------+-------+-----------+-------+<br />| Field | Type | Null | Key | Default | Extra |<br />+---------------+--------------+------+-------+-----------+-------+<br />| companyId | bigint(20) | NO | MUL | NULL | |<br />| groupId | bigint(20) | NO | PRI | NULL | |<br />| userId | bigint(20) | NO | PRI | NULL | |<br />+---------------+--------------+------+-------+-----------+-------+</span></blockquote>
<div class="separator" style="clear: both;">
に設定されています。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
ユーザが所属するユーザグループの情報については</div>
<div class="separator" style="clear: both;">
<b>Users_UserGroups</b>テーブル</div>
<blockquote class="tr_bq" style="clear: both;">
<span face="Trebuchet MS, sans-serif">+-----------------+-------------+-------+-----+-----------+--------+<br />| Field | Type | Null | Key | Default | Extra |<br />+-----------------+-------------+-------+------+----------+--------+<br />| companyId | bigint(20) | NO | MUL | NULL | |<br />| userId | bigint(20) | NO | PRI | NULL | |<br />| userGroupId | bigint(20) | NO | PRI | NULL | |<br />+-----------------+-------------+-------+------+----------+--------+</span></blockquote>
<div class="separator" style="clear: both;">
に設定されています。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
【ロール】</div>
<div class="separator" style="clear: both;">
ユーザが割り当てられているロールの情報については</div>
<div class="separator" style="clear: both;">
<b>Users_Roles</b>テーブル</div>
<blockquote class="tr_bq" style="clear: both;">
<span face="Trebuchet MS, sans-serif">+---------------+-------------+-------+-------+-----------+--------+</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| Field | Type | Null | Key | Default | Extra |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">+---------------+-------------+-------+-------+-----------+--------+</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| companyId | bigint(20) | NO | MUL | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| roleId | bigint(20) | NO | PRI | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| userId | bigint(20) | NO | PRI | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">+---------------+-------------+-------+-------+-----------+--------+</span></blockquote>
<div class="separator" style="clear: both;">
に設定されています。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
【プロフィールとダッシュボード】</div>
<div class="separator" style="clear: both;">
この項目からはユーザ個人の公開サイト(プロフィール)、非公開サイト(ダッシュボード)へ移動できます。</div>
<div class="separator" style="clear: both;">
ユーザの個人サイトの情報は</div>
<div class="separator" style="clear: both;">
<b>Group_</b>テーブル</div>
<blockquote class="tr_bq" style="clear: both;">
<span face="Trebuchet MS, sans-serif">+----------------------------------+-----------------+------+---------+-----------+-------+</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| Field | Type | Null | Key | Default | Extra |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">+----------------------------------+-----------------+------+---------+-----------+-------+</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| mvccVersion | bigint(20) | NO | | 0 | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| uuid_ | varchar(75) | YES | MUL | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| groupId | bigint(20) | NO | PRI | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| companyId | bigint(20) | YES | MUL | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| creatorUserId | bigint(20) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| classNameId | bigint(20) | YES | MUL | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| classPK | bigint(20) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| parentGroupId | bigint(20) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| liveGroupId | bigint(20) | YES | MUL | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| treePath | longtext | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| groupKey | varchar(150) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| name | longtext | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| description | longtext | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| type_ | int(11) | YES | MUL | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| typeSettings | longtext | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| manualMembership | tinyint(4) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| membershipRestriction | int(11) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| friendlyURL | varchar(255) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| site | tinyint(4) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| remoteStagingGroupCount | int(11) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| inheritContent | tinyint(4) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| active_ | tinyint(4) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">+----------------------------------+------------------+-------+-------+------------+-------+</span></blockquote>
<div class="separator" style="clear: both;">
に設定されています。</div>
<div class="separator" style="clear: both;">
このテーブルのClassPKカラムの値にユーザのuserIdと同じ値が設定されているものがユーザ個人のサイトになります。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
【パスワード】</div>
<div class="separator" style="clear: both;">
パスワードについては</div>
<div class="separator" style="clear: both;">
<b>User_</b>テーブルのpassword_カラムに値が登録されています。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
【アプリ】</div>
<div class="separator" style="clear: both;">
デフォルトでは設定されていません。</div>
<div class="separator" style="clear: both;">
<br /></div>
<h3 style="clear: both;">
連絡先タブ</h3>
<div class="separator" style="clear: both;">
次に連絡先タブについてみていきましょう。</div>
<div class="separator" style="clear: both;">
連絡先タブには</div>
<div class="separator" style="clear: both;">
</div>
<ul>
<li>住所</li>
<li>連絡先情報</li>
</ul>
<br />
<div class="separator" style="clear: both;">
の2つの項目があります。</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq1mTJ6BTm10jwNkCP9e97y0ZU5y76Cgi3ytxOQktQf5OVeFRFlx69i7RcD5Uhf1JHZvAMJUNY9aKVQJEX0IkRVd2NJO7sryUSeG5nSXU9f857fHHkxBxXFCubB60URPQZvpdCHPupA-m_4jaz2aJUmGeaLbj1l2CTOXY722oeNlqRYdVeSX0sUqlX/s1492/blogimage03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="990" data-original-width="1492" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq1mTJ6BTm10jwNkCP9e97y0ZU5y76Cgi3ytxOQktQf5OVeFRFlx69i7RcD5Uhf1JHZvAMJUNY9aKVQJEX0IkRVd2NJO7sryUSeG5nSXU9f857fHHkxBxXFCubB60URPQZvpdCHPupA-m_4jaz2aJUmGeaLbj1l2CTOXY722oeNlqRYdVeSX0sUqlX/w402-h266/blogimage03.png" width="402" /></a></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
【住所】</div>
<div class="separator" style="clear: both;">
ユーザの住所情報については</div>
<div class="separator" style="clear: both;">
<b>Address</b>テーブル</div>
<div class="separator" style="clear: both;">
に登録されます。</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
【連絡先情報】</div>
<div class="separator" style="clear: both;">
ユーザの連絡先情報については、いろいろな項目があります。</div>
<div class="separator" style="clear: both;">
各々の設定については以下のようになっています。</div>
<div class="separator" style="clear: both;">
</div>
<ul>
<li>電話番号 :Phoneテーブル</li>
<li>追加メールアドレス :EmailAddressテーブル</li>
<li>Webサイト :Websiteテーブル</li>
<li>Jabber :Contact_テーブルのjabberSnカラム</li>
<li>Skype :Contact_テーブルのskypeSnカラム</li>
<li>SMS :Contact_テーブルのsmsSnカラム</li>
<li>Facebook :Contact_テーブルのfacebookSnカラム</li>
<li>Twitter :Contact_テーブルのtwitterSnカラム</li>
<li>OPEN ID :User_テーブルのopenIdカラム</li>
</ul>
<br />
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h3>
表示タブ</h3>
最後の表示設定タブについてみていきましょう。<br />
表示設定タブには<br />
<br />
<ul>
<li>通知設定</li>
<li>表示設定</li>
</ul>
<br />
の2つの項目があります。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJK8VdkePeyh-LuFZ1BMBE2DncPdJ2IMK25Fx_kYMPG-az5LT-tcVmuVCyjO-bacytmSCFSYhMCUlWINKmGePKqsm4LuWXUHkkZrHRhYqVclihMYtXELDk06RJ0Q0rr8an4x6ioAdIrE7MamX40wxU4JT-kUdJNmFv89a6O7-jYc-st2iO4EdfjHgf/s1492/blogImage04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1054" data-original-width="1492" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJK8VdkePeyh-LuFZ1BMBE2DncPdJ2IMK25Fx_kYMPG-az5LT-tcVmuVCyjO-bacytmSCFSYhMCUlWINKmGePKqsm4LuWXUHkkZrHRhYqVclihMYtXELDk06RJ0Q0rr8an4x6ioAdIrE7MamX40wxU4JT-kUdJNmFv89a6O7-jYc-st2iO4EdfjHgf/w402-h284/blogImage04.png" width="402" /></a></div>
<br />
【通知設定】<br />
ユーザの通知設定情報については<br />
<b>AnnouncementsDelivery</b>テーブル<br />
<blockquote class="tr_bq">
<span face="Trebuchet MS, sans-serif">+----------------+---------------+-------+--------+----------+--------+</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| Field | Type | Null | Key | Default | Extra |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">+----------------+---------------+-------+--------+----------+--------+</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| deliveryId | bigint(20) | NO | PRI | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| companyId | bigint(20) | YES | MUL | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| userId | bigint(20) | YES | MUL | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| type_ | varchar(75) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| email | tinyint(4) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| sms | tinyint(4) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">| website | tinyint(4) | YES | | NULL | |</span><br style="font-family: "Trebuchet MS", sans-serif;" /><span face="Trebuchet MS, sans-serif">+----------------+---------------+-------+--------+---------+---------+</span></blockquote>
に設定されています。<br />
表示設定の項目で<br />
共通は"general"<br />
ニュースは"news",<br />
テストポートレットは"test"<br />
がtype_に設定されます。<br />
<br />
【表示設定】<br />
標準時については<b>User_</b>テーブルのtimezoneIdカラム<br />
あいさつ文については<b>User_</b>テーブルのgreetingカラム<br />
に設定されています。<br />
<br />
以上で、ユーザ情報の設定項目に対応するデータベースのテーブル情報について<br />
確認できました。<br />
ユーザに関連する情報だけでも、さまざまなテーブルが利用されていることがわかりましたね。<br />
Liferayではデータの追加・削除はデータベースを直接操作するのが推奨されていない理由が体感していただけたのではないでしょうか。<br />
<br />
それでは、次回はまた別の設定項目についてみていきたいと思います。<br />
<br />
<br />Alkanhttp://www.blogger.com/profile/13988465687923901704noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-10406313470156583172020-06-22T15:10:00.000+09:002022-08-17T18:40:49.172+09:00Liferayでアクセス解析ツールを設定してみようこんにちは。大谷です。<br />
<br />
Webサイトの運用にあたっては、どのページがよく見られているか、流入や離脱はどのようになっているのかなどのアクセス解析を通じて、ユーザー行動や成果を可視化し、Webサイトの改善につなげていきたいですよね。一般的にはGoogle Analyticsをはじめとするアクセス解析ツールが用いられますが、Liferayで作成したWebサイトについてもこれらのアクセス解析ツールを利用することができます。<br />
<br />
そこで今回は、Liferayで構築したサイトへのアクセス解析ツールの設定方法を紹介したいと思います。大きく3つの方法があるので、それぞれについて説明します。<br />
<br />
<h3>
1. Google AnalyticsのトラッキングIDを指定する</h3>
<br />
Liferayは、Google AnalyticsのトラッキングIDを指定するだけでトラッキングコードを埋め込むことができます。設定方法は以下のとおり、とても簡単です!<br />
<br />
1. <a href="https://support.google.com/analytics/answer/1008015?hl=ja" target="_blank">こちらのドキュメント</a>を参考にしてGoogle Analyticsをセットアップし、トラッキングIDを入手する。<br />
2. Liferayにログインしてアクセス解析対象のサイトに移動し、「設定」->「サイト設定」->「詳細設定」タブを開く。<br />
3. 「Google アナリティクスID」に先ほど入手したトラッキングIDを入力して「保存」をクリックする。<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivgFHFaLvyDlnhBbRKkR75Fv89d12QVnPoGRZEnlkKYAqgRGaJkoguJxZFobgz1kwJhevyZ-5rVww7fAW-teVJRO_ApDn-p100jVKmHbQljPxJ6h3QdMeh9i1B_KfV6iFdpnpBFjqMcs3677PySsA9k1FrddyJtzirXLFQ7Uz1dNX27qM6B4AHvqk_/s834/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="815" data-original-width="834" height="359" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivgFHFaLvyDlnhBbRKkR75Fv89d12QVnPoGRZEnlkKYAqgRGaJkoguJxZFobgz1kwJhevyZ-5rVww7fAW-teVJRO_ApDn-p100jVKmHbQljPxJ6h3QdMeh9i1B_KfV6iFdpnpBFjqMcs3677PySsA9k1FrddyJtzirXLFQ7Uz1dNX27qM6B4AHvqk_/w367-h359/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB01.png" width="367" /></a></div>
<br />
これでトラッキングコード埋め込み完了です。Google Analyticsでアクセス解析できるようになります。以下、2点ほど注意点があります。<br />
<br />
<ul>
<li>設定はサイト毎に行う必要があります。多数のサイトをアクセス解析対象とする場合は3.の方法を検討した方がよいかもしれません。</li>
<li>埋め込まれるタグはGoogleアナリティクスタグ(analytics.jsスニペット)です。グローバルサイトタグ(gtag.jsスニペット)を埋め込みたい場合は2.の方法を検討してください。</li>
</ul>
<br />
<h3>
2. アクセス解析ツールのトラッキングコード(タグ)を埋め込む</h3>
<br />
また、Liferayでは指定したアクセス解析用トラッキングコードをそのまま埋め込むこともできます。例えば、Matomo(旧Piwik)やAdobe AnalyticsなどGoogle Analytics以外のアクセス解析ツールを利用したり、Google Analyticsでもグローバルサイトタグを埋め込みたい場合はこの方法が便利です。<br />
<br />
1. 利用するアクセス解析ツールをセットアップし、トラッキングコードを入手する。<br />
2. Liferayに管理者でログインし、「コントロールパネル」->「設定」->「インスタンス設定」->「その他」タブを開く。<br />
3. 「分析」欄にアクセス解析ツールの名前を追記して「保存」をクリックする(名前は区別がつけばよいだけなので適当でOK。以下の例では「gtag.js」を追加)。<div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC8mR5mU1tb_hVfgL07btcqdMdj4-NDT3ZdvwN2vyIe9re4crsyOtFZEIPMtaQ4h7UqEYuLipNp2ghiHhoPAtZnqZQ5L7HVwT5YG8dbugaNn23GbgcwOG28mmGe1tTjo7a2DscQ61sGFdC8zIZWhVgn-8DUTdURkMaTy3sJqz74GTy-iN-IQWRgWsZ/s1187/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB03%20(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="638" data-original-width="1187" height="208" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC8mR5mU1tb_hVfgL07btcqdMdj4-NDT3ZdvwN2vyIe9re4crsyOtFZEIPMtaQ4h7UqEYuLipNp2ghiHhoPAtZnqZQ5L7HVwT5YG8dbugaNn23GbgcwOG28mmGe1tTjo7a2DscQ61sGFdC8zIZWhVgn-8DUTdURkMaTy3sJqz74GTy-iN-IQWRgWsZ/w387-h208/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB03%20(1).png" width="387" /></a></div>
<br />
4. アクセス解析対象のサイトに移動し、「設定」->「サイト設定」->「詳細設定」タブを開く。<br />
5. 先ほど追加した項目にトラッキングコードを入力して「保存」をクリックする。</div><div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVDDlNrkyGonKpXNzIG3D_4EoCgd-oBSbphPzj7HVkMpZgcLxQDKJjgTRRCAK8Fwd4eUPfDYt_dcAoXe9jeZU1vVglEhA13NhD4yd3nxDDvnsMvDnKJhPgShEHRsgqLmU59FGiTv3yDEQLLyheZqmiWReLpKpPUSjDDxRTRGdni9YfoDUQMmd33xpa/s819/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB02%20(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="741" data-original-width="819" height="331" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVDDlNrkyGonKpXNzIG3D_4EoCgd-oBSbphPzj7HVkMpZgcLxQDKJjgTRRCAK8Fwd4eUPfDYt_dcAoXe9jeZU1vVglEhA13NhD4yd3nxDDvnsMvDnKJhPgShEHRsgqLmU59FGiTv3yDEQLLyheZqmiWReLpKpPUSjDDxRTRGdni9YfoDUQMmd33xpa/w365-h331/%E3%82%AF%E3%83%AA%E3%83%83%E3%83%95%E3%82%9A%E3%83%9B%E3%82%99%E3%83%BC%E3%83%88%E3%82%99%E4%B8%80%E6%99%82%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB02%20(1).png" width="365" /></a></div>
<br />
これでトラッキングコードが埋め込まれます。1.の方法と同様、サイト毎に設定を行う必要があります。<br />
<br />
<h3>
3. カスタムテーマにトラッキングコード(タグ)を埋め込む</h3>
<br />
多数のサイトに一括でトラッキングコードを埋め込みたい場合は、カスタムテーマにトラッキングコードを記述し、カスタムテーマを適用した全てのサイトにトラッキングコードを埋め込むという方法もあります。<br />
他にも埋め込むべきタグがある場合や、タグ埋め込み先を詳細に管理したい場合などは、タグマネージャを利用する方がよいかもしれません。タグマネージャで埋め込むタグや配信先を管理するイメージです。具体的な方法は <a href="http://labo-blog.aegif.jp/2019/04/liferay.html" target="_blank">Liferayのサイトにタグを埋め込む</a> の「全てのページにタグを埋め込む」で紹介していますのでご参照ください。<br />
<br />
<br />
今回の記事は以上になります。アクセス解析ツールには無償利用可能なものもありますので、是非試してみてください。</div>Tasuku Otanihttp://www.blogger.com/profile/18132336091954266906noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-12809960677104678642020-05-29T12:05:00.002+09:002022-08-17T18:44:48.848+09:00ResourcePermissionの考察 (3)<a href="http://labo-blog.aegif.jp/2020/05/resourcepermission-2.html">前回</a>、Liferayのリソース権限のDBレコードについて考察しました。今回は権限チェックの実行について考察したいと思います。<br />
<br />
Liferayは開発者が直接に<span style="background-color: #fff2cc;">ResourcePermission</span>を利用しないように設計されています。開発者フォーラムを見ていると<a href="https://liferay.dev/forums/-/message_boards/message/15726251">it is inadvisable to manipulate the Liferay database directly</a>、<a href="https://liferay.dev/forums/-/message_boards/message/58472726">do not ever change it or write to the database</a>(Liferayデータベースを直接操作することは推奨されていません。なので、直接変更したり、データベースに書き込んだりしないでください。)<br />
のようなコメントがしばしばあります。そのため、Liferayはユーザ権限操作機能を提供しています。では、今回は権限操作機能中に一番基本の<span style="background-color: #fff2cc;">PermissionChecker</span>から考察しましょう。<br />
<div>
<br /></div>
<h4>
PermissionCheckerのメソッド</h4>
<div>
<div>
Liferayでは、ユーザごとに<span style="background-color: #fff2cc;">PermissionChecker</span>のインスタンスを持っています。<span style="background-color: #fff2cc;">PermissionChecker</span>は<span style="background-color: #fff2cc;">ResourceLocalService</span>を介して<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルレコードを確認する形でユーザの権限をチェックしてるため、権限チェックのメソッド<span style="background-color: #fff2cc;">hasPermission()</span>の<a href="https://docs.liferay.com/ce/portal/7.1-latest/javadocs/portal-kernel/com/liferay/portal/kernel/security/permission/PermissionChecker.html">メソッドシグネーチャ</a>は<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルの要素になります。<br />
<pre class="brush:java">boolean hasPermission(group, name, primKey, actionId);</pre>
</div>
<div>
<ul>
<li>Liferayの<span style="background-color: #fff2cc;">companyId</span>は<span style="background-color: #fff2cc;">group</span>から取得できるため、<span style="background-color: #fff2cc;">PermissionChecker</span>では<span style="background-color: #fff2cc;">companyId</span>に代わりに<span style="background-color: #fff2cc;">group</span>をパラメータとして利用している</li>
<li>ユーザロールは<span style="background-color: #fff2cc;">PermissionChecker</span>のプロパティーのためメソッドに含まれていない</li>
</ul>
</div>
</div>
まとめると、以下の情報を<span style="background-color: #fff2cc;">PermissionCheckerに</span>提供すれば、Liferayはユーザの権限を判断することができます。<br />
<ul>
<li>リソースのグループID</li>
<li>リソース名</li>
<li>リソースのPrimeKey</li>
<li>アクションID</li>
</ul>
では、リソース毎に<span style="background-color: #fff2cc;">PermissionChecker</span>提供する情報を考察しましょう。<br />
<br />
<h4>
Liferayにおいての権限チェック</h4>
<div>
あるユーザが、あるリソースに対する操作の権限をチェックする際の手順を考察しましょう。<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルのレコードはロール毎に記録されているため、権限チェックの際、ユーザのロールを全部取得し、<span style="background-color: #fff2cc;">PermissionChecker</span>において以下の判断を行うことが必要です。</div>
<div>
<div>
<span style="font-size: x-small;">※ 共通パラメータ<span style="background-color: #fff2cc;">actionId</span>を除外し、<span style="background-color: #fff2cc;">roleId</span>は<span style="background-color: #fff2cc;">PermissionChecker</span>が読み出せるため除外する</span></div>
</div>
<table>
<thead>
<tr>
<th>リソース種別</th>
<th>scope</th>
<th>必要パラメータ</th>
<th>チェック内容</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="4">ポートレット</td>
<td>1</td>
<td>portletId<br />
companyId</td>
<td><span style="background-color: #fff2cc;">companyId</span>のLiferayインスタンス中<br />
<span style="background-color: #fff2cc;">portletId</span>で特定されるポートレットに対する操作権限<br />
<span style="background-color: #fff2cc;">primKey=companyId</span></td>
</tr>
<tr>
<td>2</td>
<td>portletId<br />
groupId</td>
<td><span style="background-color: #fff2cc;">groupId</span>のサイト中<br />
<span style="background-color: #fff2cc;">portletId</span>で特定されるポートレットに対する操作権限<br />
<span style="background-color: #fff2cc;">primKey=groupId</span></td>
</tr>
<tr>
<td>3</td>
<td>portletId</td>
<td>サイトロールが割り当てられる際のみ<br />
<span style="background-color: #fff2cc;">portletId</span>で特定されるポートレットに対する操作権限<br />
<span style="background-color: #fff2cc;">primKey=0</span></td>
</tr>
<tr>
<td>4</td>
<td>portletId<br />
layoutId</td>
<td><span style="background-color: #fff2cc;">primKey=layoutId + _LAYOUT_ + portletId</span><br />
で特定するポートレットに対する操作権限</td>
</tr>
<tr>
<td rowspan="4">インスタンス化<br />
できない仮想<br />
モデル</td>
<td>1</td>
<td>モデル名<br />
companyId</td>
<td><span style="background-color: #fff2cc;">companyId</span>のLiferayインスタンス中<br />
モデル名で特定されるモデルに対する操作権限<br />
<span style="background-color: #fff2cc;">primKey=companyId</span></td>
</tr>
<tr>
<td>2</td>
<td>モデル名<br />
groupId</td>
<td><span style="background-color: #fff2cc;">groupId</span>のサイト中<br />
モデル名で特定されるモデルに対する操作権限<br />
primKey=<span style="background-color: #fff2cc;">groupId</span></td>
</tr>
<tr>
<td>3</td>
<td>モデル名</td>
<td>サイトロールが割り当てられる際のみ<br />
モデル名で特定されるモデルに対する操作権限<br />
<span style="background-color: #fff2cc;">primKey=0</span></td>
</tr>
<tr>
<td>4</td>
<td>-</td>
<td>仮想モデルはインスタンスを持っていない</td>
</tr>
<tr>
<td rowspan="4">インスタンス化<br />
可能なモデル</td>
<td>1</td>
<td>モデル名<br />
companyId</td>
<td>当該ロールはポータル範囲の操作権限を持つこと<br />
<span style="background-color: #fff2cc;">primKey=companyId</span></td>
</tr>
<tr>
<td>2</td>
<td>モデル名<br />
groupId</td>
<td><span style="background-color: #fff2cc;">groupId</span>のサイト中<br />
モデル名で特定されるモデルに対する操作権限<br />
<span style="background-color: #fff2cc;">primKey=groupId</span></td>
</tr>
<tr>
<td>3</td>
<td>モデル名</td>
<td>サイトロールが割り当てられる際のみ<br />
モデル名で特定されるモデルに対する操作権限<br />
<span style="background-color: #fff2cc;">primKey=0</span></td>
</tr>
<tr>
<td>4</td>
<td>モデル名<br />
primaryKey</td>
<td><span style="background-color: #fff2cc;">primaryKey</span>で特定されるモデルリソースに対する操作権限</td>
</tr>
</tbody>
</table>
Liferayでは、<span style="background-color: #fff2cc;">companyId</span>は<span style="background-color: #fff2cc;">group</span>、<span style="background-color: #fff2cc;">layout</span>などエンティティーから取得できるため、権限チェックが必要なメソッドは以下となります。<br />
<div>
<br /></div>
<table>
<thead>
<tr>
<th>リソース種別</th>
<th>scope</th>
<th>権限チェックメソッド</th>
<th>Liferayのインターフェース</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="4">ポートレット</td>
<td>1</td>
<td rowspan="3">check(permissionChecker, group, portlet, action)<br />
<span style="background-color: #fff2cc;">3</span>の場合、<span style="background-color: #fff2cc;">groupId=0</span></td>
<td rowspan="4"><a href="https://docs.liferay.com/ce/portal/7.1-latest/javadocs/portal-kernel/com/liferay/portal/kernel/service/permission/PortletPermission.html">PortletPermission</a></td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>check(permissionChecker, group, layout, portletId, actionId)</td>
</tr>
<tr>
<td rowspan="4">インスタンス化<br />
できない仮想<br />
モデル</td>
<td>1</td>
<td rowspan="3">check(permisisonChecker, group, name, action)</td>
<td rowspan="3"><a href="https://docs.liferay.com/ce/portal/7.1-latest/javadocs/portal-kernel/com/liferay/portal/kernel/security/permission/resource/PortletResourcePermission.html">PortletResourcePermission</a><br />
<span style="background-color: #fff2cc;">name</span>はプロパティとして実装クラスに登録する</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td rowspan="4">インスタンス化<br />
可能なモデル</td>
<td>1</td>
<td rowspan="4">check(permissionChecker, primaryKey, actionId)<br />
check(permissionChecker, model, actionId)</td>
<td rowspan="4"><a href="https://docs.liferay.com/ce/portal/7.1-latest/javadocs/portal-kernel/com/liferay/portal/kernel/security/permission/resource/ModelResourcePermission.html">ModelResourcePermission</a><br />
<span style="background-color: #fff2cc;">name</span>はプロパティとして実装クラスに登録する<br />
<span style="background-color: #fff2cc;">groupId</span>はLiferay<span style="background-color: #fff2cc;">model</span>において<span style="background-color: #fff2cc;">getGroupId</span>で取得する</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
</tbody>
</table>
ここまで考察すると、ようやく第一回の課題「Liferayが提供している<span style="background-color: #fff2cc;">Permission</span>関連クラスのシグネーチャが異なった理由」を解決しました。<br />
<br />
<div>
<div>
※ <span style="font-size: x-small;">ただし、まだ解決していない課題があります。現在のLiferayにおいて、モデルリソースとして定義される仮想モデルに対する権限チェックを行うクラス名は<span style="background-color: #fff2cc;">PortletResourcePermission</span>です。</span></div>
<div>
<ul>
<li><span style="font-size: x-small;">例として、ブログポートレットの<span style="background-color: #fff2cc;">com.liferay.blogs</span>仮想モデルに対する<span style="background-color: #fff2cc;">ADD_ENTRY</span>権限の判定は <span style="background-color: #fff2cc;">BlogsPermission.contains(permissionChecker, scopeGroupId, ActionKeys.ADD_ENTRY)</span>が行います。<a href="https://github.com/liferay/liferay-portal/blob/master/modules/apps/blogs/blogs-web/src/main/java/com/liferay/blogs/web/internal/security/permission/resource/BlogsPermission.java">BlogsEntryPermission.java</a>のソースコードを確認すると、<span style="background-color: #fff2cc;">PortletResourcePermission</span>をOSGIサービスとして参照してることが分かります。</span></li>
</ul>
</div>
<div>
<span style="font-size: x-small;">正直、理由が分かりません。</span><br />
<br /></div>
</div>
<h4>
</h4>
<h4>
権限チェックに追加されたクラス</h4>
<div>
<div>
<span style="font-size: x-small;">※ 以下の内容は<a href="https://github.com/liferay/liferay-portal/tree/7.1.x">Liferay-CE 7.1</a>に基づいています。7.0は一部ヘルパークラスを持っていません。</span></div>
<div>
<br /></div>
</div>
<div>
<div>
Liferay7.0の権限カスタマイズに詳しい方はもう気づいたかもしれませんか、Liferay7.1からの権限設定手順で、<a href="https://help.liferay.com/hc/zh-cn/articles/360017887032-Registering-Permissions-">権限を登録する</a>に、<span style="background-color: #fff2cc;">ModelResourcePermissionLogic</span>と<span style="background-color: #fff2cc;">PortletResourcePermissionLogic</span>などクラスは新規追加されます。では、Liferayの標準モジュール<span style="background-color: #fff2cc;">Blogs</span>を考察し、新規されたクラスを整理しましょう。</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmbrkl1Z8q0-iCXWI5PqYrU1Bi5hTzqdIHO2-OyrO0LxqJd-VRhkg8piUBZ3mJRgyGry1v8Os80VWGLZ7HftvVFeBLbhGFNm3Rrw9joLo6_KiOyCjpNmk3tZfCWS2wqrdowRqrfak8JmxxfkrSwTsuYchcOvV_1C29cVv-2e5-6z2DN1tY74yYlQds/s1279/blog_pm_check.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="589" data-original-width="1279" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmbrkl1Z8q0-iCXWI5PqYrU1Bi5hTzqdIHO2-OyrO0LxqJd-VRhkg8piUBZ3mJRgyGry1v8Os80VWGLZ7HftvVFeBLbhGFNm3Rrw9joLo6_KiOyCjpNmk3tZfCWS2wqrdowRqrfak8JmxxfkrSwTsuYchcOvV_1C29cVv-2e5-6z2DN1tY74yYlQds/w405-h186/blog_pm_check.png" width="405" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div>
<div class="separator" style="clear: both;">
ブログポートレットのUIにおいて</div>
<div class="separator" style="clear: both;">
</div>
<ul>
<li>ブログポートレットの設定はリソース<span style="background-color: #fff2cc;">com_liferay_blogs_web_portlet_BlogsPortlet</span>の権限<span style="background-color: #fff2cc;">CONFIGURATION</span>で決まります。</li>
<li><span style="background-color: #fff2cc;">新しいエントリー</span>ボタンの表示可否はモデルリソース<span style="background-color: #fff2cc;">com.liferay.blogs</span>の権限<span style="background-color: #fff2cc;">ADD_ENTRY</span>で決まります。</li>
<li><span style="background-color: #fff2cc;">permission-blog</span>の編集可否はモデルリソース<span style="background-color: #fff2cc;">com.liferay.blogs.model.BlogsEntry</span>の権限<span style="background-color: #fff2cc;">UPDATE</span>で決まります。</li>
</ul>
まず、インスタンス化可能なモデルリソース<span style="background-color: #fff2cc;">com.liferay.blogs.model.BlogsEntry</span>の権限チェックから考察しましょう。<br />
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
<i><u>インスタンス化可能なモデルリソースの権限チェック</u></i></div>
<div>
<br /></div>
<div>
<div>
ブログエンティティの<span style="background-color: #fff2cc;">更新</span>ボタンの表示の判定は<a href="https://github.com/liferay/liferay-portal/blob/master/modules/apps/blogs/blogs-web/src/main/resources/META-INF/resources/blogs/entry_action.jsp">blogs-web/src/main/resources/META-INF/resources/blogs/entry_action.jsp</a>において<span style="background-color: #fff2cc;">BlogsEntryPermission.contains(permissionChecker, entry, ActionKeys.UPDATE)</span>が行なっています。このクラスから考察すると、Liferay7.1のモデルリソースは以下のような構造のことが分かります。</div>
</div>
<div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGOOTtZtnQiFhyyxKkUDK3W1a7I-kWetedI14wZMC-7zQqQ02Gf4KGDa0bb6G1H05CxdXDzrGFG4g8DKn8d13XSn7-lzUccotODn-fsZNcyXOeMZl9XsX9IyEGO5okBYydCemv8-Mzi7yfg6vw6F5a7PrZ49YJ_yi9IRnqJ1hRtVZAUvqGheJbDDTw/s1155/modelresourcepermission.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="627" data-original-width="1155" height="221" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGOOTtZtnQiFhyyxKkUDK3W1a7I-kWetedI14wZMC-7zQqQ02Gf4KGDa0bb6G1H05CxdXDzrGFG4g8DKn8d13XSn7-lzUccotODn-fsZNcyXOeMZl9XsX9IyEGO5okBYydCemv8-Mzi7yfg6vw6F5a7PrZ49YJ_yi9IRnqJ1hRtVZAUvqGheJbDDTw/w406-h221/modelresourcepermission.png" width="406" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<div>
<br /></div>
<div>
ブログポートレットは、<span style="background-color: #fff2cc;">DefaultModelResourcePermission</span>を介して、<span style="background-color: #fff2cc;">ModelResourcePermissionLogic</span>と<span style="background-color: #fff2cc;">PermissionChecker</span>を用いてあるブログエンティティーに対してユーザがもっている権限をチェックしています。では、<a href="https://github.com/liferay/liferay-portal/blob/8326a95fe0966a30a3e66b0df88eb24b5ff91790/portal-kernel/src/com/liferay/portal/kernel/internal/security/permission/resource/DefaultModelResourcePermission.java#L138">DefaultModelResourcePermission</a>の流れを確認しましょう。</div>
<div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN8j49QkPOq1xNMFT7YRRMnDH-ehCtLggXGOXvrwXdscBrpvZNZZG4ycIpwq66NPdipLLCgq45D8bTQ9gvwpmW-k0YdiHwCzQj7CiYOc5FPgT5IlveB_Leuxtp819ZIYNXQycPX6wCTIQg9TPSdjW3W-XxzQ-F0qBIA9m5w5CwkbV40iXw2ufhFV9T/s1014/defpermission_flow.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1014" data-original-width="460" height="426" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN8j49QkPOq1xNMFT7YRRMnDH-ehCtLggXGOXvrwXdscBrpvZNZZG4ycIpwq66NPdipLLCgq45D8bTQ9gvwpmW-k0YdiHwCzQj7CiYOc5FPgT5IlveB_Leuxtp819ZIYNXQycPX6wCTIQg9TPSdjW3W-XxzQ-F0qBIA9m5w5CwkbV40iXw2ufhFV9T/w193-h426/defpermission_flow.png" width="193" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<div>
<div>
では、フローグラフ中の<span style="background-color: #fff2cc;">ModelResourcePermisisonLogic[]</span>はどこから登録されますか?その答えは<a href="https://github.com/liferay/liferay-portal/blob/7.1.x/modules/apps/blogs/blogs-service/src/main/java/com/liferay/blogs/internal/security/permission/resource/definition/BlogsEntryModelResourcePermissionDefinition.java">BlogsEntryModelResourcePermissionDefinition.java</a>にあります。</div>
</div>
<pre class="brush:java">@Override
public void registerModelResourcePermissionLogics(
ModelResourcePermission modelResourcePermission,
Consumer>
modelResourcePermissionLogicConsumer) {
modelResourcePermissionLogicConsumer.accept(
new StagedModelPermissionLogic<>(
_stagingPermission, BlogsPortletKeys.BLOGS,
BlogsEntry::getEntryId));
modelResourcePermissionLogicConsumer.accept(
new WorkflowedModelPermissionLogic<>(
_workflowPermission, modelResourcePermission,
_groupLocalService, BlogsEntry::getEntryId));
}
</pre>
続いて<a href="https://github.com/liferay/liferay-portal/blob/master/portal-kernel/src/com/liferay/portal/kernel/security/permission/resource/StagedModelPermissionLogic.java">StagedModelPermissionLogic.java</a>と<a href="https://github.com/liferay/liferay-portal/blob/master/portal-kernel/src/com/liferay/portal/kernel/security/permission/resource/WorkflowedModelPermissionLogic.java">WorkflowedModelPermissionLogic.java</a>を考察しましょう(<span style="background-color: #fff2cc;">Staging</span>については<a href="https://help.liferay.com/hc/articles/360018172191-Enabling-Staging-">Staging 公式ドキュメント</a>を参考してください)。<br />
<br />
<ul>
<li><span style="background-color: #fff2cc;">StagedModelPermissionLogic</span>は、<a href="https://github.com/liferay/liferay-portal/blob/7.1.x/modules/apps/export-import/export-import-service/src/main/java/com/liferay/exportimport/internal/staging/permission/StagingPermissionImpl.java">StagingPermissionImpl.java</a>を介して、サイトページ状態が<span style="background-color: #fff2cc;">Stage</span>の場合、一定操作(例:ACCESS, VIEWなど)以外を禁止する</li>
<li><span style="background-color: #fff2cc;">WorkflowedModelPermissionLogic</span>は、<a href="https://github.com/liferay/liferay-portal/blob/7.1.x/portal-impl/src/com/liferay/portal/workflow/permission/WorkflowPermissionImpl.java">WorkflowPermissionImpl.java</a>を介して、ユーザの公開前コンテントに対するアクセス権限を判定する</li>
</ul>
<br />
<div>
<div>
すなわち、登録したのは本来の権限判定対象であるブログエンティティの<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルレコードに関係ないロジックです。<br />
<br />
ここまで考察すると、Liferay 7.1の権限構造をようやく理解できます。<span style="background-color: #fff2cc;">DefaultModelResourcePermission</span>は<span style="background-color: #fff2cc;">ModelResourcePermisisonLogic</span>と<span style="background-color: #fff2cc;">PermissionChecker</span>両方を参照する理由は、<span style="background-color: #fff2cc;">ModelResourcePermisisonLogic</span>と<span style="background-color: #fff2cc;">PermissionChecker</span>の役割が違うのです:</div>
</div>
<div>
<ul>
<li>開発者は<span style="background-color: #fff2cc;">ModelResourcePermissionLogic</span>を介して<span style="background-color: #fff2cc;">ModelResourcePermission</span>に登録したLiferayの<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルに関係ないビジネスロジック</li>
<ul>
<li>登録方式は<a href="https://help.liferay.com/hc/articles/360017887032-Registering-Permissions-">公式ドキュメント</a>方式と<a href="https://github.com/liferay/liferay-portal/blob/master/modules/apps/blogs/blogs-service/src/main/java/com/liferay/blogs/internal/security/permission/resource/definition/BlogsEntryModelResourcePermissionDefinition.java">Liferay 7.1 ソースコード</a>方式があります</li>
<li>どの方式でもOSGIサービス登録になります</li>
</ul>
<li>登録された権限ビジネスロジックは全てnullを返す場合、<span style="background-color: #fff2cc;">PermissionChecker</span>を利用し、<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルからユーザ権限をチェックします。</li>
</ul>
</div>
<div>
<div>
Liferay 7.0の<a href="https://github.com/liferay/liferay-portal/blob/7.0.x/portal-impl/src/com/liferay/portlet/blogs/service/permission/BlogsEntryPermission.java">BlogsEntryPermission.java</a>と比べてみると、7.1の権限チェッククラスの各機能は切り離されていることが分かります。</div>
</div>
<div>
<br /></div>
<table>
<thead>
<tr>
<th>Liferay 7.0</th>
<th>Liferay 7.1</th>
</tr>
</thead>
<tbody>
<tr>
<td><span style="background-color: #fff2cc;">BlogsEntryPermission</span>は直接的に権限判定を行う</td>
<td><span style="background-color: #fff2cc;">BlogsEntryPermission</span>は<span style="background-color: #fff2cc;">ModelResourcePermission</span><br />
を介して権限判定を行う</td>
</tr>
<tr>
<td><span style="background-color: #fff2cc;">StagingPermissionUtil</span>と<span style="background-color: #fff2cc;">WorkflowPermissionUtil</span><br />
を直接参照する</td>
<td>OSGIサービスの<span style="background-color: #fff2cc;">xxxPermissionLogic</span>方式で<br />
<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルに関係ない権限ロジック<br />
を登録する</td>
</tr>
<tr>
<td><span style="background-color: #fff2cc;">PermissionChecker</span>を直接参照する</td>
<td><span style="background-color: #fff2cc;">PermissionChecker</span>は直接参照しない</td>
</tr>
</tbody>
</table>
<br />
<u><i>ポートレットリソースの権限チェック</i></u><br />
<u><i><br /></i></u>
ブログポートレットの<span style="background-color: #fff2cc;">設定</span>などボタンの表示は<span style="background-color: #fff2cc;">com_liferay_blogs_web_portlet_BlogsPortlet</span>ポートレットリソースの権限チェックにおいて判定しています。ポートレット権限の判定はLiferayの組み込み機能のため、<a href="https://help.liferay.com/hc/articles/360018164431-Defining-Permissions-">公式ドキュメント</a>の説明の通り<span style="background-color: #fff2cc;">resource-actions</span>にアクション定義を入れたらLiferayは自動的にブログポートレット権限チェックを行います。<br />
ポートレットの権限判定はモデルリソースのようなOSGI構造を持っていません。具体的には<a href="http://portletpermissionimpl.java/">PortletPermissionImpl.java</a>を参考してください。<br />
<div>
<br /></div>
<div>
<i><u>仮想モデルリソースの権限チェック</u></i></div>
<div>
<br /></div>
<div>
<div>
<span style="background-color: #fff2cc;">新規作成</span>表示の判定は<a href="https://github.com/liferay/liferay-portal/blob/master/modules/apps/blogs/blogs-web/src/main/resources/META-INF/resources/dynamic_include/portlet_header.jsp">blogs-web/src/main/resources/META-INF/resources/dynamic_include/portlet_header.jsp</a>において</div>
<div>
<ul>
<li> <span style="background-color: #fff2cc;">BlogsPermission.contains(permissionChecker, scopeGroupId, ActionKeys.ADD_ENTRY)</span>が行います。</li>
</ul>
</div>
<div>
前述の通り、<a href="https://github.com/liferay/liferay-portal/blob/master/modules/apps/blogs/blogs-web/src/main/java/com/liferay/blogs/web/internal/security/permission/resource/BlogsPermission.java">BlogsPermission.java</a>は<span style="background-color: #fff2cc;">PortletResourcePermission</span>を参照し権限チェックを行なっています。<span style="background-color: #fff2cc;">PortletResourcePermission</span>の構造は<span style="background-color: #fff2cc;">ModelResourcePermission</span>とほぼ同じのため、考察を省略します。</div>
</div>
<div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihj3AJb05GNvdsxhLdoGR_sjCKGwsOqISANNyDUzTSsJGGrFtlKnZ12__-XbrFvT18o1a7xV2uL3aYWcmOxuyFtC_s5NkbeDnhAhvVbuFlSzxIwSlSH6rnRmouaH8mYyJs0RQRKVnaMfpQBx4M8PwR5BVIiV1EwEAE6DO9W8livRSt0Jx92LynVzae/s741/virtualmodel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="324" data-original-width="741" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihj3AJb05GNvdsxhLdoGR_sjCKGwsOqISANNyDUzTSsJGGrFtlKnZ12__-XbrFvT18o1a7xV2uL3aYWcmOxuyFtC_s5NkbeDnhAhvVbuFlSzxIwSlSH6rnRmouaH8mYyJs0RQRKVnaMfpQBx4M8PwR5BVIiV1EwEAE6DO9W8livRSt0Jx92LynVzae/w458-h201/virtualmodel.png" width="458" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<i><u>PermissionCheckerの正体</u></i></div>
<div>
<br /></div>
<div>
<div>
ここまで考察すると、Liferayでは、<span style="background-color: #fff2cc;">PortletPermission</span>、<span style="background-color: #fff2cc;">PortletResourcePermission</span>、<span style="background-color: #fff2cc;">ModelResourcePermission</span>などヘルパークラスを介して<span style="background-color: #fff2cc;">PermissionChecker</span>インタフェースを利用し、違うリソースに対する権限チェックを行っていることが分かりました。</div>
<div>
<br /></div>
<div>
では、最後に<span style="background-color: #fff2cc;">PermisisonChecker</span>の正体を確認しましょう。ポートレットJSPで<span style="background-color: #fff2cc;">PermissionChecker</span>のクラス名を出力すると、<a href="https://github.com/liferay/liferay-portal/blob/master/portal-impl/src/com/liferay/portal/security/permission/StagingPermissionChecker.java">StagingPermissionChecker.java</a>のことが確認できますが、ソースコードを見ると、<span style="background-color: #fff2cc;">StagingPermissionChecker</span>はもう一つ<span style="background-color: #fff2cc;">_permissionChecker</span>をラップしています。続いて<a href="https://github.com/liferay/liferay-portal/blob/b04855c6030207e66804f9f7f56ec8b736c28b41/portal-impl/src/com/liferay/portal/security/permission/PermissionCheckerFactoryImpl.java#L33">PermissionCheckerFactoryImpl.java</a>を確認すると、<span style="background-color: #fff2cc;">PermissionChecker</span>の正体は<span style="background-color: #fff2cc;">PropsValues</span>、すなわち<span style="background-color: #fff2cc;">portal.properties</span>で設定されたクラス名です。</div>
</div>
<pre class="brush:java">public PermissionCheckerFactoryImpl() throws Exception {
Class<permissionchecker> clazz =
(Class<permissionchecker>)Class.forName(
PropsValues.PERMISSIONS_CHECKER);
_permissionChecker = clazz.newInstance();
}
</permissionchecker></permissionchecker></pre>
皆さまは多分すでに存知ですが、Liferayのシステム<span style="background-color: #fff2cc;">PermissionChecker</span>は、<span style="background-color: #fff2cc;">portal-ext.properties</span>で設定できます。<br />
<div>
</div>
<pre class="brush:html"># Set the default permission checker class used by
# com.liferay.portal.security.permission.PermissionCheckerFactory to check
# permissions for actions on objects. This class can be overriden with a
# custom class that implements
# com.liferay.portal.security.permission.PermissionChecker.
#
#permissions.checker=com.liferay.portal.security.permission.SimplePermissionChecker
permissions.checker=com.liferay.portal.security.permission.AdvancedPermissionChecker
</pre>
そして、Liferayのデフォルトの状態の<span style="background-color: #fff2cc;">PermissionChecker</span>の正体は<a href="https://github.com/liferay/liferay-portal/blob/master/portal-impl/src/com/liferay/portal/security/permission/AdvancedPermissionChecker.java">AdvancedPermissionChecker.java</a>であることが分かりました。さらに、<span style="background-color: #fff2cc;">portal-ext.properties</span>にカスタマイズクラスを登録するとLiferayのデフォルト<span style="background-color: #fff2cc;">PermissionChecker</span>を変更することもできます。
<style>
table {
margin: 10px 0 15px 0;
border-collapse: collapse;
border-spacing: 0;
display: block;
width: 100%;
overflow: auto;
word-break: keep-all;
word-wrap: break-word;
border-top-color: gray;
}
thead {
display: table-header-group;
vertical-align: middle;
border-top-color: inherit;
border-right-color: inherit;
border-bottom-color: inherit;
border-left-color: inherit;
}
tr {
display: table-row;
vertical-align: inherit;
border-top-color: inherit;
border-right-color: inherit;
border-bottom-color: inherit;
border-left-color: inherit;
}
th {
border: 1px solid #d6d6d6;
padding: 6px 13px;
}
tbody {
display: table-row-group;
vertical-align: middle;
border-top-color: inherit;
border-right-color: inherit;
border-bottom-color: inherit;
border-left-color: inherit;
}
td {
border: 1px solid #d6d6d6;
padding: 6px 13px;
display: table-cell;
vertical-align: inherit;
}
</style>Min Wuhttp://www.blogger.com/profile/13688681791400596862noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-22811399851609859412020-05-26T16:58:00.002+09:002022-08-17T18:46:42.144+09:00ResourcePermissionの考察 (2)<a href="http://labo-blog.aegif.jp/2020/05/resourcepermission-1.html">前回</a>、Liferayが一般ロールに与える権限を考察しました。今回は、サイトロール、組織ロールなどグループロールに対する権限の考察から始めようと思います。Liferay権限システムでは、サイトロールと組織ロールに付与される一般権限の適用範囲は<span style="background-color: #fff2cc;">グループテンプレート</span>と認識し、<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルでは<span style="background-color: #fff2cc;">scope=3</span><span style="background-color: white;">になります</span>。<br />
<br />
それでは、前回と同じく、モデルリソースとポートレットリソース別でサイトロール、組織ロールに付与する権限を考察しましょう。<br />
<div>
<br /></div>
<div>
<h4>
サイトロール x モデルリソース</h4>
</div>
<div>
<div>
以下の準備を行いましょう。設定方法は前回同様です。</div>
<div>
<br /></div>
<div>
<ul>
<li><span style="background-color: #fff2cc;">blog_site_role</span>サイトロールを作成する</li>
<li><span style="background-color: #fff2cc;">blog_site_role</span>を開き</li>
<ul>
<li><span style="background-color: #fff2cc;">ブログ/エントリー追加する</span>権限を追加する</li>
<li><span style="background-color: #fff2cc;">ブログのエントリ/表示</span>権限を追加する</li>
</ul>
<li>前回、デフォルトサイトに作成したブログエンティティ<span style="background-color: #fff2cc;">permission-blog</span>の権限定義において</li>
<ul>
<li><span style="background-color: #fff2cc;">blog_site_role</span>に<span style="background-color: #fff2cc;">更新</span>権限を追加する</li>
</ul>
</ul>
</div>
<div>
では、<span style="background-color: #fff2cc;">Role_</span>と<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルを確認しましょう。</div>
</div>
<div>
<br /></div>
<pre class="brush:sql">select roleId, name, type_ from Role_ where name = "blog_site_role";
select resourcePermissionId, name, scope, primKey, primKeyId, roleId, actionIds
from ResourcePermission where roleId = 50910;
</pre>
結果は以下の通りです。<br />
<div>
<br /></div>
<table>
<thead>
<tr>
<th>roleId</th>
<th>ロール名</th>
<th>ロールtype</th>
</tr>
</thead>
<tbody>
<tr>
<td>50910</td>
<td>blog_site_role</td>
<td>2</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>ID</th>
<th>リソース名</th>
<th>scope</th>
<th>primKey</th>
<th>primKeyId</th>
<th>roleId</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>5226</td>
<td>com.liferay.blogs</td>
<td>3</td>
<td>0</td>
<td>0</td>
<td>50910</td>
<td>2</td>
</tr>
<tr>
<td>5227</td>
<td>com.liferay.blogs.model.BlogsEntry</td>
<td>3</td>
<td>0</td>
<td>0</td>
<td>50910</td>
<td>1</td>
</tr>
<tr>
<td>5228</td>
<td>com.liferay.blogs.model.BlogsEntry</td>
<td>4</td>
<td>50893</td>
<td>50893</td>
<td>50910</td>
<td>32</td>
</tr>
</tbody>
</table>
その結果が表す意味を考察しましょう。<br />
<div>
<br /></div>
<table>
<thead>
<tr>
<th>ID</th>
<th>ロール</th>
<th>どんなリソース</th>
<th>どの操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>5226</td>
<td>blog_site_role</td>
<td><span style="background-color: #fff2cc;">scope=3</span>: サイトロール<span style="background-color: #fff2cc;">blog_site_role</span>を持つサイト中の全て<span style="background-color: #fff2cc;">com.liferay.blogs</span></td>
<td>ADD_ENTRY</td>
</tr>
<tr>
<td>5227</td>
<td>blog_site_role</td>
<td><span style="background-color: #fff2cc;">scope=3</span>: サイトロール<span style="background-color: #fff2cc;">blog_site_role</span>を持つサイト中の全て<span style="background-color: #fff2cc;">com.liferay.blogs.model.BlogsEntry</span></td>
<td>VIEW</td>
</tr>
<tr>
<td>5228</td>
<td>blog_site_role</td>
<td><span style="background-color: #fff2cc;">scope=4</span>: <span style="background-color: #fff2cc;">id=50893</span>の<span style="background-color: #fff2cc;">com.liferay.blogs.model.BlogsEntry</span>インスタンス</td>
<td>UPDATE</td>
</tr>
</tbody>
</table>
※ ユーザは複数サイト中同じサイトロールに割り当てられることができるため、ユーザがサイトロールを持つサイト中のみに、そのサイトロールに与える<span style="background-color: #fff2cc;">scope=3</span>の権限を持ちます。<br />
<h4>
サイトロール x ポートレットリソース</h4>
<div>
<div>
以下の準備を行いましょう。</div>
</div>
<div>
<div>
<ul>
<li><span style="background-color: #fff2cc;">blog_site_role</span>を開いて、権限定義に</li>
<ul>
<li><span style="background-color: #fff2cc;">アプリケーション権限/ページに追加する</span>権限を追加する</li>
</ul>
<li>デフォルトサイトのブログポートレットに</li>
<ul>
<li>ポートレット権限設定を開いて<span style="background-color: #fff2cc;">blog_site_role</span>に<span style="background-color: #fff2cc;">設定</span>権限を追加する</li>
</ul>
</ul>
</div>
<div>
それ後、ロールと<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルで確認しましょう。結果は以下の通りです(重複するデータについては除外します)。</div>
</div>
<div>
<br /></div>
<div>
<br /></div>
<table>
<thead>
<tr>
<th>ID</th>
<th>リソース名</th>
<th>scope</th>
<th>primKey</th>
<th>primKeyId</th>
<th>roleId</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>5232</td>
<td>com_liferay_blogs_web_portlet_BlogsPortlet</td>
<td>3</td>
<td>0</td>
<td>0</td>
<td>50910</td>
<td>2</td>
</tr>
<tr>
<td>5233</td>
<td>com_liferay_blogs_web_portlet_BlogsPortlet</td>
<td>4</td>
<td>38656_LAYOUT_com_liferay_blogs_web_portlet_BlogsPortlet</td>
<td>0</td>
<td>50910</td>
<td>4</td>
</tr>
</tbody>
</table>
結果を考察しましょう。<br />
<div>
<br /></div>
<table>
<thead>
<tr>
<th>ID</th>
<th>ロール</th>
<th>どんなリソース</th>
<th>どの操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>5232</td>
<td>blog_site_role</td>
<td><span style="background-color: #fff2cc;">scope=3</span>: サイトロール<span style="background-color: #fff2cc;">blog_site_role</span>を持つサイト中の全て<span style="background-color: #fff2cc;">BlogsPortlet</span></td>
<td>ADD_ENTRY</td>
</tr>
<tr>
<td>5228</td>
<td>blog_site_role</td>
<td><span style="background-color: #fff2cc;">scope=4</span>: <span style="background-color: #fff2cc;">id=38656</span>のレイアウト上の<span style="background-color: #fff2cc;">BlogsPortlet</span></td>
<td>UPDATE</td>
</tr>
</tbody>
</table>
<h4>
組織ロール</h4>
<div>
<div>
Liferayでは組織ロールの挙動はサイトロールとほぼ一致のため省略します。<br />
<br /></div>
</div>
<h4>
まとめ</h4>
<div>
<div>
ここまで考察した結果をまとめましょう。<span style="background-color: #fff2cc;">scope=3</span>のサイトロールと組織ロールの適用範囲はユーザが当該ロールを割り当てられているかとうかで決まります。</div>
<div>
<br /></div>
<div>
<ul>
<li>特定インスタンスを持っていないリソース</li>
<ul>
<li>サイトロールの権限の適用範囲は、ユーザが当該ロールを割り当てられているサイトのみです。そのため、リソース<span style="background-color: #fff2cc;">primKey</span>は0になります。</li>
<li>組織ロールの権限の適用範囲は、ユーザが当該ロールを割り当てらている組織の組織サイトです。そのため、リソース<span style="background-color: #fff2cc;">primKey</span>は0になります。</li>
</ul>
<li>リソースの特定インスタンス</li>
<ul>
<li>権限の適用範囲は<span style="background-color: #fff2cc;">name</span>と<span style="background-color: #fff2cc;">primKey</span>が特定できるリソースのみです。</li>
</ul>
</ul>
</div>
</div>
<div>
<br /></div>
<table>
<thead>
<tr>
<th>リソース種類</th>
<th>特定インスタンス</th>
<th>リソース名</th>
<th>scope</th>
<th>primKey</th>
<th>適用範囲</th>
</tr>
</thead>
<tbody>
<tr>
<td>モデル</td>
<td>N</td>
<td>モデル名</td>
<td>1</td>
<td>companyId</td>
<td><span style="background-color: #fff2cc;">primKey</span>が表すLiferayインスタンス</td>
</tr>
<tr>
<td>モデル</td>
<td>N</td>
<td>モデル名</td>
<td>3</td>
<td>0</td>
<td><span style="background-color: #fff2cc;">roleId</span>が表すロールを持ち場所(サイトまたは組織のサイト)中の全モデルインスタンス</td>
</tr>
<tr>
<td>モデル</td>
<td>Y</td>
<td>モデル名</td>
<td>4</td>
<td>リソースId</td>
<td><span style="background-color: #fff2cc;">primKey</span>が表すモデルインスタンス</td>
</tr>
<tr>
<td>ポートレット</td>
<td>N</td>
<td>ポートレットキー</td>
<td>1</td>
<td>companyId</td>
<td><span style="background-color: #fff2cc;">primKey</span>が表すLiferayインスタンス</td>
</tr>
<tr>
<td>ポートレット</td>
<td>N</td>
<td>ポートレットキー</td>
<td>3</td>
<td>0</td>
<td><span style="background-color: #fff2cc;">roleId</span>が表すロールを持ち場所(サイトまたは組織のサイト)中の全<span style="background-color: #fff2cc;">primKey</span>が表すポートレット</td>
</tr>
<tr>
<td>ポートレット</td>
<td>Y</td>
<td>ポートレットキー</td>
<td>4</td>
<td><span style="background-color: #fff2cc;">layout</span>と<br />
ポートレットキー</td>
<td><span style="background-color: #fff2cc;">primKey</span>が表すポートレット</td>
</tr>
</tbody>
</table>
<h4>
その他</h4>
<h5>
チームロール</h5>
<div>
Liferayでは、サイト内の<a href="https://portal.liferay.dev/docs/6-2/user/-/knowledge_base/u/creating-teams-for-advanced-site-membership-management">チーム</a>が作成できます。チームに権限を与えることもできます。例として、デフォルトサイトに<span style="background-color: #fff2cc;">team-1</span>チームを作成した後に、前回作成した<span style="background-color: #fff2cc;">permission-blog</span>の権限設定を開いて<span style="background-color: #fff2cc;">team-1</span>ロールを確認できます。</div><div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwFPk9CwE-BrTq8ah0hFAGqIjWMuTs3oGpH_0tqnvHcQwFNplSX5b7wsaQcW350QdmFPM0X7Zmf326In79atv5kWfcAAp5How9V7FC1lFrdemUnzQInQdCQKkli1CPrxalYecpbAZpBgrW2LdrlaRuPlqivD5vcEQ7a8Kg-04204_0bv1LaF4pRXKx/s1600/team_permission.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="472" data-original-width="1600" height="146" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwFPk9CwE-BrTq8ah0hFAGqIjWMuTs3oGpH_0tqnvHcQwFNplSX5b7wsaQcW350QdmFPM0X7Zmf326In79atv5kWfcAAp5How9V7FC1lFrdemUnzQInQdCQKkli1CPrxalYecpbAZpBgrW2LdrlaRuPlqivD5vcEQ7a8Kg-04204_0bv1LaF4pRXKx/w497-h146/team_permission.png" width="497" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<br />
では、<span style="background-color: #fff2cc;">team-1</span>ロールに<span style="background-color: #fff2cc;">更新する</span>権限を追加し、データベースを確認しましょう。</div>
<div>
<br /></div>
<pre class="brush:sql">select teamId, name from Team where name = "team-1";
select roleId, name, type_ from Role_ where name = "50924";
select resourcePermissionId, name, scope, primKey, primKeyId, roleId, actionIds
from ResourcePermission where roleId = 50925;
</pre>
結果は以下の通りです。<br />
<div>
<br /></div>
<table>
<thead>
<tr>
<th>teamId</th>
<th>チーム名</th>
</tr>
</thead>
<tbody>
<tr>
<td>50924</td>
<td>team-1</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>roleId</th>
<th>ロール名</th>
<th>ロールtype</th>
</tr>
</thead>
<tbody>
<tr>
<td>50925</td>
<td>50924</td>
<td>4</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>ID</th>
<th>リソース名</th>
<th>scope</th>
<th>primKey</th>
<th>primKeyId</th>
<th>roleId</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>5239</td>
<td>com.liferay.blogs.model.BlogsEntry</td>
<td>4</td>
<td>50893</td>
<td>50893</td>
<td>50925</td>
<td>32</td>
</tr>
</tbody>
</table>
チームを作成後、Liferayは自動的に<span style="background-color: #fff2cc;">classPk=teamId</span>、<span style="background-color: #fff2cc;">className=チーム</span>のロールを作成します。そのロールに与える権限はチームの所属サイト上のブログインスタンスとブログポートレットインスタンスだけのため、チームロールの権限レコードは<span style="background-color: #fff2cc;">scope=4</span>になります。<br />
<h5>
scope=2</h5>
<div>
L<a href="https://liferay.dev/blogs/-/blogs/deep-dive-in-roles-and-permissions">iferay公式ブログ記事</a>の説明の通り、<span style="background-color: #fff2cc;">scope=2</span>(グループ範囲)の<span style="background-color: #fff2cc;">ResourcePermission</span>レコードが存在します。ただし、今まで検証した権限の<span style="background-color: #fff2cc;">scope</span>はいずれでも<span style="background-color: #fff2cc;">2</span>になりません。では、<span style="background-color: #fff2cc;">scope=2</span>の権限は一体何でしょうか?<br />
<br />
答えは、指定されたグループ(=サイト)内のリソースのみに有効する権限です。以下の手順で検証しましょう。<br />
<br />
<ul>
<li><span style="background-color: #f3f3f3;">一般ロール</span><span style="background-color: #fff2cc;">blog_role</span>を開き</li>
<ul>
<li><span style="background-color: #fff2cc;">権限の定義</span>に<span style="background-color: #fff2cc;">ブログ/権限設定</span>を追加する</li>
<li>追加の際、<span style="background-color: #fff2cc;">権限設定</span>項目の右の<span style="background-color: #fff2cc;">変更</span>ボタンを押し、<span style="background-color: #fff2cc;">Liferay DXP</span>(デフォルトサイト)と<span style="background-color: #fff2cc;">ユーザー非公開サイト</span>を選択する</li>
</ul>
</ul>
</div>
<div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOY5FyOn74aj3RHMi1md5_dYG4ptKTNZnYJobOotxmRjq3b5XSAI2nE_1TvnwecgAASDOSaNrAcfvnzVVNX9szTwT2xxM3j2GMnv-Tmxxmje4A-9YjzxT4-sYuYGcqQe-ETM-05cBiiTkr93L0CbJ0P2JbPve-mwp-k22DHOcKgk-c7VOtqQzydIU3/s1600/scope2_permission.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="734" data-original-width="1600" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOY5FyOn74aj3RHMi1md5_dYG4ptKTNZnYJobOotxmRjq3b5XSAI2nE_1TvnwecgAASDOSaNrAcfvnzVVNX9szTwT2xxM3j2GMnv-Tmxxmje4A-9YjzxT4-sYuYGcqQe-ETM-05cBiiTkr93L0CbJ0P2JbPve-mwp-k22DHOcKgk-c7VOtqQzydIU3/w419-h192/scope2_permission.png" width="419" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<div class="separator" style="clear: both;">
その後、データベースをチェックしましょう。</div>
<div class="separator" style="clear: both;">
<br /></div>
<pre class="brush:sql">select resourcePermissionId, name, scope, primKey, primKeyId, roleId, actionIds
from ResourcePermission where roleId = 50867 and scope = 2;
</pre>
結果はご覧の通り、<span style="background-color: #fff2cc;">scope=2</span>と<span style="background-color: #fff2cc;">primKey</span>は<span style="background-color: #fff2cc;">Liferay DXP</span>サイトと<span style="background-color: #fff2cc;">ユーザー非公開サイト</span>の<span style="background-color: #fff2cc;">groupId</span>の権限レコードが作成されました。<br />
<br />
<table>
<thead>
<tr>
<th>ID</th>
<th>リソース名</th>
<th>scope</th>
<th>primKey</th>
<th>primKeyId</th>
<th>roleId</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>5324</td>
<td>com_liferay_blogs_web_portlet_BlogsPortlet</td>
<td>2</td>
<td>20126</td>
<td>20126</td>
<td>50867</td>
<td>8</td>
</tr>
<tr>
<td>5325</td>
<td>com_liferay_blogs_web_portlet_BlogsPortlet</td>
<td>2</td>
<td>20132</td>
<td>20132</td>
<td>50867</td>
<td>8</td>
</tr>
</tbody>
</table>
では、<span style="background-color: #fff2cc;">scope=2</span>の権限と<span style="background-color: #fff2cc;">scope=3</span>のサイトロールの権限の違いを考察しましょう。<br />
<div>
<br /></div>
<table>
<thead>
<tr>
<th>scope</th>
<th>適用範囲</th>
</tr>
</thead>
<tbody>
<tr>
<td>2</td>
<td><span style="background-color: #fff2cc;">primKey</span>が表すサイト内のリソース、1個レコードの適用サイト数は1</td>
</tr>
<tr>
<td>3</td>
<td><span style="background-color: #fff2cc;">roleId</span>が表すサイトロールを持つサイト内のリソース 、1個レコードは複数サイト適用可能</td>
</tr>
</tbody>
</table>
<br />
次回はここまて考察した内容をLiferayカスタマイズでの運用を考察したい思います。<br />
<style>
table {
margin: 10px 0 15px 0;
border-collapse: collapse;
border-spacing: 0;
display: block;
width: 100%;
overflow: auto;
word-break: keep-all;
word-wrap: break-word;
border-top-color: gray;
}
thead {
display: table-header-group;
vertical-align: middle;
border-top-color: inherit;
border-right-color: inherit;
border-bottom-color: inherit;
border-left-color: inherit;
}
tr {
display: table-row;
vertical-align: inherit;
border-top-color: inherit;
border-right-color: inherit;
border-bottom-color: inherit;
border-left-color: inherit;
}
th {
border: 1px solid #d6d6d6;
padding: 6px 13px;
}
tbody {
display: table-row-group;
vertical-align: middle;
border-top-color: inherit;
border-right-color: inherit;
border-bottom-color: inherit;
border-left-color: inherit;
}
td {
border: 1px solid #d6d6d6;
padding: 6px 13px;
display: table-cell;
vertical-align: inherit;
}
</style>Min Wuhttp://www.blogger.com/profile/13688681791400596862noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-36737394538151563942020-05-20T22:15:00.002+09:002022-08-17T18:49:47.789+09:00ResourcePermissionの考察 (1)こんにちは。ウです。<br />
<br />
みな様がLiferayカスタマイズをする時、権限周りのメソッド"シグネチャーに困ったことがありますか?例えば、<span style="background-color: #fff2cc;"><a href="https://github.com/liferay/liferay-portal/blob/master/portal-kernel/src/com/liferay/portal/kernel/security/permission/PermissionChecker.java" style="background-color: white;">PermissionChecker</a></span>とか、Liferay 7.1から新規したヘルパークラス<span style="background-color: white;"><a href="https://github.com/liferay/liferay-portal/blob/master/portal-kernel/src/com/liferay/portal/kernel/security/permission/resource/ModelResourcePermission.java">ModelResourcePermission.java</a></span>と<span style="background-color: white;"><a href="https://github.com/liferay/liferay-portal/blob/master/portal-kernel/src/com/liferay/portal/kernel/security/permission/resource/PortletResourcePermission.java">PortletResourcePermission.java</a></span>などにおいてはメソッド中、このような定義がよく見えます。<br />
<br />
<pre class="brush:java">//PermissionChecker
public boolean hasOwnerPermission(long companyId, String name, long primKey, long ownerId, String actionId);
public boolean hasPermission(Group group, String name, long primKey, String actionId);
// ModelResourcePermission
public void check(PermissionChecker permissionChecker, long primaryKey, String actionId);
public void check(PermissionChecker permissionChecker, T model, String actionId);
// PortletResourcePermission
public void check(PermissionChecker permissionChecker, Group group, String actionId);
</pre>
<br />
どの場面でどのメソッドを利用しますか?利用の際どの値をメソッドに与えますか?そのメソッドシグネチャーはLiferayの権限管理の関係はどうですか?今回はこの権限周りにいて考察しようと思います。<br />
<div>
<br /></div>
<div>
<div>
ちなみに、みなさまは<a href="https://liferay.dev/blogs/-/blogs/deep-dive-in-roles-and-permissions">Liferayオフィシャルブログの権限関連記事</a>を読んだことがありますか?この記事はLiferayのロールと権限の基本関係を説明しているのでぜひおすすめです。</div>
</div>
<div>
<br /></div>
<h4>
Liferayの権限</h4>
<div>
<div>
みな様のご存知通り、Liferayの権限<a href="https://portal.liferay.dev/docs/7-0/tutorials/-/knowledge_base/t/adding-permissions-to-resources">システム</a>には、ポートレットリソースまたはモデルリソース毎の粒度で行われています。従って:</div>
<div>
<br /></div>
<div>
<ul>
<li>Liferayリソース(<span style="background-color: #fff2cc;">Blog</span>、<span style="background-color: #fff2cc;">JournalArticle</span>または<span style="background-color: #fff2cc;">DLFileEntry</span>など)の初期パーミッションは全部<span style="background-color: #fff2cc;">ResourceLocalService.addResources</span>に介して<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルにレコードを作成している(例:<a href="https://github.com/liferay/liferay-portal/blob/7a8b847a3f3e8bc649d94cb80248623ea2bde5a2/modules/apps/journal/journal-service/src/main/java/com/liferay/journal/service/impl/JournalArticleLocalServiceImpl.java#L841">JournalArticleLocalServiceImpl.java</a>)。</li>
<li>逆に、<span style="background-color: #fff2cc;">PermissionChecker</span>がユーザの権限をチェックする際、同じく<span style="background-color: #fff2cc;">ResourceLocalService.hasUserPermission</span>などのメソッドを利用している(例:<a href="https://github.com/liferay/liferay-portal/blob/7a8b847a3f3e8bc649d94cb80248623ea2bde5a2/portal-impl/src/com/liferay/portal/security/permission/AdvancedPermissionChecker.java">AdvancedPermissionChecker.java</a>)。</li>
</ul>
</div>
<div>
<br /></div>
<div>
すなわち、Liferayでは、<span style="background-color: #fff2cc;">ResourcePermission</span>と<span style="background-color: #fff2cc;">PermissionChecker</span>を利用し本当の<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルの詳細情報を隠しています。Liferayの権限システムを深く理解したい場合、<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルとリソース権限の関係を考察しないといけない理由はそこにあります。</div>
<div>
<br /></div>
</div>
<h4>
ResourcePermissionテーブル</h4>
<div>
<div>
Liferayが行なっている権限管理は<a href="https://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%83%AB%E3%83%99%E3%83%BC%E3%82%B9%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%88%B6%E5%BE%A1">ロールベースアクセス制御(RBAC)</a>方式のため、最終的にデータベースに記入するレコードは以下の内容になります:</div>
<div>
<ul>
<li>あるロールが</li>
<li>あるリソースに対して</li>
<li>どんな操作が許可される</li>
</ul>
</div>
<div>
<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルはその三つの情報を含んでいます。上記<a href="https://liferay.dev/blogs/-/blogs/deep-dive-in-roles-and-permissions">Liferayオフィシャルブログ記事</a>を参考して具体的に整理してみましょう。</div>
<div>
<br /></div>
<div>
<ul>
<li><span style="background-color: #fff2cc;">name</span>: リソース名</li>
<ul>
<li>ポートレットリソース:ポートレットキー</li>
<li>モデルリソース:モデル名</li>
</ul>
<li><span style="background-color: #fff2cc;">primKey</span>: リソースID(権限範囲)</li>
<ul>
<li>全Liferayインスタンス有効権限: <span style="background-color: #fff2cc;">companyId</span></li>
<li>グループ内有効: <span style="background-color: #fff2cc;">groupId</span></li>
<li>具体的なリソースに対する権限:</li>
<ul>
<li>モデルリソース: リソース<span style="background-color: #fff2cc;">primKey</span></li>
<li>ポートレットリソース: <span style="background-color: #fff2cc;">layoutId</span> + <span style="background-color: #fff2cc;">_LAYOUT_</span> + <span style="background-color: #fff2cc;">portletId</span></li>
</ul>
</ul>
<li><span style="background-color: #fff2cc;">scope</span>: 権限の範囲</li>
<ul>
<li>1: 全Liferayインスタンスに有効</li>
<li>2: グループ内のみ有効</li>
<li>3: グループテンプレート(サイト、組織)内のみ有効</li>
<li>4: 具体的なリソースインスタンスに対する権限</li>
</ul>
<li> <span style="background-color: #fff2cc;">roleId</span>: ロールID</li>
<li> <span style="background-color: #fff2cc;">actionId</span>: 権限が許可する操作</li>
<ul>
<li><span style="background-color: #fff2cc;">actionId</span>のbitwise定義は<a href="https://liferay.dev/blogs/-/blogs/deep-dive-in-roles-and-permissions">Liferayオフィシャルブログ記事</a>を参考する</li>
</ul>
</ul>
</div>
<div>
<br /></div>
<div>
まとめると、以下のグラフのように<span style="background-color: #fff2cc;">RBAC</span>に必要な情報をレコードで格納しています。<br />
<br /></div>
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGMc6YzVIhv1eezt2YGTvCgC1PRnpJ3LNC7ITNuW3MfVy4dBnLgqFyix1uNafmMD9RiLfAyhenst55u67nCxQ8NcCWKj1-7oh1zwrAcx-M-sPdMqmZZ7H2nxCQ6sGK2rGcFGSLoXzb_Tov9hmqXWEuNH625XwyuutwngWHA3Qoe43iv4hDBS6Sen2I/s557/rp_table_column.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="498" data-original-width="557" height="231" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGMc6YzVIhv1eezt2YGTvCgC1PRnpJ3LNC7ITNuW3MfVy4dBnLgqFyix1uNafmMD9RiLfAyhenst55u67nCxQ8NcCWKj1-7oh1zwrAcx-M-sPdMqmZZ7H2nxCQ6sGK2rGcFGSLoXzb_Tov9hmqXWEuNH625XwyuutwngWHA3Qoe43iv4hDBS6Sen2I/w258-h231/rp_table_column.png" width="258" /></a></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
それでは、具体的にどのような内容が格納されるのかを確認しましょう。</div>
<div class="separator" style="clear: both;">
<br /></div>
<h4>
考察</h4>
<div>
<div>
今回はLiferayの標準モジュール<span style="background-color: #fff2cc;">Blog</span>ポートレットを利用して<span style="background-color: #fff2cc;">ResourcePermission</span>テーブル中一般ロールに対する権限の表現を確認しましょう。<br />
<br /></div>
</div>
<h4>
一般ロール x モデルリソース</h4>
<div>
<div>
以下の準備を行いましょう:</div>
<div>
<br /></div>
<div>
<ul>
<li>一般ロール<span style="background-color: #fff2cc;">blog_role</span>を作成する</li>
<li><span style="background-color: #fff2cc;">blog_role</span>を開いて、権限定義に</li>
<ul>
<li><span style="background-color: #fff2cc;">ブログ/エントリー追加する</span>権限を追加する</li>
<li><span style="background-color: #fff2cc;">ブログのエントリ/表示</span>権限を追加する</li>
</ul>
</ul>
</div>
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNIu4jmnu34laYPDOrziGaubRNranSAaHV6AFITL2jbFe5v0uWcDDDC3hRxO7YiWjC2wHEvWkU6gRYVOKP3oObJ5m_zz3DzV7l3SvJyYrr4XVpZKHdnyT66UJj51RgtwPzT_Ra8T49KhKlenVN-HJ81U_Id72R9SYjo4DLEr1LcJqmXindKglQ86gb/s965/blog_role_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="329" data-original-width="965" height="151" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNIu4jmnu34laYPDOrziGaubRNranSAaHV6AFITL2jbFe5v0uWcDDDC3hRxO7YiWjC2wHEvWkU6gRYVOKP3oObJ5m_zz3DzV7l3SvJyYrr4XVpZKHdnyT66UJj51RgtwPzT_Ra8T49KhKlenVN-HJ81U_Id72R9SYjo4DLEr1LcJqmXindKglQ86gb/w445-h151/blog_role_1.png" width="445" /></a></div>
<div>
<br /></div>
<div>
<ul>
<li>デフォルトサイトにブログポートレットを置き、その中に<span style="background-color: #fff2cc;">permisison-blog</span>というブログエンティティを作成する</li>
<li><span style="background-color: #fff2cc;">permission-blog</span>の権限定義に、</li>
<ul>
<li> <span style="background-color: #fff2cc;">blog_role</span>に<span style="background-color: #fff2cc;">表示</span>と<span style="background-color: #fff2cc;">更新</span>を追加する</li>
</ul>
</ul>
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgub3F1ICfocmEV7Bf6g00xz1D16G8ewZvDSpcUlfSCUT5-BTMLJE77K1fTUpBvqn_yTko6JeYbnSs5TAGV__YfeY3kxr3RmMsjC9ETfsEAHrYIAK2p75_gqs6TGxl3tyRTCxkDBzn7qme_pm6Vpl2fDaYL-nUi_MA-DPEvGpJ544YBhbA39VAD_7Ek/s926/blog_perm_instance.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="377" data-original-width="926" height="175" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgub3F1ICfocmEV7Bf6g00xz1D16G8ewZvDSpcUlfSCUT5-BTMLJE77K1fTUpBvqn_yTko6JeYbnSs5TAGV__YfeY3kxr3RmMsjC9ETfsEAHrYIAK2p75_gqs6TGxl3tyRTCxkDBzn7qme_pm6Vpl2fDaYL-nUi_MA-DPEvGpJ544YBhbA39VAD_7Ek/w431-h175/blog_perm_instance.png" width="431" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
その後、ロールと<span style="background-color: #fff2cc;">ResourcePermission</span>テーブルで確認しましょう。</div>
<pre class="brush:sql">select roleId, name, type_ from Role_ where name = "blog_role";
select resourcePermissionId, name, scope, primKey, primKeyId, roleId, actionIds from ResourcePermission where roleId = 50867;
</pre>
<br />
結果は以下の通りです。<br />
<table>
<thead>
<tr>
<th>roleId</th>
<th>ロール名</th>
<th>ロールtype</th>
</tr>
</thead>
<tbody>
<tr>
<td>50867</td>
<td>blog_role</td>
<td>1</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>ID</th>
<th>リソース名</th>
<th>scope</th>
<th>primKey</th>
<th>primKeyId</th>
<th>roleId</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>5207</td>
<td>com.liferay.blogs</td>
<td>1</td>
<td>20099</td>
<td>20099</td>
<td>50867</td>
<td>2</td>
</tr>
<tr>
<td>5218</td>
<td>com.liferay.blogs.model.BlogsEntry</td>
<td>1</td>
<td>20099</td>
<td>20099</td>
<td>50867</td>
<td>1</td>
</tr>
<tr>
<td>5219</td>
<td>com.liferay.blogs.model.BlogsEntry</td>
<td>4</td>
<td>50893</td>
<td>50893</td>
<td>50867</td>
<td>33</td>
</tr>
</tbody>
</table>
<br />
では、その結果はどのような権限を表すのかについて考察しましょう。<br />
<div>
</div>
<table>
<thead>
<tr>
<th>ID</th>
<th>ロール</th>
<th>どんなリソース</th>
<th>どの操作※</th>
</tr>
</thead>
<tbody>
<tr>
<td>5207</td>
<td>blog_role</td>
<td><span style="background-color: #fff2cc;">scope=1</span>: liferayインスタンス<span style="background-color: #fff2cc;">20099</span>中の全て<span style="background-color: #fff2cc;">com.liferay.blogs</span></td>
<td>ADD_ENTRY</td>
</tr>
<tr>
<td>5218</td>
<td>blog_role</td>
<td><span style="background-color: #fff2cc;">scope=1</span>: liferayインスタンス<span style="background-color: #fff2cc;">20099</span>中の全て<span style="background-color: #fff2cc;">com.liferay.blogs.model.BlogsEntry</span></td>
<td>VIEW</td>
</tr>
<tr>
<td>5219</td>
<td>blog_role</td>
<td><span style="background-color: #fff2cc;">scope=4</span>: <span style="background-color: #fff2cc;">id=50893</span>の<span style="background-color: #fff2cc;">com.liferay.blogs.model.BlogsEntry</span>インスタンス</td>
<td>VIEW + UPDATE</td>
</tr>
</tbody>
</table>
<h4>
一般ロール x ポートレットリソース</h4>
<div>
<div>
続いて、以下の準備を行いましょう。</div>
<div>
<ul>
<li> <span style="background-color: #fff2cc;">blog_role</span>を開いて、権限定義に</li>
<ul>
<li><span style="background-color: #fff2cc;">アプリケーション権限/ページに追加する</span>権限を追加する</li>
</ul>
</ul>
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieuaTXseLUOhUCD1W1b02ZKEvojyPWNU6slNUsUBpkgKx05tgSOG-kjqT6Sf9uKz2Ukkerxry7p0IJfPYzovDWFLcAXvwDG7le_kPztj3lsgZ1blsMCz503OVGupaEruC4WNWZyhcqHm5Zo7-0xXOl9UrwallzErmjWx36uZEAn8kTLlNkcz4-q1lX/s959/blog_role_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="384" data-original-width="959" height="163" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieuaTXseLUOhUCD1W1b02ZKEvojyPWNU6slNUsUBpkgKx05tgSOG-kjqT6Sf9uKz2Ukkerxry7p0IJfPYzovDWFLcAXvwDG7le_kPztj3lsgZ1blsMCz503OVGupaEruC4WNWZyhcqHm5Zo7-0xXOl9UrwallzErmjWx36uZEAn8kTLlNkcz4-q1lX/w407-h163/blog_role_2.png" width="407" /></a></div>
<div>
<br /></div>
<div>
<ul>
<li>デフォルトサイトのブログポートレットに</li>
<ul>
<li>ポートレット権限設定を開いて<span style="background-color: #fff2cc;">blog_role</span>に<span style="background-color: #fff2cc;">設定</span>権限を追加する</li>
</ul>
</ul>
</div>
</div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0m3R5GEBm4JzpgJWS6bz2S1YkakGqxIXmnzwWtRPStLSaHFpSTyDVijRG43bwK8GPl_UA8jefAp2GpB0-LbtmHH5BezIHrtEAF-g3Zqmx61n6yzZTk8a1vg7xx3MpbWZF3Md6HruS-zCabG2Shwyx0kDb94Opwn-QpIlbKTIqU_A1GVF4rp0AiVSL/s926/blog_perm_portlet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="416" data-original-width="926" height="199" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0m3R5GEBm4JzpgJWS6bz2S1YkakGqxIXmnzwWtRPStLSaHFpSTyDVijRG43bwK8GPl_UA8jefAp2GpB0-LbtmHH5BezIHrtEAF-g3Zqmx61n6yzZTk8a1vg7xx3MpbWZF3Md6HruS-zCabG2Shwyx0kDb94Opwn-QpIlbKTIqU_A1GVF4rp0AiVSL/w442-h199/blog_perm_portlet.png" width="442" /></a></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
それ後、ロールとResourcePermissionテーブルで確認しましょう。</div>
<pre class="brush:sql">select resourcePermissionId, name, scope, primKey, primKeyId, roleId, actionIds from ResourcePermission where roleId = 50867;
</pre>
<br />
結果は以下の通りです(重複レコードを除外します)。<br />
<table>
<thead>
<tr>
<th>ID</th>
<th>リソース名</th>
<th>scope</th>
<th>primKey</th>
<th>primKeyId</th>
<th>roleId</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>5222</td>
<td>com_liferay_blogs_web_portlet_BlogsPortlet</td>
<td>1</td>
<td>20099</td>
<td>20099</td>
<td>50867</td>
<td>2</td>
</tr>
<tr>
<td>5223</td>
<td>com_liferay_blogs_web_portlet_BlogsPortlet</td>
<td>4</td>
<td>38656_LAYOUT_com_liferay_blogs_web_portlet_BlogsPortlet</td>
<td>0</td>
<td>50867</td>
<td>4</td>
</tr>
</tbody>
</table>
<br />
では、その結果はどのような権限を表すのかについて考察しましょう。<br />
<table>
<thead>
<tr>
<th>ID</th>
<th>ロール</th>
<th>どんなリソース</th>
<th>どの操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>5222</td>
<td>blog_role</td>
<td><span style="background-color: #fff2cc;">scope=1</span>: liferayインスタンス<span style="background-color: #fff2cc;">20099</span>中の全て<span style="background-color: #fff2cc;">BlogsPortlet</span></td>
<td>ADD_TO_PAGE</td>
</tr>
<tr>
<td>5219</td>
<td>blog_role</td>
<td><span style="background-color: #fff2cc;">scope=4</span>: <span style="background-color: #fff2cc;">id=38656</span>のレイアウト上の<span style="background-color: #fff2cc;">BlogsPortlet</span></td>
<td>CONFIGURATION</td>
</tr>
</tbody>
</table>
<h4>
まとめ</h4>
<div>
<div>
ここまでチェックすると、権限を与えられるリソースは三種類があることがわかりました。</div>
</div>
<div>
<ul>
<li>具体的なインスタンスを持っていないリソース</li>
<ul>
<li>そのモデルクラスは存在しないためインスタンス化できないため仮想モデルとして認識します。</li>
<ul>
<li>例:リソース<span style="background-color: #fff2cc;">com.liferay.blogs</span>はLiferayブログその概念を表すものと認識できます。</li>
</ul>
<li>そのリソースに与えられる権限は、具体的なブログエンティティに関係ありません。</li>
<ul>
<li>権限例:新規作成、パーミッション設定、ブログの購読</li>
</ul>
<li>特定できるインスタンスに適用しないため、scopeは<span style="background-color: #fff2cc;">4</span>になれません。</li>
<li><span style="background-color: #fff2cc;">primKey</span>は権限が適用される範囲の対象を表します。</li>
<ul>
<li><span style="background-color: #fff2cc;">scope=1</span>の場合、primKeyはliferayインスタンスIDです。</li>
</ul>
</ul>
<li>任意ある種類のインスタンス化可能なリソース</li>
<ul>
<li>対象は任意Liferayモデルまたはポートレット</li>
<ul>
<li>例:リソース<span style="background-color: #fff2cc;">com.liferay.blogs.model.BlogsEntry, scope=1</span>は全Liferayインスタンス中の任意Liferayブログを表し、そのリソースに与える権限は全Liferayインスタンス中のブログで有効となります。</li>
<li>例:リソース<span style="background-color: #fff2cc;">com_liferay_blogs_web_portlet_BlogsPortlet, scope=1</span>は全Liferayインスタンス中任意ブログポートレットを表し、そのリソースに与える権限は全Liferayインスタンス中のブログポートレットで有効となります。</li>
</ul>
<li>操作は具体的にインスタンスに対するアクションです。</li>
<ul>
<li>例:参照、更新、削除、コメント追加、ポートレット追加</li>
</ul>
<li>任意インスタンスに適応する権限のため、scopeは<span style="background-color: #fff2cc;">4</span>になれません。</li>
<li><span style="background-color: #fff2cc;">primKey</span>は権限が適用される範囲の対象を表します。</li>
<ul>
<li><span style="background-color: #fff2cc;">scope=1</span>の場合、primKey=LiferayインスタンスID</li>
</ul>
</ul>
<li>特定したリソース</li>
<ul>
<li>対象は任意Liferayモデルまたはポートレット</li>
<ul>
<li>例:リソース<span style="background-color: #fff2cc;">com.liferay.blogs.model.BlogsEntry, scope=4</span>は<span style="background-color: #fff2cc;">primKey</span>に指定するブログエンティティと認識します。その権限はその特定のブログエンティティのみで有効です。</li>
<li>例:リソース<span style="background-color: #fff2cc;">com_liferay_blogs_web_portlet_BlogsPortlet, scope=4</span>は<span style="background-color: #fff2cc;">primKey</span>に指定するブログポートレットと認識します。その権限はその特定のブログポートレットので有効です。</li>
</ul>
<li>操作は具体的にインスタンスに対するアクションです。</li>
<li><span style="background-color: #fff2cc;">primKey</span>は特定インスタンスのIDになります。</li>
<ul>
<li>モデルリソースの場合、<span style="background-color: #fff2cc;">primKey</span><span style="background-color: white;">=</span><span style="background-color: #fff2cc;">モデルID</span></li>
<li>ポートレットリソースの場合、<span style="background-color: #fff2cc;">primKey</span>=<span style="background-color: #fff2cc;">layoutId</span> + <span style="background-color: #fff2cc;">_LAYOUT_</span> + <span style="background-color: #fff2cc;">ポートレットキー</span></li>
</ul>
</ul>
</ul>
</div>
<div>
<div>
次回、サイトロールなどグループロールに与える権限を考察しようと思います。</div>
</div>
<div>
<br /></div>
<hr />
※ actionIdの内容は以下のsqlで取得できます。<br />
<pre class="brush:sql">select name, actionId, bitwiseValue from ResourceAction where name="com.liferay.blogs" and bitwiseValue = 2;
select name, actionId, bitwiseValue from ResourceAction where name="com.liferay.blogs.model.BlogsEntry" and (bitwiseValue = 1 or bitwiseValue=32);
select name, actionId, bitwiseValue from ResourceAction where name="com_liferay_blogs_web_portlet_BlogsPortlet " and (bitwiseValue = 2 or bitwiseValue = 4);
</pre>
<table><thead>
<tr><th>リソース名</th><th>操作</th><th>bitwiseValue</th></tr>
</thead><tbody>
<tr><td>com.liferay.blogs</td><td>ADD_ENTRY</td><td>2</td></tr>
<tr><td>com.liferay.blogs.model.BlogsEntry</td><td>VIEW</td><td>1</td></tr>
<tr><td>com.liferay.blogs.model.BlogsEntry</td><td>UPDATE</td><td>32</td></tr>
<tr><td>com_liferay_blogs_web_portlet_BlogsPortlet</td><td>ADD_TO_PAGE</td><td>2</td></tr>
<tr><td>com_liferay_blogs_web_portlet_BlogsPortlet</td><td>CONFIGURATION</td><td>4</td></tr>
</tbody></table>
<style>
table {
margin: 10px 0 15px 0;
border-collapse: collapse;
border-spacing: 0;
display: block;
width: 100%;
overflow: auto;
word-break: keep-all;
word-wrap: break-word;
border-top-color: gray;
}
thead {
display: table-header-group;
vertical-align: middle;
border-top-color: inherit;
border-right-color: inherit;
border-bottom-color: inherit;
border-left-color: inherit;
}
tr {
display: table-row;
vertical-align: inherit;
border-top-color: inherit;
border-right-color: inherit;
border-bottom-color: inherit;
border-left-color: inherit;
}
th {
border: 1px solid #d6d6d6;
padding: 6px 13px;
}
tbody {
display: table-row-group;
vertical-align: middle;
border-top-color: inherit;
border-right-color: inherit;
border-bottom-color: inherit;
border-left-color: inherit;
}
td {
border: 1px solid #d6d6d6;
padding: 6px 13px;
display: table-cell;
vertical-align: inherit;
}
</style>Min Wuhttp://www.blogger.com/profile/13688681791400596862noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-21854552878497364652020-05-01T12:07:00.002+09:002022-08-17T18:50:55.312+09:00Tomcat9をアップデートしたらWebサーバ(Apache)とAJP接続できなくなった話こんにちは。おおたにです。<br />
<br />
先日Tomcat9を最新バージョン(その時点では9.0.33)にアップデートしたところ、WebサーバとのAJP接続がうまくいかなくなったので、今回はその対処法を紹介します。<br />
<br />
<h3>
原因</h3>
<br />
<a href="https://www.jpcert.or.jp/at/2020/at200009.html" target="_blank">こちらの脆弱性</a>への対応のため、Tomcat 9.0.31でAJP1.3コネクタ設定が変更されたことが原因でした。具体的な変更点は<a href="http://tomcat.apache.org/tomcat-9.0-doc/changelog.html#Tomcat_9.0.31_(markt)" target="_blank">Tomcat 9.0.31のchangelog</a>にありますが、主なものは以下の3点です。<br />
<ul>
<li>AJPコネクタ(8009番ポートのやつ)がデフォルトでdisabledになった</li>
<li>バインドアドレスのデフォルトがIPv6ループバックアドレス(::1)になった</li>
<li>新しい属性<code>secretRequired</code>が追加され、デフォルトで<code>true</code>となっている(trueの場合、<code>secret</code>属性でシークレットキーを指定する必要がある)</li>
</ul>
<br />
以下、上記変更に対応するための設定方法です。今回はApache HTTP Serverを例に説明しますが、Apache HTTP Serverのバージョンにより設定が若干異なります。<br />
<br />
<h3>
Apache HTTP Server 2.4.43以降の場合</h3>
<br />
Tomcat側は、<code><TOMCAT_DIR>/conf/server.xml</code>でAJPコネクタのコメントアウトを外した後、以下のように設定します。<br />
<pre class="brush:xml"> <Connector protocol="AJP/1.3"
address="TomcatサーバのIPアドレス"
port="8009"
secret="シークレットキー"
redirectPort="8443" URIEncoding="UTF-8" />
</pre>
<ul>
<li>address : TomcatサーバのIPアドレス。複数のインタフェースが存在する場合はWebサーバとの通信に利用する方のIPアドレスを指定する。</li>
<li>secret : AJPコネクタのシークレットキー。</li>
</ul>
<br />
Apache HTTP Server側は、<code>ProxyPass</code>設定に<code>secret</code>パラメータを追加して先ほどと同じ値を指定します。<br />
<pre class="brush:bash">ProxyPass / ajp://TomcatサーバのIPアドレス/ secret=シークレットキー
</pre>
<br />
<h3>
Apache HTTP Server 2.4.41以前の場合</h3>
<br />
AJPコネクタのシークレットキーに対応できないため、Tomcat側で<code>secretRequired</code>を<code>false</code>に設定する必要があります。<br />
<pre class="brush:xml"> <Connector protocol="AJP/1.3"
address="TomcatサーバのIPアドレス"
port="8009"
secretRequired="false"
redirectPort="8443" URIEncoding="UTF-8" />
</pre>
Apache HTTP Server側は特に設定変更しなくてOKです。<br />
<br />
<br />
弊社ではLiferayやAlfrescoといったオープンソース製品のカスタマイズ/導入支援を行っておりますが、Tomcat/Apacheを使ってホストすることが多いためさっそくこの問題にあたりました。どうぞご参考まで。Tasuku Otanihttp://www.blogger.com/profile/18132336091954266906noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-28688444174762591392020-04-24T16:29:00.003+09:002022-08-17T18:53:10.556+09:00ユーザ、グループと組織の関係に役立つ便利なツール(その2)<a href="http://labo-blog.aegif.jp/2020/04/1.html">前回</a>、ユーザからユーザの所属または所有ロールを取得するための便利な<span style="background-color: #fff2cc;">UserBag</span>を紹介しました。今回は、その逆方向、組織の下の全てユーザ、あるロールにアサインした全てのユーザ、またはサイトメンバー全員を取る方法を紹介しようと思います。<br />
<br />
実は、Liferayのポータル機能として、ユーザ管理、ロール管理またはサイトメンバー一覧などの画面で、すでに上記機能が実装されていますが、その画面が利用したメソッドは、ポートレットからの呼び出しを前提としたシグネチャーを持っています(すなわち、<span style="background-color: #fff2cc;">PortletRequest</span>、<span style="background-color: #fff2cc;">HttpServletRequest</span>など)。 Liferayカスタマイズの際、サービスレイヤからそういう機能を実装する場面が多いため、今回の内容は、Liferayの既存機能の中の<span style="background-color: #fff2cc;">xxxRequest</span>などポートレット特化のパラメーターを利用しないこととします(すなわち本来<span style="background-color: #fff2cc;">xxxRequest</span>から作成したものをハードコードで作成する)。<br />
<br />
<h4>
UserSearch</h4>
<div>
<div>
Liferayの<span style="background-color: #fff2cc;">UsersAdminPortlet</span>または<span style="background-color: #fff2cc;">SiteMembershipsPortlet</span>のユーザリスト部分を確認すると<a href="https://github.com/liferay/liferay-portal/blob/master/modules/apps/users-admin/users-admin-web/src/main/java/com/liferay/users/admin/web/internal/display/context/ViewUsersManagementToolbarDisplayContext.java">ユーザ管理のViewUsersManagementToolbarDisplayContext.java</a>または<a href="https://github.com/liferay/liferay-portal/blob/master/modules/apps/site/site-memberships-web/src/main/java/com/liferay/site/memberships/web/internal/display/context/UsersDisplayContext.java">サイトメンバー管理のUsersDisplayContext.java</a>、よく<span style="background-color: #fff2cc;">UserSearch</span>というクラスを見ます。さらに、Liferayには、階層構造を用いてデータベースの検索よりサーチエンジンの検索が早いことを利用し、指定条件のユーザを取得できるメソッドが用意されています。</div>
</div>
<div>
<br /></div>
<pre class="brush:java">// UsersDisplayContext.java
UserSearch userSearch = new UserSearch(_renderRequest, getPortletURL());
UserSearchTerms searchTerms =
(UserSearchTerms)userSearch.getSearchTerms();
LinkedHashMap<string object=""> userParams = new LinkedHashMap<>();
userParams.put("inherit", Boolean.TRUE);
userParams.put("usersGroups", Long.valueOf(getGroupId()));
int usersCount = UserLocalServiceUtil.searchCount(
themeDisplay.getCompanyId(), searchTerms.getKeywords(),
searchTerms.getStatus(), userParams);
userSearch.setTotal(usersCount);
List<user> users = UserLocalServiceUtil.search(
themeDisplay.getCompanyId(), searchTerms.getKeywords(),
searchTerms.getStatus(), userParams, userSearch.getStart(),
userSearch.getEnd(), userSearch.getOrderByComparator());
userSearch.setResults(users);
</user></string></pre>
そして、<a href="https://github.com/liferay/liferay-portal/blob/master/portal-impl/src/com/liferay/portlet/usersadmin/search/UserSearch.java">UserSearch.java</a>、<a href="https://github.com/liferay/liferay-portal/blob/master/portal-impl/src/com/liferay/portlet/usersadmin/search/UserSearchTerms.java">UserSearchTerms.java</a>などのソースを参照し、以下のようなサービスレイヤ向け<span style="background-color: #fff2cc;">UserSearch</span>が作成できます。<br />
<ul>
<li><span style="background-color: #fff2cc;">searchTerms.getKeywords()</span>のデフォルト値は<span style="background-color: #fff2cc;">null</span>になる</li>
<li>ユーザ全体を取りたい場合、<span style="background-color: #fff2cc;">start=0</span>、<span style="background-color: #fff2cc;">end=総数</span>を指定する</li>
<li><span style="background-color: #fff2cc;">userSearch.getOrderByComparator()</span>のデフォルト値は<span style="background-color: #fff2cc;">UsersAdminUtil.getUserOrderByComparator("last-name", "asc")</span>になる</li>
</ul>
<pre class="brush:java">Component(
property = {
"osgi.command.scope=liferay",
"osgi.command.function=checkOrganizationUsers",
"osgi.command.function=checkSiteUsers",
"osgi.command.function=checkRoleUsers"
},
service = SiteUserOrgCmd.class
)
public class SiteUserOrgCmd {
private static final long companyId = PortalUtil.getDefaultCompanyId();
public void checkOrganizationUsers(String orgName) throws Exception {
Organization org = OrganizationLocalServiceUtil.getOrganization(companyId, orgName);
LinkedHashMap<string object=""> userParams = new LinkedHashMap<string object="">();
userParams.put("inherit", Boolean.TRUE);
userParams.put("usersOrgs", org.getOrganizationId());
int usersCount = UserLocalServiceUtil.searchCount(companyId, StringPool.BLANK, WorkflowConstants.STATUS_APPROVED, userParams);
OrderByComparator<user> obc = UsersAdminUtil.getUserOrderByComparator("last-name", "asc");
List<user> res = UserLocalServiceUtil.search(companyId, StringPool.BLANK, WorkflowConstants.STATUS_APPROVED, userParams, 0, usersCount, obc);
System.out.println("Users of organization " + orgName + ": ");
for (User u : res) {
System.out.println(" " + u.getScreenName());
}
}
public void checkSiteUsers(String siteName) throws Exception {
Group grp = null;
for (Group g : GroupLocalServiceUtil.getGroups(QueryUtil.ALL_POS, QueryUtil.ALL_POS)) {
if (g.getName(Locale.getDefault()).equals(siteName)) {
grp = g;
break;
}
}
LinkedHashMap<string object=""> userParams = new LinkedHashMap<string object="">();
userParams.put("inherit", Boolean.TRUE);
userParams.put("usersGroups", grp.getGroupId());
int usersCount = UserLocalServiceUtil.searchCount(companyId, StringPool.BLANK, WorkflowConstants.STATUS_APPROVED, userParams);
OrderByComparator<user> obc = UsersAdminUtil.getUserOrderByComparator("last-name", "asc");
List<user> res = UserLocalServiceUtil.search(companyId, StringPool.BLANK, WorkflowConstants.STATUS_APPROVED, userParams, 0, usersCount, obc);
System.out.println("Users of site " + siteName + ": ");
for (User u : res) {
System.out.println(" " + u.getScreenName());
}
}
public void checkRoleUsers(String roleName) throws Exception {
Role role = RoleLocalServiceUtil.getRole(companyId, roleName);
LinkedHashMap<string object=""> userParams = new LinkedHashMap<string object="">();
userParams.put("inherit", Boolean.TRUE);
userParams.put("usersRoles", role.getRoleId());
int usersCount = UserLocalServiceUtil.searchCount(companyId, StringPool.BLANK, WorkflowConstants.STATUS_APPROVED, userParams);
OrderByComparator<user> obc = UsersAdminUtil.getUserOrderByComparator("last-name", "asc");
List<user> res = UserLocalServiceUtil.search(companyId, StringPool.BLANK, WorkflowConstants.STATUS_APPROVED, userParams, 0, usersCount, obc);
System.out.println("Users of site " + roleName + ": ");
for (User u : res) {
System.out.println(" " + u.getScreenName());
}
}
}
</user></user></string></string></user></user></string></string></user></user></string></string></pre>
<br />
<h4>
検証</h4>
<br />
前回と同じ、検証用エンティティを作成しましょう。<br />
<br />
<ul>
<li>ユーザ: <span style="background-color: #fff2cc;">ub_user</span>, <span style="background-color: #fff2cc;">ub_user2</span>, <span style="background-color: #fff2cc;">ub_user3</span></li>
<li>ユーザグループ: <span style="background-color: #fff2cc;">ub_grp</span></li>
<li>組織: <span style="background-color: #fff2cc;">ub_org</span></li>
<ul>
<li><span style="background-color: #fff2cc;">ub_org</span>の下の階層に<span style="background-color: #fff2cc;">ob_org1</span>を作成する</li>
</ul>
<li>サイト: <span style="background-color: #fff2cc;">ub_site</span></li>
<li>一般ロール: <span style="background-color: #fff2cc;">ub_role</span></li>
</ul>
<br />
では、上記サービスで<span style="background-color: #fff2cc;">UserSearch</span>の効果を検証しましょう。<br />
<br />
<h4>
組織</h4>
<ul>
<li> <span style="background-color: #fff2cc;">ub_org</span> <- <span style="background-color: #fff2cc;">ub_user2</span>、<span style="background-color: #fff2cc;">ub_org1</span> <- <span style="background-color: #fff2cc;">ub_user3</span></li>
</ul>
<pre class="brush:html">g! checkSiteUsers ub_site
Users of site ub_site:
test
ub_user
ub_user3
ub_user2
</pre>
<br />
<ul>
<li>前回同様、dxp-14パッチまでのLiferayには、<span style="background-color: #fff2cc;">ub_user3</span>を直接に<span style="background-color: #fff2cc;">ub_org</span>にアサインしなくで、その下の<span style="background-color: #fff2cc;">ub_org1</span>にアサインすると、<span style="background-color: #fff2cc;">ub_user3</span>は<span style="background-color: #fff2cc;">ub_site</span>のサイトメンバーとして認識できなくなります。</li>
</ul>
<br />
<h4>
ロール</h4>
<div>
<div>
<span style="background-color: #fff2cc;">ub_role</span>を:</div>
<div>
<ul>
<li><span style="background-color: #fff2cc;">ub_user</span>にアサインする</li>
<li><span style="background-color: #fff2cc;">ub_grp</span>にアサインし、<span style="background-color: #fff2cc;">ub_user2</span>を<span style="background-color: #fff2cc;">ub_grp</span>にアサインする</li>
<li><span style="background-color: #fff2cc;">ub_org</span>にアサインし、<span style="background-color: #fff2cc;">ub_user3</span>を<span style="background-color: #fff2cc;">ub_org</span>にアサインする</li>
</ul>
</div>
</div>
<pre class="brush:html">g! checkRoleUsers ub_role
Users of site ub_role:
ub_user
ub_user3
ub_user2</pre>
<br />
<h4>
まとめ</h4>
<div>
<div>
今回、Liferayが提供する<span style="background-color: #fff2cc;">UserSearch</span>を利用し、サイト、組織またはロールの所属ユーザを全部取得する方法を紹介しました。実は、<span style="background-color: #fff2cc;">UserSearch</span>だけではなく、<a href="https://github.com/liferay/liferay-portal/blob/master/portal-impl/src/com/liferay/portlet/rolesadmin/search/RoleSearch.java">RoleSearch</a>、<a href="https://github.com/liferay/liferay-portal/blob/master/portal-impl/src/com/liferay/portlet/usergroupsadmin/search/UserGroupSearch.java">UserGroupSearch</a>、<a href="https://github.com/liferay/liferay-portal/blob/master/portal-impl/src/com/liferay/portlet/usersadmin/search/GroupSearch.java">GroupSearch</a>などの<span style="background-color: #fff2cc;">search</span>系メソッドがLiferay中に定義されています。このようなクラスを同じ手段で改造したら、サービスレイヤであるエンティティーの下のロール、ユーザグループの取得も可能になります。</div>
</div>
<div>
<br /></div>
Min Wuhttp://www.blogger.com/profile/13688681791400596862noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-71823402220335849332020-04-21T13:21:00.001+09:002022-08-17T18:53:32.539+09:00ユーザ、グループと組織の関係に役立つ便利なツール(その1)Liferayカスタマイズのビジネスロジックに、以下のような処理がよくあると思います。<br />
<br />
<br />
<ul>
<li>ユーザにアサインしたロールを取得する</li>
<li>ユーザの所属組織を取得する</li>
<li>ユーザの所属サイトを取得する</li>
<li>組織に所属するユーザを取得する</li>
<li>サイトのサイトメンバーを取得する</li>
<li>など...</li>
</ul>
<br />
<br />
みなさまはこのような処理を行う時、<span style="background-color: #fff2cc;">userLocalService.getGroupUsers</span>(グループのユーザを取る)、<span style="background-color: #fff2cc;">organizationLocalService.getUserOrganizations</span>(ユーザが所属する組織を取得)などのメソッドをよく利用しますか?実は、これは間違っています。<br />
<br />
その原因は、Liferayのサービスから取得できるものは、データベースの中に直接存在するレコードのみです。ただし、組織、サイトは階層構造のため、ユーザがサイトに所属する際、ユーザ-サイトに直接関連するデータベースレコードが存在しないこともできます(例えば、ユーザが所属するユーザグループがサイトメンバとしてサイトにアサインすることができます)。<br />
<br />
そのため、データベース上直接関連がないエンティティを取るため、再帰的に階層構造をトラバースしないといけません。そこで、Liferayは階層構造を配慮した便利なツールを提供しています。<br />
<br />
今回はユーザからユーザの所属サイト、ユーザグループ、組織またはユーザにアサインしたロールを取るツールを紹介したいと思います。次回は逆方向でサイト、ユーザグループ、組織から所属ユーザを取るツールです。<br />
<br />
<h4>
UserBag</h4>
以下のコードでUserBagが作成できます。<br />
<br />
<pre class="brush:java">UserBag userBag = UserBagFactoryUtil.create(userId);
</pre>
<br />
作成された<span style="background-color: #fff2cc;">UserBag</span>を利用し、以下の処理を行えます。<br />
<br />
<ul>
<li><span style="background-color: #fff2cc;">userBag.getRoles()</span></li>
<ul>
<li>ユーザにアサインしたロールを取得する。</li>
</ul>
<li><span style="background-color: #fff2cc;">userBag.getUserUserGroupIds()</span></li>
<ul>
<li>ユーザが所属するユーザグループのIDを取得する</li>
</ul>
<li><span style="background-color: #fff2cc;">userBag.getUserOrgs()</span></li>
<ul>
<li>ユーザが所属する組織を取得する。</li>
</ul>
<li><span style="background-color: #fff2cc;">userBag.getUserGroups()</span></li>
<ul>
<li>ユーザが所属するサイトを取得する。</li>
</ul>
<li><span style="background-color: #fff2cc;">userBag.getGroups()</span></li>
<ul>
<li>ユーザが所属するグループを取得する。</li>
</ul>
</ul>
※ Liferayには、ユーザグループ、サイトと組織その三つのエンティティに全部<span style="background-color: #fff2cc;">group</span>と関連しています。そのため、<span style="background-color: #fff2cc;">getUserGroups()</span>メソッドはユーザグループではなく、ユーザの所属グループをリターンします。<br />
※ 実に、ユーザグループと組織に繋がる<span style="background-color: #fff2cc;">group</span>は、ユーザグループまたは組織のプロファイルページと見られます。<br />
<br />
<h4>
検証</h4>
さて、Liferayを起動して<span style="background-color: #fff2cc;">UserBag</span>の効果を検証しましょう。ひとまず、検証用モジュールを作りましょう。<br />
<br />
<pre class="brush:java">@Component(
property = {
"osgi.command.scope=liferay",
"osgi.command.function=checkUserOrganizations",
"osgi.command.function=checkUserSites",
"osgi.command.function=checkUserRoles"
},
service = SiteUserOrgCmd.class
)
public class SiteUserOrgCmd {
private static final long companyId = PortalUtil.getDefaultCompanyId();
public void checkUserOrganizations(String screenName) throws Exception {
User user = UserLocalServiceUtil.getUserByScreenName(companyId, screenName);
UserBag userBag = UserBagFactoryUtil.create(user.getUserId());
System.out.println("User's organizations in userBag: ");
for (Organization org : userBag.getUserOrgs()) {
System.out.println(" " + org.getName());
}
System.out.println("User's organizations in service: ");
for (Organization org : OrganizationLocalServiceUtil.getUserOrganizations(user.getUserId())) {
System.out.println(" " + org.getName());
}
}
public void checkUserSites(String screenName) throws Exception {
User user = UserLocalServiceUtil.getUserByScreenName(companyId, screenName);
UserBag userBag = UserBagFactoryUtil.create(user.getUserId());
System.out.println("User's sites: ");
for (Group grp : userBag.getUserGroups()) {
System.out.println(" " + grp.getName(Locale.getDefault()));
}
System.out.println("User's sites in service: ");
for (Group grp : GroupLocalServiceUtil.getUserGroups(user.getUserId(), true)) {
System.out.println(" " + grp.getName(Locale.getDefault()));
}
}
public void checkUserRoles(String screenName) throws Exception {
User user = UserLocalServiceUtil.getUserByScreenName(companyId, screenName);
UserBag userBag = UserBagFactoryUtil.create(user.getUserId());
System.out.println("User's roles: ");
for (Role r : userBag.getRoles()) {
System.out.println(" " + r.getName());
}
System.out.println("User's roles in service: ");
for (Role r : RoleLocalServiceUtil.getUserRoles(user.getUserId())) {
System.out.println(" " + r.getName());
}
}
}
</pre>
<br />
※ Liferayユーザグループが階層構造になれないため、検証内容から外します。<br />
<br />
続いて、検証用エンティティを用意します。<br />
- ユーザ: <span style="background-color: #fff2cc;">ub_user</span><br />
- ユーザグループ: <span style="background-color: #fff2cc;">ub_grp</span><br />
- 組織: <span style="background-color: #fff2cc;">ub_org</span><br />
- 階層組織: <span style="background-color: #fff2cc;">ub_org/ub_org1</span><br />
- サイト: <span style="background-color: #fff2cc;">ub_site</span><br />
- 一般ロール: <span style="background-color: #fff2cc;">ub_role</span><br />
<br />
それては、gogo shellで<span style="background-color: #fff2cc;">UserBag</span>の効果を検証しましょう。<br />
※ 検証中、明記以外の場合、「検証の度にユーザ、ロール、サイトと組織の関係を元に戻す」を前提として検証操作をします。<br />
<br />
<h4>
組織</h4>
以下の状況を考えてみましょう。<br />
<ul>
<li> <span style="background-color: #fff2cc;">ub_org</span> <- <span style="background-color: #fff2cc;">ub_user</span></li>
<ul>
<li><span style="background-color: #fff2cc;">ub_org</span>は階層構造中一番トップな組織ため、<span style="background-color: #fff2cc;">UserBag</span>と<span style="background-color: #fff2cc;">OrganizationLocalService</span>の戻り値は同じです。</li>
</ul>
</ul>
<pre class="brush:html">g! checkUserOrganizations ub_user
User's organizations in userBag:
ub_org
User's organizations in service:
ub_org
</pre>
<br />
<ul>
<li><span style="background-color: #fff2cc;">ub_org1</span><span style="background-color: transparent;"> <- </span><span style="background-color: #fff2cc;">ub_user</span></li>
<ul>
<li> <span style="background-color: #fff2cc;">ub_org1</span>は<span style="background-color: #fff2cc;">ub_org</span>の一個下の階層の組織のため、ユーザが直接に<span style="background-color: #fff2cc;">ub_org1</span>のユーザとして追加すると、<span style="background-color: #fff2cc;">OrganizationLocalService</span>はDBに直接存在するレコード<span style="background-color: #fff2cc;">ub_org1</span>をリターンします。それに対して、<span style="background-color: #fff2cc;">UserBag</span>は階層構造の上の組織ub_orgもリターンします。</li>
</ul>
</ul>
<pre class="brush:html">g! checkUserOrganizations ub_user
User's organizations in userBag:
ub_org
ub_org1
User's organizations in service:
ub_org1</pre>
<br />
<h4>
サイト</h4>
以下の状況を考えてみましょう。<br />
<ul>
<li><span style="background-color: #fff2cc;">ub_site</span> <- <span style="background-color: #fff2cc;">ub_user</span></li>
<ul>
<li>ユーザが直接にサイトメンバーとしてサイトへ登録すると、<span style="background-color: #fff2cc;">UserBag</span>と<span style="background-color: #fff2cc;">GroupLocalService</span>の出力が同じです。</li>
</ul>
</ul>
g! checkUserSites ub_user<br />
<pre class="brush:html">User's sites:
ub_site
User's sites in service:
ub_site
</pre>
<br />
<ul>
<li><span style="background-color: #fff2cc;">ub_site</span> <- <span style="background-color: #fff2cc;">ub_grp</span>, <span style="background-color: #fff2cc;">ub_grp</span> <- <span style="background-color: #fff2cc;">ub_user</span></li>
<ul>
<li>ユーザが直接にサイトへ登録ではなく、ユーザグループに通じでサイトメンバーへ登録際、<span style="background-color: #fff2cc;">UserBag</span>と<span style="background-color: #fff2cc;">GroupLocalService</span>の出力が同じです。</li>
</ul>
<li>最初に「あれ?」と思う方がいらっしゃいませんか?</li>
<ul>
<li>実は、<span style="background-color: #fff2cc;">GroupLocalServiceUtil.getUserGroups(long userId, boolean inherit))</span>のパラメーターとして<span style="background-color: #fff2cc;">inherit=true</span>を指定したら、<span style="background-color: #fff2cc;">GroupLocalService</span>でも<span style="background-color: #fff2cc;">UserBag</span>のような出力ができます。</li>
</ul>
</ul>
<pre class="brush:html">g! checkUserSites ub_user
User's sites:
ub_site
User's sites in service:
ub_site
</pre>
<br />
<ul>
<li><span style="background-color: #fff2cc;">ub_site</span> <- <span style="background-color: #fff2cc;">ub_org</span>, <span style="background-color: #fff2cc;">ub_org</span> <- <span style="background-color: #fff2cc;">ub_user</span></li>
<ul>
<li>ユーザが直接にサイトへ登録ではなく、ユーザグループに通じでサイトメンバーへ登録際、<span style="background-color: #fff2cc;">UserBag</span>と<span style="background-color: #fff2cc;">GroupLocalService</span>の出力が同じです。</li>
<li>理由はユーザグループの場合と同じです。</li>
<li>ちなみに、組織サイトも結果に入りました。</li>
</ul>
</ul>
<pre class="brush:html">g! checkUserSites ub_user
User's sites:
ub_org
ub_site
User's sites in service:
ub_org
ub_site
</pre>
<br />
<br />
<ul>
<li>※ <span style="background-color: #fff2cc;">ub_site</span> <- <span style="background-color: #fff2cc;">ub_org</span>, <span style="background-color: #fff2cc;">ub_org1</span> <- <span style="background-color: #fff2cc;">ub_user</span></li>
<ul>
<li>ちょっと変な結果ですが、<span style="background-color: #fff2cc;">ub_user</span>を直接に組織<span style="background-color: #fff2cc;">ub_org</span>の下に置かなくて、<span style="background-color: #fff2cc;">ub_org</span>下の<span style="background-color: #fff2cc;">ub_org1</span>にアサインしたとき、<span style="background-color: #fff2cc;">ub_user</span>は<span style="background-color: #fff2cc;">ub_site</span>のサイトメンバーとして認識されないようです。</li>
<li>これはLiferayの仕様(liferay-7.1-sp2, dxp-14-7110まで)だそうです(サイトメンバー管理画面にも同じ結果が確認できます)。</li>
</ul>
</ul>
<pre class="brush:html">g! checkUserSites ub_user
User's sites:
ub_org1
User's sites in service:
ub_org1
</pre>
<br />
<h4>
ロール</h4>
以下の状況を考えてみましょう。<br />
<ul>
<li><span style="background-color: #fff2cc;">ub_role</span> <- <span style="background-color: #fff2cc;">ub_user</span></li>
<ul>
<li>ユーザが直接にロールをアサインするとき、<span style="background-color: #fff2cc;">UserBag</span>と<span style="background-color: #fff2cc;">RoleLocalService</span>の出力が同じです。</li>
</ul>
</ul>
<pre class="brush:html">g! checkUserRoles ub_user
User's roles:
User
ub_role
User's roles in service:
User
ub_role
</pre>
<br />
<ul>
<li><span style="background-color: #fff2cc;">ub_role</span> <- <span style="background-color: #fff2cc;">ub_grp</span>, <span style="background-color: #fff2cc;">ub_grp</span> <- <span style="background-color: #fff2cc;">ub_user</span></li>
<ul>
<li>ユーザがユーザグループを通じてユ<span style="background-color: #fff2cc;">ub_role</span>にアサインされるとき、データベースにレコードがいないため、<span style="background-color: #fff2cc;">UserBag</span>と<span style="background-color: #fff2cc;">RoleLocalService</span>の出力が違います。</li>
</ul>
</ul>
<pre class="brush:html">g! checkUserRoles ub_user
User's roles:
User
ub_role
User's roles in service:
User
</pre>
<br />
<ul>
<li><span style="background-color: #fff2cc;">ub_role</span> <- <span style="background-color: #fff2cc;">ub_org</span>, <span style="background-color: #fff2cc;">ub_org1</span> <- <span style="background-color: #fff2cc;">ub_user</span></li>
<ul>
<li>ユーザが組織を通じてユub_roleにアサインされるとき、データベースにレコードがいないため、<span style="background-color: #fff2cc;">UserBag</span>と<span style="background-color: #fff2cc;">RoleLocalService</span>の出力が違います。</li>
<li><span style="background-color: #fff2cc;">ub_org1</span>は階層構造上<span style="background-color: #fff2cc;">ub_org</span>の下の階層のため、ユーザは<span style="background-color: #fff2cc;">ub_role</span>を持っています。</li>
</ul>
</ul>
<pre class="brush:html">g! checkUserRoles ub_user
User's roles:
User
ub_role
User's roles in service:
User
</pre>
<br />
<h4>
まとめ</h4>
今回は、Liferayが提供した<span style="background-color: #fff2cc;">UserBag</span>を利用し、ユーザから当該ユーザの所属とロールを取得する方法を紹介しました。<span style="background-color: #fff2cc;">UserBag</span>はLiferayの階層構造を配慮して結果をリターンするため、カスタマイズの際役に立つでしょう。また、公式github上のソースコードを参考すると、UserBagをより深く理解できますので(<a href="https://github.com/liferay/liferay-portal/blob/master/portal-impl/src/com/liferay/portal/security/permission/UserBagImpl.java">UserBagImpl</a>, <a href="https://github.com/liferay/liferay-portal/blob/master/portal-impl/src/com/liferay/portal/security/permission/UserBagFactoryImpl.java">UserBagFactoryImpl</a>)、ぜひおすすめします。<br />
<br />
ちなみに、<span style="background-color: #fff2cc;">UserBag</span>の定義はLiferayのkernelモジュールである<span style="background-color: #fff2cc;">com.liferay.portal.security.permission</span>の中にあり、Liferayの<span style="background-color: #fff2cc;">permissionChecker</span>はよくこのクラスを利用しています。これは本来<span style="background-color: #fff2cc;">UserBag</span>を開発する理由でしょう。
<br />Min Wuhttp://www.blogger.com/profile/13688681791400596862noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-41191387919792834862020-04-15T11:23:00.001+09:002022-08-17T18:54:31.877+09:00Alfresco Content Applicationを使ってみようこんにちは。てらしたです。<br />
<br />
今回はAlfrescoの新しいUIとして開発されているAlfresco Content Applicationをご紹介します。Alfresco Content Applicationは、Alfresco Development Framework(ADF)を使って開発されており、Alfresco上のコンテンツの操作に特化したUIとなっています。<a href="https://github.com/Alfresco/alfresco-content-app/tree/development/docs/features" target="_blank">GitHubのページ</a>に記載されているコンセプトがわかりやすかったので引用しておきます。<br />
<blockquote class="tr_bq">
The concept of this application is a simple user interface which makes accessing files in the Alfresco Content Services repository easy.<br />
Often Content Management systems provide more capabilities out of the box than most users need; providing too many capabilities to these users prevents them from working efficiently, so they may end up using unsanctioned file management solutions which presents a proliferation of content storage and collaboration solutions as well as compliance issues for organizations.<br />
This application simplifies the complexity of Content Management and provides comprehensive extensibility features for developers, using the Alfresco Application Development Framework, to easily and quickly create custom solutions for specific user cases.</blockquote>
Alfrescoは3.x以降、Alfresco Shareを標準のUIとして新機能の実装や既存機能の改善が行われてきました。その結果、機能が多くなり過ぎて全部乗せのようなUIになってしまっています。ダッシュボード、ブログ、Wiki、カレンダーやワークフローは使わず、コンテンツ管理機能だけ使いたいという場合にはShareではtoo muchなので、Alfresco Content Applicationをカスタマイズして使うというケースが今後増えてくるのではないかと思います。<br />
<br />
前置きが長くなりましたが、Alfresco Content Applicationを起動する手順をご紹介します。準備さえできてしまえば本当に簡単に起動できます。<br />
まず準備として、最新のAlfrescoをインストールして起動します。現時点(2020年4月)では201911GAが最新のGA版なので、例えば<a href="http://labo-blog.aegif.jp/2020/03/alfresco-community-edition.html" target="_blank">こちらの記事</a>を参考にしてもらえればと思います。<br />
次に、Node.jsのLTS版(現時点ではv10かv12)をインストールします。以上で準備は完了です。<br />
あとは、GitHubのプロジェクトをcloneして依存モジュールをインストールして起動するだけです。
<br />
<pre class="brush:bash">git clone https://github.com/Alfresco/alfresco-content-app.git
cd alfresco-content-app
npm install
npm start
</pre>
<br />
起動したら自動的にブラウザでログイン画面が開くはずですが、開かない場合は以下のURLを手動で開いてみてください。
<br />
<br />
<a href="http://localhost:4200/">http://localhost:4200/</a><br />
<br />
ログインしてサンプルサイトの文書ライブラリを開くと以下のようにフォルダやファイルにアクセスできると思います。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQNTjhV7eBqxvNivFskFo1PwVMIZt5GFmQnHZb3hHwt4lzvIi7923cFP8D66qoOgC_zGznCSy1EhuUZ_dW4-W-SbK-cmAuJgF4Zlpo84Z1FptQC8bAyHsbSKhNp8TJLOpadiCqxohcbxhinMji4HtOuV4JvjaL7iedtjFiVeJhC5DH6lKu-F9EE69q/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-03-27%2011.03.53.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1028" data-original-width="1600" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQNTjhV7eBqxvNivFskFo1PwVMIZt5GFmQnHZb3hHwt4lzvIi7923cFP8D66qoOgC_zGznCSy1EhuUZ_dW4-W-SbK-cmAuJgF4Zlpo84Z1FptQC8bAyHsbSKhNp8TJLOpadiCqxohcbxhinMji4HtOuV4JvjaL7iedtjFiVeJhC5DH6lKu-F9EE69q/w386-h248/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202020-03-27%2011.03.53.png" width="386" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<br />
少し使ってみていただければ、コンテンツ操作に特化していてShareに比べてかなりシンプルなUIになっていることがわかるのではないかと思います。<br />
コンテンツ操作に関しては、ファイル/フォルダのアップロードや検索もできますし、新規ボタンから「ライブラリの作成」でサイトを新規に作ってその文書ライブラリにアクセスすることもできます。ただ、サイトメンバーの管理はできないようなので、今のところはそれはShareからやるしかなさそうです。Jun Terashitahttp://www.blogger.com/profile/09039721862238185320noreply@blogger.com0tag:blogger.com,1999:blog-3274102168139802613.post-4691663911803345822020-03-31T15:53:00.001+09:002022-08-18T11:03:18.960+09:00Liferay DXP 7.1 言語リソースカスタマイズの共有こんにちは、うです。<br />
<br />
<a href="http://labo-blog.aegif.jp/2020/03/liferay-dxp-7.html">前回</a>、Liferay DXP 7でのカスタイムモジュール(ポートレット)の言語リソースを他モジュールに共有する方法を紹介しました。今回は、Liferay DXP 7.1以降、既存モジュール言語リソースに対するカスタマイズを複数既存モジュールに適用する方法を紹介します。<br />
<br />
みなさまはすでにご存知かもしれませんが、Liferay DXP 7.1から、モジュール言語リソースのカスタマイズ方式は従来の<a href="https://portal.liferay.dev/docs/7-0/tutorials/-/knowledge_base/t/overriding-language-keys">OSGI-Service方式</a>から<a href="https://portal.liferay.dev/docs/7-1/tutorials/-/knowledge_base/t/overriding-a-modules-language-keys">OSGI-Capability方式</a>になりました。従って、<a href="https://bnd.bndtools.org/heads/provide_capabaility.html">bnd-tools Provide-Capability</a>のみで、複数モジュールが同じ言語リソースカスタマイズを利用できます。<br />
<br />
公式例:<br />
<pre class="brush:html">Provide-Capability:\
liferay.resource.bundle;\
resource.bundle.base.name="content.Language",\
liferay.resource.bundle;\
resource.bundle.aggregate:String="(bundle.symbolic.name=com.liferay.docs.l10n.myapp.lang),\
(bundle.symbolic.name=com.liferay.blogs.web)";\
bundle.symbolic.name=com.liferay.blogs.web;\
resource.bundle.base.name="content.Language";\
service.ranking:Long="2";\
servlet.context.name=blogs-web
</pre>
<br />
複数カスタマイズ共有(例として、<span style="background-color: #fff2cc;">blogs-web</span>と<span style="background-color: #fff2cc;">product-navigbation-control-menu-web</span>を対象にする)例。<br />
<br />
<pre class="brush:html">Provide-Capability:\
liferay.resource.bundle;\
resource.bundle.base.name="content.Language",\
liferay.resource.bundle;\
resource.bundle.aggregate:String="(bundle.symbolic.name=com.liferay.docs.l10n.myapp.lang),\
(bundle.symbolic.name=com.liferay.blogs.web)";\
bundle.symbolic.name=com.liferay.blogs.web;\
resource.bundle.base.name="content.Language";\
service.ranking:Long="2";\
servlet.context.name=blogs-web
liferay.resource.bundle;\
resource.bundle.aggregate:String="(bundle.symbolic.name=com.liferay.docs.l10n.myapp.lang),\
(bundle.symbolic.name=com.liferay.product.navigation.control.menu.web)";\
bundle.symbolic.name=com.liferay.product.navigation.control.menu.web;\
resource.bundle.base.name="content.Language";\
service.ranking:Long="2";\
servlet.context.name=product-navigation-control-menu-web
</pre>
<br />
まとめると、Liferay DXP 7.1にでの言語リソース定義は、以下のルールに従いましょう。<br />
<br />
<ul>
<li> <span style="background-color: #fff2cc;">bnd.bnd</span>に<span style="background-color: #fff2cc;">Provide-Capability</span>を追加する</li>
<li> <span style="background-color: #fff2cc;">Provide-Capability</span>に以下のディレクティブを追加する</li>
<ol>
<li><span style="background-color: #fff2cc;">liferay.resource.bundle;resource.bundle.base.name=...</span>: 言語キー所在パッケージパスを定義する</li>
<li><span style="background-color: #fff2cc;">liferay.resource.bundle;resource.bundle.aggregate...</span>: カスタム対象モジュールを宣言する</li>
<li>複数の対象モジュールがある場合、上記2のディレクテイブを複数記入する</li>
<li>全てディレクテイブはコンマ<span style="background-color: #fff2cc;">,</span>で区切る</li>
</ol>
</ul>
<br />Min Wuhttp://www.blogger.com/profile/13688681791400596862noreply@blogger.com0