package org.springframework.roo.process.manager; import org.springframework.roo.file.monitor.FileMonitorService; import org.springframework.roo.file.undo.UndoManager; import org.springframework.roo.metadata.MetadataService; import org.springframework.roo.process.manager.event.ProcessManagerStatus; import org.springframework.roo.process.manager.event.ProcessManagerStatusProvider; /** * Provides coordinated execution of major ROO operations. * <p> * A {@link ProcessManager} delivers: * <ul> * <li>A well-defined state publication model via * {@link ProcessManagerStatusProvider}</li> * <li>Startup-time registration of the initial monitoring requests (after the * {@link #completeStartup()} method has been called)</li> * <li>Specific scanning of {@link FileMonitorService} at well-defined times</li> * <li>The ability to execute {@link CommandCallback}s for user-requested * operations</li> * <li>An assurance the above is conducted within a "transaction-like" model</li> * </ul> * <p> * Once constructed, all methods in {@link ProcessManager} operate in a * "transaction-like" manner. This is achieved by use of a {@link FileManager} * that shares the same {@link UndoManager}. * <p> * Once available, a {@link ProcessManager} will ordinarily wait for either * {@link #backgroundScan()} or {@link #execute(CommandCallback)}. It will block * until the state of the {@link ProcessManager} returns to * {@link ProcessManagerStatus#AVAILABLE}. * <p> * {@link ProcessManager} guarantees: * <ul> * <li>The status will remain {@link ProcessManagerStatus#STARTING} until * {@link #completeStartup()} has been called. This is intended to allow objects * depending on {@link ProcessManager} or other {@link MetadataService}s to be * constructed and register for events. The initial monitoring requests will * only be registered during {@link #completeStartup()}, which therefore * simplifies the design of dependent objects as they generally (i) don't need * to retrieve metadata produced before they were listening and (ii) can freely * modify the file system pursuant to {@link FileManager} with assurance of * correct "transaction" behaviour.</li> * <li>At the end of a successful startup, background scan or command execution, * {@link UndoManager#reset()} method will be called.</li> * <li>An uncaught exception will cause {@link UndoManager#undo()} to be called * (before re-throwing the exception).</li> * <li>A {@link FileMonitorService#scanAll()} will be called after a command is * executed, and will continue to be called until such time as it does not * return any further changes. Such calls will occur within the scope of the * same "transaction" as used for the command.</li> * </ul> * <p> * {@link ProcessManager} implementations also guarantee to update * {@link ActiveProcessManager} whenever running an operation, and clear it when * an operation completes. * * @author Ben Alex * @since 1.0 */ public interface ProcessManager extends ProcessManagerStatusProvider { /** * Execute a user command within a "transaction". This method blocks until * {@link ProcessManagerStatus#AVAILABLE}. * <p> * This method may throw {@link RuntimeException}s that occurred while * executing. * * @param <T> the class of the object that * {@link CommandCallback#callback()} will return (required) * @param callback the callback to actually executed (required) * @return the result of executing the callback */ <T> T execute(CommandCallback<T> callback); long getLastScanDuration(); long getMinimumDelayBetweenScan(); /** * @return true if the system is in development mode, which generally means * more detailed diagnostics are requested from add-ons (defaults to * false) */ boolean isDevelopmentMode(); void setDevelopmentMode(boolean developmentMode); void setMinimumDelayBetweenScan(long minimumDelayBetweenScan); /** * Allows the process manager to terminate gracefully. In particular this * means any background threads it has started are terminated. It is safe to * call this method more than once, but no other method in the process * manager need operate correctly after termination. */ void terminate(); void timerBasedScan(); }