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     * @throws OperationException
059     *
060     * @since 5.9.2
061     */
062    void putOperation(OperationType op, boolean replace) throws OperationException;
063
064    /**
065     * Removes an operation given its class. If the operation was not registered does nothing.
066     */
067    void removeOperation(Class<?> key);
068
069    /**
070     * Removes an operation given it's type. If the operation was not registered does nothing.
071     *
072     * @since 5.9.2
073     */
074    void removeOperation(OperationType type);
075
076    /**
077     * Gets all operation types that was registered.
078     */
079    OperationType[] getOperations();
080
081    /**
082     * Gets an operation type given its ID. Throws an exception if the operation is not found.
083     */
084    OperationType getOperation(String id) throws OperationNotFoundException;
085
086    /**
087     * Builds the operation chain given a context. If the context input object or the chain cannot be resolved (no path
088     * can be found through all the operation in the chain) then {@link InvalidChainException} is thrown. The returned
089     * object can be used to run the chain.
090     */
091    CompiledChain compileChain(Class<?> inputType, OperationChain chain) throws OperationException;
092
093    /**
094     * Same as previous but takes an array of operation parameters
095     */
096    CompiledChain compileChain(Class<?> inputType, OperationParameters... chain) throws OperationException;
097
098    /**
099     * Builds and runs the operation chain given a context. If the context input object or the chain cannot be resolved
100     * (no path can be found through all the operation in the chain) then {@link InvalidChainException} is thrown.
101     */
102    Object run(OperationContext ctx, OperationChain chain) throws OperationException;
103
104    /**
105     * Same as previous but for managed chains identified by an ID. For managed chains always use this method since the
106     * compiled chain is cached and run will be faster
107     */
108    Object run(OperationContext ctx, String chainId) throws OperationException;
109
110    /**
111     * Shortcut to execute a single operation described by the given ID and map of parameters
112     */
113    Object run(OperationContext ctx, String id, Map<String, ?> params) throws OperationException;
114
115    /**
116     * Registers a parametrized operation chain. This chain can be executed later by calling <code>run</code> and
117     * passing the chain ID. If a chain having the same ID exists an exception is thrown
118     *
119     * @deprecated since 5.9.2 no specific chain registry anymore: chains are now operations, use
120     *             {@link #putOperation(OperationType, boolean) method instead.
121     * @since 5.7.2
122     */
123    @Deprecated
124    void putOperationChain(OperationChain chain) throws OperationException;
125
126    /**
127     * Registers a parametrized operation chain. This chain can be executed later by calling <code>run</code> and
128     * passing the chain ID. If the replace attribute is true then any chain already registered under the same id will
129     * be replaced otherwise an exception is thrown.
130     *
131     * @deprecated since 5.9.2 no specific chain registry anymore: chains are now operations, use
132     *             {@link #putOperation(OperationType, boolean) method instead.
133     * @since 5.7.2
134     */
135    @Deprecated
136    void putOperationChain(OperationChain chain, boolean replace) throws OperationException;
137
138    /**
139     * Removes a registered operation chain given its ID. Do nothing if the chain was not registered.
140     *
141     * @deprecated since 5.9.2 no specific chain registry anymore: chains are now operations, use
142     *             {@link #removeOperation(OperationType)} method instead.
143     * @since 5.7.2
144     */
145    @Deprecated
146    void removeOperationChain(String id);
147
148    /**
149     * Gets a registered operation chain.
150     *
151     * @deprecated since 5.9.2 no specific chain registry anymore: chains are now operations, use
152     *             {@link #getOperation(String)} method instead.
153     * @since 5.7.2
154     */
155    @Deprecated
156    OperationChain getOperationChain(String id) throws OperationNotFoundException;
157
158    /**
159     * Gets a list of all registered chains
160     *
161     * @deprecated since 5.9.2 no specific chain registry anymore: chains are now operations, use {@link #getOperations()} method
162     *             instead.
163     * @since 5.7.2
164     * @return the list or an empty list if no registered chains exists
165     */
166    @Deprecated
167    List<OperationChain> getOperationChains();
168
169    /**
170     * Registers a new type adapter that can adapt an instance of the accepted type into one of the produced type.
171     */
172    void putTypeAdapter(Class<?> accept, Class<?> produce, TypeAdapter adapter);
173
174    /**
175     * Removes a type adapter
176     */
177    void removeTypeAdapter(Class<?> accept, Class<?> produce);
178
179    /**
180     * Gets a type adapter for the input type accept and the output type produce. Returns null if no adapter was
181     * registered for these types.
182     */
183    TypeAdapter getTypeAdapter(Class<?> accept, Class<?> produce);
184
185    /**
186     * Adapts an object to a target type if possible otherwise throws an exception. The method must be called in an
187     * operation execution with a valid operation context.
188     */
189    <T> T getAdaptedValue(OperationContext ctx, Object toAdapt, Class<?> targetType) throws OperationException;
190
191    /**
192     * Checks whether or not the given type is adaptable into the target type. An instance of an adaptable type can be
193     * converted into an instance of the target type.
194     * <p>
195     * This is a shortcut to <code>getTypeAdapter(typeToAdapt, targetType) != null</code>
196     */
197    boolean isTypeAdaptable(Class<?> typeToAdapt, Class<?> targetType);
198
199    /**
200     * Generates a documentation model for all registered operations. The documentation model is generated from
201     * operation annotations and can be used in UI tools to describe operations. The returned list is sorted using
202     * operation ID. Optional method.
203     */
204    List<OperationDocumentation> getDocumentation() throws OperationException;
205
206    /**
207     * @since 5.7.2
208     * @param id operation ID
209     * @return true if operation registry contains the given operation
210     */
211    boolean hasOperation(String id);
212
213    /**
214     * @since 5.7.3
215     */
216    void putChainException(ChainException exceptionChain);
217
218    /**
219     * @since 5.7.3
220     */
221    void removeExceptionChain(ChainException exceptionChain);
222
223    /**
224     * @since 5.7.3
225     */
226    ChainException[] getChainExceptions();
227
228    /**
229     * @since 5.7.3
230     */
231    ChainException getChainException(String onChainId);
232
233    /**
234     * @since 5.7.3
235     */
236    void putAutomationFilter(AutomationFilter automationFilter);
237
238    /**
239     * @since 5.7.3
240     */
241    void removeAutomationFilter(AutomationFilter automationFilter);
242
243    /**
244     * @since 5.7.3
245     */
246    AutomationFilter getAutomationFilter(String id);
247
248    /**
249     * @since 5.7.3
250     */
251    AutomationFilter[] getAutomationFilters();
252
253    /**
254     * @since 5.7.3
255     */
256    boolean hasChainException(String onChainId);
257
258    /**
259     * @since 5.9.5
260     */
261    void putOperation(Class<?> type, boolean replace, String contributingComponent,
262            List<WidgetDefinition> widgetDefinitionList) throws OperationException;
263
264    /**
265     * This running method execute operation process through a new transaction.
266     *
267     * @param ctx the operation context.
268     * @param chainId the chain Id.
269     * @param chainParameters chain parameters.
270     * @param timeout Transaction timeout.
271     * @param rollbackGlobalOnError Rollback or not transaction after failing.
272     * @since 6.0
273     */
274    Object runInNewTx(OperationContext ctx, String chainId, Map<String,?> chainParameters, Integer timeout,
275            boolean rollbackGlobalOnError) throws OperationException;
276}