001/*
002 * (C) Copyright 2013 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, Object> params) throws OperationException;
113
114/**
115     * Registers a parametrized operation chain. This chain can be executed
116     * later by calling <code>run</code> and passing the chain ID. If a chain
117     * having the same ID exists an exception is thrown
118     *
119     * @deprecated no specific chain registry anymore: chains are now
120     *             operations, use {@link #putOperation(OperationType, boolean)
121     *             method instead.
122     * @since 5.7.2
123     */
124    @Deprecated
125    void putOperationChain(OperationChain chain) throws OperationException;
126
127/**
128     * Registers a parametrized operation chain. This chain can be executed
129     * later by calling <code>run</code> and passing the chain ID. If the
130     * replace attribute is true then any chain already registered under the
131     * same id will be replaced otherwise an exception is thrown.
132     *
133     * @deprecated no specific chain registry anymore: chains are now
134     *             operations, use {@link #putOperation(OperationType, boolean)
135     *             method instead.
136     * @since 5.7.2
137     */
138    @Deprecated
139    void putOperationChain(OperationChain chain, boolean replace) throws OperationException;
140
141    /**
142     * Removes a registered operation chain given its ID. Do nothing if the chain was not registered.
143     *
144     * @deprecated no specific chain registry anymore: chains are now operations, use
145     *             {@link #removeOperation(OperationType)} method instead.
146     * @since 5.7.2
147     */
148    @Deprecated
149    void removeOperationChain(String id);
150
151    /**
152     * Gets a registered operation chain.
153     *
154     * @deprecated no specific chain registry anymore: chains are now operations, use {@link #getOperation(String)}
155     *             method instead.
156     * @since 5.7.2
157     */
158    @Deprecated
159    OperationChain getOperationChain(String id) throws OperationNotFoundException;
160
161    /**
162     * Gets a list of all registered chains
163     *
164     * @deprecated no specific chain registry anymore: chains are now operations, use {@link #getOperations()} method
165     *             instead.
166     * @since 5.7.2
167     * @return the list or an empty list if no registered chains exists
168     */
169    @Deprecated
170    List<OperationChain> getOperationChains();
171
172    /**
173     * Registers a new type adapter that can adapt an instance of the accepted type into one of the produced type.
174     */
175    void putTypeAdapter(Class<?> accept, Class<?> produce, TypeAdapter adapter);
176
177    /**
178     * Removes a type adapter
179     */
180    void removeTypeAdapter(Class<?> accept, Class<?> produce);
181
182    /**
183     * Gets a type adapter for the input type accept and the output type produce. Returns null if no adapter was
184     * registered for these types.
185     */
186    TypeAdapter getTypeAdapter(Class<?> accept, Class<?> produce);
187
188    /**
189     * Adapts an object to a target type if possible otherwise throws an exception. The method must be called in an
190     * operation execution with a valid operation context.
191     */
192    <T> T getAdaptedValue(OperationContext ctx, Object toAdapt, Class<?> targetType) throws OperationException;
193
194    /**
195     * Checks whether or not the given type is adaptable into the target type. An instance of an adaptable type can be
196     * converted into an instance of the target type.
197     * <p>
198     * This is a shortcut to <code>getTypeAdapter(typeToAdapt, targetType) != null</code>
199     */
200    boolean isTypeAdaptable(Class<?> typeToAdapt, Class<?> targetType);
201
202    /**
203     * Generates a documentation model for all registered operations. The documentation model is generated from
204     * operation annotations and can be used in UI tools to describe operations. The returned list is sorted using
205     * operation ID. Optional method.
206     */
207    List<OperationDocumentation> getDocumentation() throws OperationException;
208
209    /**
210     * @since 5.7.2
211     * @param id operation ID
212     * @return true if operation registry contains the given operation
213     */
214    boolean hasOperation(String id);
215
216    /**
217     * @since 5.7.3
218     */
219    void putChainException(ChainException exceptionChain);
220
221    /**
222     * @since 5.7.3
223     */
224    void removeExceptionChain(ChainException exceptionChain);
225
226    /**
227     * @since 5.7.3
228     */
229    ChainException[] getChainExceptions();
230
231    /**
232     * @since 5.7.3
233     */
234    ChainException getChainException(String onChainId);
235
236    /**
237     * @since 5.7.3
238     */
239    void putAutomationFilter(AutomationFilter automationFilter);
240
241    /**
242     * @since 5.7.3
243     */
244    void removeAutomationFilter(AutomationFilter automationFilter);
245
246    /**
247     * @since 5.7.3
248     */
249    AutomationFilter getAutomationFilter(String id);
250
251    /**
252     * @since 5.7.3
253     */
254    AutomationFilter[] getAutomationFilters();
255
256    /**
257     * @since 5.7.3
258     */
259    boolean hasChainException(String onChainId);
260
261    /**
262     * @since 5.9.5
263     */
264    void putOperation(Class<?> type, boolean replace, String contributingComponent,
265            List<WidgetDefinition> widgetDefinitionList) throws OperationException;
266
267    /**
268     * This running method execute operation process through a new transaction.
269     *
270     * @param ctx the operation context.
271     * @param chainId the chain Id.
272     * @param chainParameters chain parameters.
273     * @param timeout Transaction timeout.
274     * @param rollbackGlobalOnError Rollback or not transaction after failing.
275     * @since 6.0
276     */
277    Object runInNewTx(OperationContext ctx, String chainId, Map chainParameters, Integer timeout,
278            boolean rollbackGlobalOnError) throws OperationException;
279}