6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NTTデータイントラマートAdvent Calendar 2020

Day 25

【intra-mart】[IM-FormaDesigner]別のFormaアプリで添付したファイルをダウンロードURL付きで取得する方法

Last updated at Posted at 2020-12-26

今日の時点でもう期間が過ぎてしまっているのですが、はじめてAdvent Calendarの記事を投稿します。

  • NTTデータイントラマート Advent Calendar 2020

やりたかったこと

あるFormaアプリ(A)でアップロードしたファイル一覧を、別のFormaアプリ(B)のグリッドテーブルでダウンロードしたり、選択したりしたかったのです。
JavaEE開発モデルやスクリプト開発モデルを用いて専用の画面を作成すれば、すぐに実現可能と思われるのですが、それだとシステム停止を伴うデプロイ作業が発生してしまいます。システム停止調整となると・・・社内事情やユーザ事情などいろんなことがあり、それだけは避けなければならない・・・。
したがってIM-FormaDesignerなど、デプロイを伴わない機能だけで要件を満たし、迅速に対応する必要がありました。

  • IM-FormaアプリAで添付ファイルをアップロード
  • IM-FormaアプリB側で、A側のファイルを取得し、ダウンロードURLを生成
  • これをJava開発モデルやスクリプト開発モデルではなく、warファイル差し替えを行わずデプロイを伴わない下記の方法で実現したい
    • IM-FormaDesigner
    • IM-LogicDesigner
    • データソース定義

概要図

image.png

成果物(gifアニメーション)

get_other_app_file.gif

成果物の各種定義

やったこと

ダウンロード用ページの解析

IM-FormaDesignerからファイルをダウンロードするには、独自のダウンロード用ページを経由するか、
標準のファイルダウンロード部品のページを経由する必要があります。

独自のダウンロード用ページは前述したとおりデプロイが必要となるので利用ができません。
そこで、標準のファイルダウンロードページを経由させることにします。

標準のファイルダウンロードページ:forma/designer/types/product/72/fileupload/download

しかし、ここに然るべきパラメータをfile_idapplication_idを渡すだけでは適切に動作しません。
im_markという(おそらく)セッションごとに自動付与されるパラメータを渡してあげる必要があります。
im_markはどうやったら取得できるのか?これを調べる必要があります。

intra-mart社が作成したソースが格納されているテナントID/WEB-INF配下をdownloadなどのキーワードでgrep検索してみます。
そうすると、WEB-INF/jssp/product/src/forma/designer/types/product/72/fileupload配下にいい感じのコードが見つかります。

  • fileupload_savefile.jsの48行目付近
fileupload_savefile.js
    var downloadUrl = new URL('forma/designer/types/product/72/fileupload/download');
    downloadUrl.setArgument('application_id', request.applicationId);
    downloadUrl.setArgument('insert_id', request.insertId);
    downloadUrl.setArgument('upload_item_id', request.uploadItemId);
    downloadUrl.setArgument('imfr_process_key', request.processKey);
    downloadUrl.setArgument('file_id', FRCryptionUtil.encrypt(result.fileId));
    downloadUrl.setArgument('type', result.fileInfo.type);

    // ファイル情報の返却
    response.sendMessageBodyString(ImJson.toJSONString([{
      name           : oFile.getFileName(),
      application_id : request.applicationId,
      insert_id      : request.insertId,
      process_key    : request.processKey,
      input_id       : request.uploadItemId,
      file           : {
        id           : result.fileId,
        encrypt_id   : FRCryptionUtil.encrypt(result.fileId),
        type         : result.fileInfo.type,
        size         : result.fileInfo.file_size,
        name         : oFile.getFileName(),
        display_size : displaySize(result.fileInfo.file_size),
        notes        : request.fileNotes,
        record_date  : Procedure.imfr_date_utils.getDisplayDatetimeFormat(recordDate,
          formats.IM_DATETIME_FORMAT_DATE_STANDARD, formats.locale),
        record_time  : Procedure.imfr_date_utils.getDisplayDatetimeFormat(recordDate,
          formats.IM_DATETIME_FORMAT_DATE_STANDARD + ' ' + formats.IM_DATETIME_FORMAT_TIME_STANDARD, formats.locale),
        download_url : downloadUrl.location(),
        imageThumbnailPreview : isImageThumbnailPreview
      }
    }]));

どうやら、URLクラスオブジェクトに然るべきパラメータを渡すことでダウンロード用のURLを生成しているようです。
そこで、このソースを元に、LogicDesignerのJavaScript定義を作成し、IN/OUTを設定します。

ロジックフローの作成

image.png

function run(input) {

  var downloadUrl = null;
  var downloadUrlStr = "";
  var downloadUrlForATag = "";
  var errorFlg = false;
  var errorMsg = "";
  
  try {
    downloadUrl = new URL('forma/designer/types/product/72/fileupload/download');
    downloadUrl.setArgument('application_id', input.applicationId);
    downloadUrl.setArgument('insert_id', input.insertId);
    downloadUrl.setArgument('upload_item_id', input.uploadItemId);
    downloadUrl.setArgument('imfr_process_key', input.processKey);
    downloadUrl.setArgument('file_id', FRCryptionUtil.encrypt(input.fileId));
    downloadUrl.setArgument('type', input.type);
  } catch(e) {
    errorFlg = true;
    errorMsg = e.message;
  } finally {
    if(!errorFlg) {
      downloadUrlStr = downloadUrl.location();
      downloadUrlForATag = "<a href='" + downloadUrlStr + "'>" + input.fileName + "</a>";
    }
  }

	return {
		downloadUrl: downloadUrlStr,
		errorFlg: errorFlg,
		errorMsg: errorMsg,
		downloadUrlSource: downloadUrlForATag
	};
}

これでダウンロードURL作成の準備が完了しました。

あとは、LogicDesignerで下記のような処理を実装し、データソース定義経由で画面に返してあげればOKです

  • SQL定義を用いてIMFR_T_FILEUPLOADテーブルから、トランザクションのINSERT_IDAPPLICATION_IDを元にファイルIDやファイル名を取得する
  • 繰り返しタスクで、上記結果オブジェクトをループ
    • 各ファイルIDやファイル名ごとに、ダウンロードURL作成用のJavaScriptを実行し、URLを取得。データを返却
    • データをリスト形式でpushしていく
  • リスト形式のデータを画面に返却する

image.png

image.png

image.png

画面イメージ

  • 別アプリでファイル添付
    image.png

  • 初期表示
    image.png

  • 別アプリのデータを検索
    image.png

  • 別アプリでアップロードしたファイルと、ダウンロード用URLが表示
    image.png

これで、システム停止を行わず(デプロイせず)に、IM-FormaDesigner, LogicDesignerのみで対応を行うことができました。

年末にこの課題対応ができて一安心です。

最後に注意点

本件はあくまでもデプロイを伴うシステム変更が困難である場合の奥の手です。
本当にこの内容で対応を実施すべきかどうかを熟考した上で適用すべきと考えます。
申し訳ありませんが、この対応によって発生した障害等について、一切責任を負いませんので、ご了承ください。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?