001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 */
012package org.nuxeo.ecm.automation.core.annotations;
013
014import java.lang.annotation.ElementType;
015import java.lang.annotation.Retention;
016import java.lang.annotation.RetentionPolicy;
017import java.lang.annotation.Target;
018
019import org.nuxeo.ecm.automation.OutputCollector;
020
021/**
022 * To be used to mark methods provided by an operation. A method must have at most one argument which is the operation
023 * input and a return type which is the operation output. Methods with zero parameters (void input) will match any
024 * input. An operation may have multiple methods if it supports multiple input and output types.
025 * <p>
026 * For each INPUT/OUTPUT type association you must create a new method in an operation and annotate it using this
027 * annotation. The set of input types available in an operation are the operation accepted types and the set of output
028 * types are the operation produced types. A produced type will become the input type for the next operation in the
029 * chain, that will be dispatched to the right method that know how to consume the type.
030 * <p>
031 * When an operation provides 2 methods accepting the same input type the chain will need to take a decision to
032 * determine the best way to continue. A common algorithm to find the right path until the end of the chain is
033 * backtracking: from a set of potential nodes one is selected to be visited (randomly or not). If the node is a dead
034 * end then another node from the set is taken until the path to the last node is created.
035 * <p>
036 * A chain may have no paths until the last operation. In this case the chain is invalid and the chain processor will
037 * trigger an error. Also, a chain can provide multiple paths to the last operation. To help the engine to find the best
038 * path until the last operation you can use the {@link #priority()} attribute to specify which method is preferred. The
039 * default priority is 0 (e.g. no priority). Higher priorities have more chance to be selected when a conflict occurs.
040 * If no user priority is specified (i.e. priority is 0) then the default priority is used. Here is how the default
041 * priority is computed (the top most case has the greater priority):
042 * <ul>
043 * <li>The input type is an exact match of the method declared argument
044 * <li>The method argument type is assignable from the input type (i.e. a super type but not an exact match)
045 * <li>The input can be adapted to the method argument using registered type adapters
046 * <li>the method has no arguments (void input)
047 * </ul>
048 * If no one of these rules applies then the method will not match the input.
049 * <p>
050 * The class owning the annotated method must be annotated using {@link Operation}
051 *
052 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
053 */
054@Retention(RetentionPolicy.RUNTIME)
055@Target(ElementType.METHOD)
056public @interface OperationMethod {
057
058    /**
059     * If defined the method is iterable.
060     * <p>
061     * It means that when such a method is called with an input type of <code>Iterable<INPUT></code> (where INPUT is the
062     * declared method input type) the method will be iteratively called to generate all the outputs and collect them
063     * using the given OutputCollector.
064     *
065     * @return
066     */
067    @SuppressWarnings("rawtypes")
068    Class<? extends OutputCollector> collector() default OutputCollector.class;
069
070    int priority() default 0;
071
072}