/******************************************************************************* * Copyright (c) 2013 Arapiki Solutions Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * psmith - initial API and * implementation and/or initial documentation *******************************************************************************/ package com.buildml.model.undo; import com.buildml.model.FatalBuildStoreError; import com.buildml.model.IBuildStore; import com.buildml.model.IFileMgr; import com.buildml.model.IPackageMemberMgr; import com.buildml.utils.errors.ErrorCode; /** * An undo/redo operation for any change that is made to a path. This object records the * details of the changes necessary to the IBuildStore so they can be undone or redone later. * * @author Peter Smith <psmith@arapiki.com> */ public class FileUndoOp implements IUndoOp { /*=====================================================================================* * FIELDS/TYPES *=====================================================================================*/ /** * Bitmap of all the parts of the path that have changed, and will need to be changed * back on an undo/redo operation. */ private final static int REMOVE_PATH = 1; private final static int CHANGE_PACKAGE = 2; /** The IBuildStore we're operating on */ private IBuildStore buildStore; /** The fields of this operation that have changed - see above bitmap */ private int changedFields = 0; /** The ID of the path being changed */ private int pathId; /** For CHANGE_PACKAGE, what is the current package ID */ private int oldPkgId; /** For CHANGE_PACKAGE, what is the new package ID */ private int newPkgId; /** For CHANGE_PACKAGE, what is the current scope ID */ private int oldScopeId; /** For CHANGE_PACKAGE, what is the new scope ID */ private int newScopeId; /*=====================================================================================* * CONSTRUCTORS *=====================================================================================*/ /** * Create a new {@link FileUndoOp} object, representing a single entry on the * undo/redo stack. * * @param buildStore The IBuildStore we're performing the operation on. * @param pathId The fileMgr ID of the path being changed. */ public FileUndoOp(IBuildStore buildStore, int pathId) { this.buildStore = buildStore; this.pathId = pathId; } /*=====================================================================================* * PUBLIC METHODS *=====================================================================================*/ /** * Record the fact that the path is being trashed. */ public void recordRemovePath() { changedFields |= REMOVE_PATH; } /*-------------------------------------------------------------------------------------*/ /** * Record the fact that a path has moved into a different package. * * @param oldPkgId ID of the path's current package. * @param oldScopeId ID of the path's current scope. * @param newPkgId ID of the path's new package. * @param newScopeId ID of the path's new scope. */ public void recordChangePackage(int oldPkgId, int oldScopeId, int newPkgId, int newScopeId) { if ((oldPkgId == newPkgId) && (oldScopeId == newScopeId)) { return; } changedFields |= CHANGE_PACKAGE; this.oldPkgId = oldPkgId; this.newPkgId = newPkgId; this.oldScopeId = oldScopeId; this.newScopeId = newScopeId; } /*-------------------------------------------------------------------------------------*/ /* (non-Javadoc) * @see com.buildml.model.undo.IUndoOp.undo() */ @Override public boolean undo() { IFileMgr fileMgr = buildStore.getFileMgr(); IPackageMemberMgr pkgMemberMgr = buildStore.getPackageMemberMgr(); /* undo removal of a path */ if ((changedFields & REMOVE_PATH) != 0) { if (fileMgr.revivePathFromTrash(pathId) != ErrorCode.OK) { throw new FatalBuildStoreError( "Unable to revive file from trash: " + fileMgr.getPathName(pathId)); } } /* undo the change of package/scope */ if ((changedFields & CHANGE_PACKAGE) != 0) { pkgMemberMgr.setPackageOfMember(IPackageMemberMgr.TYPE_FILE, pathId, oldPkgId, oldScopeId); } return (changedFields != 0); } /*-------------------------------------------------------------------------------------*/ /* (non-Javadoc) * @see com.buildml.model.undo.IUndoOp.redo() */ @Override public boolean redo() { IFileMgr fileMgr = buildStore.getFileMgr(); IPackageMemberMgr pkgMemberMgr = buildStore.getPackageMemberMgr(); /* do/redo removal of a path */ if ((changedFields & REMOVE_PATH) != 0) { if (fileMgr.movePathToTrash(pathId) != ErrorCode.OK) { throw new FatalBuildStoreError( "Unable to move file to trash: " + fileMgr.getPathName(pathId)); } } /* do/redo the change of package/scope */ if ((changedFields & CHANGE_PACKAGE) != 0) { pkgMemberMgr.setPackageOfMember(IPackageMemberMgr.TYPE_FILE, pathId, newPkgId, newScopeId); } /* if there's a change, mark the editor as dirty */ return (changedFields != 0); } /*-------------------------------------------------------------------------------------*/ }