/**
* 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.model;
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 com.asakusafw.vocabulary.operator.CoGroup;
import com.asakusafw.vocabulary.operator.GroupSort;
/**
* An annotation represents which the annotated element will be used only once.
*
* This can appear with the following elements:
* <ul>
* <li>
* Input parameter of {@link CoGroup} and {@link GroupSort} operator methods.
*
* A parameter with this annotation represents that elements in the parameter must be accessed only once.
* The parameter must be defined as {@code Iterable} type, and clients can invoke
* {@link Iterable#iterator() its iterator()} only once in the operator method.
* If clients invoke the method more than once, it MAY raise an exception.
*
* Typically, the annotated parameter is used with {@code for} statement like as following:
<pre><code>
@CoGroup
public void iterate(@Key(...) @Once Iterable<Hoge> input, Result<Hoge> result) {
for (Hoge hoge : input) {
...
}
}
</code></pre>
*
* With this annotation, obtaining elements in the sequence will change the old object from the sequence.
* For example, the operations are not guaranteed in the following case:
<pre><code>
@CoGroup
public void invalid(@Key(...) @Once Iterable<Hoge> input, Result<Hoge> result) {
Iterator<Hoge> iter = input.iterator();
Hoge a = iter.next();
Hoge b = iter.next(); // this operation may break out contents of 'a'
...
}
</code></pre>
* In such the case, application developers should create a copy of the object:
<pre><code>
final Hoge a = new Hoge();
final Hoge b = new Hoge();
@CoGroup
public void invalid(@Key(...) @Once Iterable<Hoge> input, Result<Hoge> result) {
a.copyFrom(iter.next()); // create a copy
b.copyFrom(iter.next());
...
}
</code></pre>
* </li>
* </ul>
*
* @since 0.9.1
*/
@Target({ ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Once {
// no special members
}