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