001/*
002 * (C) Copyright 2013-2016 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.ecm.automation;
020
021import java.util.List;
022import java.util.Map;
023
024import org.nuxeo.ecm.automation.core.annotations.Operation;
025import org.nuxeo.ecm.platform.forms.layout.api.WidgetDefinition;
026
027/**
028 * Service providing an operation registry and operation execution methods. The operation registry is thread-safe and
029 * optimized for lookups. Progress monitor for asynchronous executions is not yet implemented.
030 *
031 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
032 * @author <a href="mailto:grenard@nuxeo.com">Guillaume</a>
033 */
034public interface AutomationService {
035
036    /**
037     * Registers an operation given its class. The operation class MUST be annotated using {@link Operation} annotation.
038     * If an operation having the same ID exists an exception will be thrown.
039     */
040    void putOperation(Class<?> type) throws OperationException;
041
042    /**
043     * Registers an operation given its class. The operation class MUST be annotated using {@link Operation} annotation.
044     * If the <code>replace</code> argument is true then any existing operation having the same ID will replaced with
045     * this one.
046     */
047    void putOperation(Class<?> type, boolean replace) throws OperationException;
048
049    /**
050     * Registers an operation given its class. The operation class MUST be annotated using {@link Operation} annotation.
051     * If the <code>replace</code> argument is true then any existing operation having the same ID will replaced with
052     * this one. Third argument represents the name of the component registring the operation
053     */
054    void putOperation(Class<?> type, boolean replace, String contributingComponent) throws OperationException;
055
056    /**
057     * Registers an operation given it's type.
058     *
059     * @since 5.9.2
060     */
061    void putOperation(OperationType op, boolean replace) throws OperationException;
062
063    /**
064     * Removes an operation given its class. If the operation was not registered does nothing.
065     */
066    void removeOperation(Class<?> key);
067
068    /**
069     * Removes an operation given it's type. If the operation was not registered does nothing.
070     *
071     * @since 5.9.2
072     */
073    void removeOperation(OperationType type);
074
075    /**
076     * Gets all operation types that was registered.
077     */
078    OperationType[] getOperations();
079
080    /**
081     * Gets an operation type given its ID. Throws an exception if the operation is not found.
082     */
083    OperationType getOperation(String id) throws OperationNotFoundException;
084
085    /**
086     * Builds the operation chain given a context. If the context input object or the chain cannot be resolved (no path
087     * can be found through all the operation in the chain) then {@link InvalidChainException} is thrown. The returned
088     * object can be used to run the chain.
089     */
090    CompiledChain compileChain(Class<?> inputType, OperationChain chain) throws OperationException;
091
092    /**
093     * Same as previous but takes an array of operation parameters
094     */
095    CompiledChain compileChain(Class<?> inputType, OperationParameters... chain) throws OperationException;
096
097    /**
098     * Builds and runs the operation chain given a context. If the context input object or the chain cannot be resolved
099     * (no path can be found through all the operation in the chain) then {@link InvalidChainException} is thrown.
100     */
101    Object run(OperationContext ctx, OperationChain chain) throws OperationException;
102
103    /**
104     * Same as previous but for managed chains identified by an ID. For managed chains always use this method since the
105     * compiled chain is cached and run will be faster
106     */
107    Object run(OperationContext ctx, String chainId) throws OperationException;
108
109    /**
110     * Shortcut to execute a single operation described by the given ID and map of parameters
111     */
112    Object run(OperationContext ctx, String id, Map<String, ?> params) throws OperationException;
113
114    /**
115     * Registers a parametrized operation chain. This chain can be executed later by calling <code>run</code> and
116     * passing the chain ID. If a chain having the same ID exists an exception is thrown
117     *
118     * @deprecated since 5.9.2 no specific chain registry anymore: chains are now operations, use
119     *             {@link #putOperation(OperationType, boolean)} method instead.
120     * @since 5.7.2
121     */
122    @Deprecated
123    void putOperationChain(OperationChain chain) throws OperationException;
124
125    /**
126     * Registers a parametrized operation chain. This chain can be executed later by calling <code>run</code> and
127     * passing the chain ID. If the replace attribute is true then any chain already registered under the same id will
128     * be replaced otherwise an exception is thrown.
129     *
130     * @deprecated since 5.9.2 no specific chain registry anymore: chains are now operations, use
131     *             {@link #putOperation(OperationType, boolean)} method instead.
132     * @since 5.7.2
133     */
134    @Deprecated
135    void putOperationChain(OperationChain chain, boolean replace) throws OperationException;
136
137    /**
138     * Removes a registered operation chain given its ID. Do nothing if the chain was not registered.
139     *
140     * @deprecated since 5.9.2 no specific chain registry anymore: chains are now operations, use
141     *             {@link #removeOperation(OperationType)} method instead.
142     * @since 5.7.2
143     */
144    @Deprecated
145    void removeOperationChain(String id);
146
147    /**
148     * Gets a registered operation chain.
149     *
150     * @deprecated since 5.9.2 no specific chain registry anymore: chains are now operations, use
151     *             {@link #getOperation(String)} method instead.
152     * @since 5.7.2
153     */
154    @Deprecated
155    OperationChain getOperationChain(String id) throws OperationNotFoundException;
156
157    /**
158     * Gets a list of all registered chains
159     *
160     * @deprecated since 5.9.2 no specific chain registry anymore: chains are now operations, use {@link #getOperations()} method
161     *             instead.
162     * @since 5.7.2
163     * @return the list or an empty list if no registered chains exists
164     */
165    @Deprecated
166    List<OperationChain> getOperationChains();
167
168    /**
169     * Registers a new type adapter that can adapt an instance of the accepted type into one of the produced type.
170     */
171    void putTypeAdapter(Class<?> accept, Class<?> produce, TypeAdapter adapter);
172
173    /**
174     * Removes a type adapter
175     */
176    void removeTypeAdapter(Class<?> accept, Class<?> produce);
177
178    /**
179     * Gets a type adapter for the input type accept and the output type produce. Returns null if no adapter was
180     * registered for these types.
181     */
182    TypeAdapter getTypeAdapter(Class<?> accept, Class<?> produce);
183
184    /**
185     * Adapts an object to a target type if possible otherwise throws an exception. The method must be called in an
186     * operation execution with a valid operation context.
187     */
188    <T> T getAdaptedValue(OperationContext ctx, Object toAdapt, Class<?> targetType) throws OperationException;
189
190    /**
191     * Checks whether or not the given type is adaptable into the target type. An instance of an adaptable type can be
192     * converted into an instance of the target type.
193     * <p>
194     * This is a shortcut to <code>getTypeAdapter(typeToAdapt, targetType) != null</code>
195     */
196    boolean isTypeAdaptable(Class<?> typeToAdapt, Class<?> targetType);
197
198    /**
199     * Generates a documentation model for all registered operations. The documentation model is generated from
200     * operation annotations and can be used in UI tools to describe operations. The returned list is sorted using
201     * operation ID. Optional method.
202     */
203    List<OperationDocumentation> getDocumentation() throws OperationException;
204
205    /**
206     * @since 5.7.2
207     * @param id operation ID
208     * @return true if operation registry contains the given operation
209     */
210    boolean hasOperation(String id);
211
212    /**
213     * @since 5.7.3
214     */
215    void putChainException(ChainException exceptionChain);
216
217    /**
218     * @since 5.7.3
219     */
220    void removeExceptionChain(ChainException exceptionChain);
221
222    /**
223     * @since 5.7.3
224     */
225    ChainException[] getChainExceptions();
226
227    /**
228     * @since 5.7.3
229     */
230    ChainException getChainException(String onChainId);
231
232    /**
233     * @since 5.7.3
234     */
235    void putAutomationFilter(AutomationFilter automationFilter);
236
237    /**
238     * @since 5.7.3
239     */
240    void removeAutomationFilter(AutomationFilter automationFilter);
241
242    /**
243     * @since 5.7.3
244     */
245    AutomationFilter getAutomationFilter(String id);
246
247    /**
248     * @since 5.7.3
249     */
250    AutomationFilter[] getAutomationFilters();
251
252    /**
253     * @since 5.7.3
254     */
255    boolean hasChainException(String onChainId);
256
257    /**
258     * @since 5.9.5
259     */
260    void putOperation(Class<?> type, boolean replace, String contributingComponent,
261            List<WidgetDefinition> widgetDefinitionList) throws OperationException;
262
263    /**
264     * This running method execute operation process through a new transaction.
265     *
266     * @param ctx the operation context.
267     * @param chainId the chain Id.
268     * @param chainParameters chain parameters.
269     * @param timeout Transaction timeout.
270     * @param rollbackGlobalOnError Rollback or not transaction after failing.
271     * @since 6.0
272     */
273    Object runInNewTx(OperationContext ctx, String chainId, Map<String,?> chainParameters, Integer timeout,
274            boolean rollbackGlobalOnError) throws OperationException;
275}