package org.jboss.loom.actions; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.jboss.loom.ctx.MigrationContext; import org.jboss.loom.ex.MigrationException; import org.jboss.loom.migrators._ext.process.ContextsStack; import org.jboss.loom.spi.IMigrator; import org.jboss.loom.tools.report.adapters.ToHashCodeAdapter; /** * Actions of which the migration consists. * * An action must implement lifecycle callbacks: * preValidate(), backup(), perform(), postValidate(), cleanBackup(), rollback(). * * It should contain information about where it why created - * what config piece of the source server it carries. * * Also it should be able to tell by which Migrator it was created * and ideally, at what place in the code (for exceptions). * * It may contain warnings if some validation failed * but doesn't prevent successful run (also see {@link Configuration.IfExists}). * * It keeps a reference to MigrationContext which is needed in perform(). * * @Jira MIGR-31 and MIGR-23. * @author Ondrej Zizka, ozizka at redhat.com */ @XmlRootElement(name="action") @XmlAccessorType( XmlAccessType.NONE ) public interface IMigrationAction extends ContextsStack.IPropagable { /** * State management - basically, a helper state to check in case * the lifecycle methods were called in wrong order. * Should be only used by actions themselves. */ enum State { INITIAL, BACKED_UP, DONE, FINISHED, ROLLED_BACK } State getState(); // Data /** Why was this action created. I.e. what AS 5 config piece is it's counterpart? */ @XmlElement(name = "originMsg") String getOriginMessage(); /** Where was this action created. (Debug purposes) */ StackTraceElement getOriginStackTrace(); /** Which migrator created this action. */ Class<? extends IMigrator> getFromMigrator(); @XmlElementWrapper(name = "dependencies") @XmlElement(name = "dep") @XmlJavaTypeAdapter( ToHashCodeAdapter.class ) List<IMigrationAction> getDependencies(); IMigrationAction addDependency( IMigrationAction dep ); /** * @returns -1 if doesn't depend, 0 if equals, 1 if direct dependency, or the distance of transitive dependency. */ public int dependsOn( IMigrationAction other ) throws AbstractStatefulAction.CircularDependencyException; /** * @returns A description of this action in terms of what exactly would it do. */ @XmlElement(name = "desc") // Doesn't work - JAXB needs a getter. String toDescription(); @XmlElementWrapper(name="warnings") @XmlElement(name="warning") List<String> getWarnings(); // Implementation stuff void setMigrationContext(MigrationContext ctx); MigrationContext getMigrationContext(); // "Lifecycle" /** * Checks whether this action can be performed under current conditions. * E.g. action for file copying would check if the file exists and is readable, * and if the destination file does not exists or is allowed to be overwritten and is writable. */ void preValidate() throws MigrationException; /** * Performs whatever is necessary to roll back the action after it was performed. * Data are stored in this action object. * Data stored by this method will be used in rollback(). */ void backup() throws MigrationException; /** * Actually performs the action - does the real change: * Copies the file, sends a CLI command. */ void perform() throws MigrationException; /** * Checks if the actions went well, e.g check if the file was copied etc. * May be no-op for certain operations which went well if perform() didn't throw. */ void postValidate() throws MigrationException; /** * Cleans anything created by the backup() method, e.g a backup file. */ void cleanBackup(); /** * Undoes whatever was done by perform(). Uses data stored in this action by backup(). * * @throws MigrationException */ void rollback() throws MigrationException; }// class