FessのMIMEタイプ判定を拡張子ベースで上書きする

Fessのクロール時のMIMEタイプ判定は、Apache Tikaを使ったコンテンツベースの検出を行っています。しかし、ファイルの内容によっては誤判定されるケースがあります。例えば、REMコメントで始まるSQLファイルがWindowsバッチファイル(application/x-bat)として検出されてしまうことがあります。この問題に対応するため、Fess 15.5でfess_config.propertiesに拡張子ベースのMIMEタイプ上書き設定を追加しました。

背景

Tikaによるコンテンツベースの検出は多くの場合正確ですが、ファイルの内容が別のファイル形式と類似している場合に誤判定が発生することがあります。特にSQLファイルでは、Oracle Database用のスクリプトがREM(remark)コメントで始まることが多く、これがWindowsバッチファイルのコマンドと同じキーワードであるため、application/x-batとして誤検出されます。

このような場合、拡張子ベースでMIMEタイプを指定できれば、コンテンツベースの検出結果を上書きして正しいMIMEタイプを設定できます。

設定方法

fess_config.propertiesに以下の設定を追加します。

# 拡張子に基づくMIMEタイプの上書き設定(1行に1つ: .拡張子=MIMEタイプ)
crawler.document.mimetype.extension.overrides=\
.sql=text/x-sql\n\
.plsql=text/x-plsql

各行は.拡張子=MIMEタイプの形式で指定し、改行文字(\n)で区切ります。この設定で指定された拡張子のファイルは、コンテンツベースの判定結果よりも拡張子ベースの設定が優先されます。

動作の仕組み

新しく追加されたFessMimeTypeHelperクラスが、従来のMimeTypeHelperImplを拡張しています。初期化時にfess_config.propertiesから設定を読み込み、拡張子とMIMEタイプのマッピングを構築します。

ファイルのMIMEタイプを判定する際の動作は以下の通りです。

  1. ファイル名から拡張子を取得(大文字・小文字は区別しない)
  2. 拡張子が上書き設定に含まれている場合、設定されたMIMEタイプを返す
  3. 含まれていない場合、従来通りコンテンツベースの検出を行う

設定の記述ルール

  • 1行に1つのマッピングを記述する(\nで区切り)
  • 形式: .拡張子=MIMEタイプ
  • 拡張子の大文字・小文字は区別されない(.sql.SQLは同じ扱い)
  • 前後の空白は自動的にトリミングされる
  • 不正な形式の行(=を含まない行)は無視される
  • 空行は無視される
  • デフォルトは空文字列(上書きなし、従来の動作を維持)

設定例

SQLファイルの誤判定を修正する場合:

crawler.document.mimetype.extension.overrides=.sql=text/x-sql

複数の拡張子を設定する場合:

crawler.document.mimetype.extension.overrides=\
.sql=text/x-sql\n\
.plsql=text/x-plsql\n\
.pls=text/x-plsql

注意事項

  • この機能はFess 15.5以降で利用可能です
  • デフォルトでは上書き設定は空のため、従来の動作と変わりません
  • 拡張子の上書き設定はコンテンツベースの判定より優先されます
  • パスを含むファイル名(/path/to/file.sql)でも拡張子は正しく認識されます

Fessクローラーのアンカー URL重複排除

Fessのクローラーで、同一ページ内のアンカータグから抽出されるURLに重複が含まれる問題を修正しました。

問題

FessXpathTransformergetAnchorListメソッドでは、HTMLページ内の<a><img><link>などのタグからURLを抽出してクロール対象のリストを作成します。しかし、同じURLが複数のタグに記述されている場合、重複したURLがそのままリストに追加されていました。これにより、クローラーが同じURLを複数回処理する無駄が発生していました。

修正内容

URLの収集に使用するコレクションをArrayListからLinkedHashSetに変更しました。

// 変更前
final List<String> urlList = new ArrayList<>(anchorList.size());
for (final RequestData requestData : anchorList) {
    urlList.add(requestData.getUrl());
}
return urlList;

// 変更後
final Set<String> urlSet = new LinkedHashSet<>(anchorList.size());
for (final RequestData requestData : anchorList) {
    urlSet.add(requestData.getUrl());
}
return new ArrayList<>(urlSet);

LinkedHashSetを使用することで、重複を排除しつつ、最初に出現した順序を維持します。戻り値はListのままなので、既存のインターフェースとの互換性も保たれています。

テスト

重複排除の動作を検証するため、7つのユニットテストを追加しました。

  • 重複なしのケース(ベースライン)
  • 同じタグ種別(<a>)からの重複
  • 異なるタグ種別(<a><img><link>)からの重複
  • 挿入順序の維持
  • リンクなしの空ドキュメント
  • すべてが同一URLのケース
  • <link>タグとの重複

PRの詳細はこちらを参照してください。

FessのAIモードUIをAtlassian Design Systemで調整

Fess 15.5に向けて、AIモード(チャット画面)のUIをAtlassian Design System(ADS)のパターンに従って全面的に調整しました。

変更の概要

今回のUI改善は、モダンなデザインシステムに沿った統一的な見た目と操作性の向上を目指しています。主な変更点は以下の通りです。

ステータスロゼンジ

ヘッダーのステータス表示を、ADSのLozenge(バッジ)パターンに変更しました。状態に応じて色が変わり、処理中はパルスアニメーションで視覚的にフィードバックします。

  • Ready: グレー背景
  • Thinking: ブルー背景(パルスアニメーション付き)
  • Error: レッド背景
  • Success: グリーン背景

ステッパーコンポーネント

検索処理の進行状況を可視化するステッパーを新規追加しました。以下の5つのフェーズをアイコン付きで表示します。

  1. Analyze – 意図分析
  2. Search – 検索実行
  3. Evaluate – 結果評価
  4. Retrieve – ドキュメント取得
  5. Answer – 回答生成

各ステップは、待機中・実行中・完了の3状態を持ち、実行中のステップにはパルスアニメーションが付きます。

ウェルカム画面

チャット開始前の空の状態に、ADSのEmpty Stateパターンに従ったウェルカム画面を表示するようにしました。以前のハードコードされたサジェスチョンチップスは削除しています。

メッセージUI

メッセージ表示も改善しています。

  • フェードインアニメーションの追加
  • タイムスタンプ表示
  • ホバー時のコピーボタン表示
  • ソースリンクのカード形式での表示
  • アバターのグラデーション化

エラーバナー

エラー発生時にリトライ・閉じるボタン付きのバナーを表示するようにしました。

入力エリア

  • 文字数カウンター(0 / 4000)の表示
  • キーボードショートカットのヒント表示(Enter送信、Shift+Enter改行)
  • ARIAラベルによるアクセシビリティ改善

ダークモード対応

全コンポーネントに対してダークモードのスタイルを追加しました。prefers-color-scheme: darkに対応しています。

16言語対応

新しいUI要素のラベルを16言語分追加しています。ステッパーのフェーズ名、ウェルカムメッセージ、入力ヒント、コピー通知など、すべての新規テキストが多言語対応済みです。

カラーパレット

ADSのカラートークンに合わせて、以下のような色使いに統一しています。

用途カラーコード
プライマリ#0052CC
テキスト(メイン)#172B4D
テキスト(サブ)#6B778C
ボーダー#DFE1E6
背景(サブ)#F4F5F7
成功#00875A
エラー#DE350B

まとめ

15.5ではこのデザインをベースにAIモードのUIを仕上げていく予定です。ADSパターンに従うことで、一貫性のあるモダンなUIを実現しています。

関連リンク