/**
* Copyright 2011-2017 Asakusa Framework Team.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.asakusafw.vocabulary.operator;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;
import com.asakusafw.vocabulary.flow.processor.InputBuffer;
import com.asakusafw.vocabulary.model.Key;
//TODO i18n
/**
* グループ結合演算子を表すメソッドに付与する注釈。
* <p>
* この演算子は、二種類のデータをそれぞれ条件に応じてグループ化してリストを作成し、
* それらのリストを処理した結果を出力する。
* </p>
* <p>
* このメソッドは、二つのモデルオブジェクトを要素に取る{@link List リスト型}の引数と、
* 複数の{@code 結果オブジェクト型}の引数を取り、
* リストの任意の要素について加工を行った後に、
* 結果オブジェクトに出力を行うプログラムを記述する。
* また、それぞれのリスト型の引数には{@link Key}注釈を指定し、
* {@link Key#group() グループ化}のためのプロパティ名を指定する必要がある
* ({@link Key#order() 整列}のためのプロパティ名および整列方向も指定可能である。
* 指定した場合、引数に渡されるリストはその条件で整列される)。
* </p>
* <p>
* また、引数には同メソッドで宣言した型変数を利用できるが、
* 全ての結果オブジェクト型の出力に型変数を含める場合には、
* いずれかの入力に同様の型変数を指定してある必要がある。
* </p>
* <p>
* この注釈を付与するメソッドは、一般的な演算子メソッドの要件の他に、
* 下記の要件をすべて満たす必要がある。
* </p>
* <ul>
* <li> 返戻型に{@code void}を指定する </li>
* <li> 以下の引数を宣言する
* <ul>
* <li>
* モデルオブジェクトを要素に取る{@link List リスト型}の引数、
* さらに{@link Key}注釈でグループ化と整列のための情報を指定する
* </li>
* <li>
* モデルオブジェクトを要素に取る{@link List リスト型}の引数、
* さらに{@link Key}注釈でグループ化と整列のための情報を指定する
* </li>
* <li> 一つ以上の結果型の引数 </li>
* </ul>
* </li>
* <li> 以下の修飾子を付与する
* <ul>
* <li> (特になし) </li>
* </ul>
* </li>
* <li> 以下の修飾子は付与しない
* <ul>
* <li> {@code abstract} </li>
* </ul>
* </li>
* </ul>
* <p>
* 例:
* </p>
<pre><code>
/**
* HogeとFooをHogeのIDでグループ化し、重複なしで突合できたもののみを結果として出力する。
* それ以外の値はエラーとして出力する。
* @param hogeList Hogeのグループごとのリスト
* @param fooList Fooのグループごとのリスト
* @param hogeResult 成功したHoge
* @param fooResult 成功したFoo
* @param hogeError 失敗したHoge
* @param fooError 失敗したFoo
*/
@CoGroup
public void checkUp(
@Key(group = "id") List<Hoge> hogeList,
@Key(group = "hogeId") List<Foo> fooList,
Result<Hoge> hogeResult,
Result<Foo> fooResult,
Result<Hoge> hogeError,
Result<Foo> fooError) {
// いずれも存在+重複なしで突合成功
if (hogeList.size() == 1 && fooList.size() == 1) {
hogeResult.add(hogeList.get(0));
fooResult.add(fooList.get(0));
}
// それ以外はエラー
else {
for (Hoge hoge : hogeList) {
hogeError.add(hoge);
}
for (Foo foo : fooList) {
fooError.add(foo);
}
}
}
</code></pre>
* @see MasterJoin
* @see GroupSort
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CoGroup {
/**
* 演算子の入力バッファの性質を指定する。
* <p>
* デフォルトではヒープ上に高速な入力バッファを構築し、巨大なグループに対しての処理は行えない。
* </p>
* @since 0.2.0
* @see InputBuffer
*/
InputBuffer inputBuffer() default InputBuffer.EXPAND;
}