/******************************************************************************* * 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.IBuildStore; import com.buildml.model.IPackageMgr; import com.buildml.model.IPackageRootMgr; /** * An undo/redo operation for any change that is made to a package. 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 PackageUndoOp implements IUndoOp { /*=====================================================================================* * FIELDS/TYPES *=====================================================================================*/ /** * Bitmap of all the parts of the package that have changed, and will need to be changed * back on an undo/redo operation. */ private final static int NEW_PACKAGE = 1; private final static int NEW_FOLDER = 2; private final static int REMOVE_PACKAGE = 4; private final static int REMOVE_FOLDER = 8; private final static int RENAME = 16; private final static int MOVE = 32; private final static int CHANGE_ROOTS = 64; /** The fields of this operation that have changed - see above bitmap */ private int changedFields = 0; /** The ID of the package being changed */ private int pkgId; /** For RENAME, REMOVE_PACKAGE and REMOVE_FOLDER, what is the old name */ private String oldName; /** For RENAME, NEW_PACKAGE and NEW_FOLDER, what is the new name */ private String newName; /** For MOVE, the old parent ID */ private int oldParentId; /** For MOVE, NEW_PACKAGE, NEW_FOLDER, REMOVE_PACKAGE, REMOVE_FOLDER, the new parent ID */ private int newParentId; /** For CHANGE_ROOTS, the source path root, before the change */ private int oldSrcRootPathId; /** For CHANGE_ROOTS, The generated path root, before the change */ private int oldGenRootPathId; /** For CHANGE_ROOTS, the source path root, after the change */ private int newSrcRootPathId; /** For CHANGE_ROOTS, the generated path root, after the change */ private int newGenRootPathId; /** Our IPackageMgr for operating on */ private IPackageMgr pkgMgr; /** Our IPackageRootMgr for operating on */ private IPackageRootMgr pkgRootMgr; /*=====================================================================================* * CONSTRUCTORS *=====================================================================================*/ /** * Create a new {@link PackageUndoOp} object, representing a single entry on the * undo/redo stack. * * @param buildStore The IBuildStore we're performing the operation on. * @param pkgId The packageMgr ID of the package being changed. */ public PackageUndoOp(IBuildStore buildStore, int pkgId) { this.pkgId = pkgId; this.pkgMgr = buildStore.getPackageMgr(); this.pkgRootMgr = buildStore.getPackageRootMgr(); this.changedFields = 0; } /*-------------------------------------------------------------------------------------*/ /** * Record the creation of a new package. * * @param newName The name of the package. * @param parentId The parent folder's ID. */ public void recordNewPackage(String newName, int parentId) { changedFields |= NEW_PACKAGE; this.newName = newName; this.newParentId = parentId; } /*-------------------------------------------------------------------------------------*/ /** * Record the creation of a new folder. * * @param newName The name of the folder. * @param parentId The parent folder's ID. */ public void recordNewFolder(String newName, int parentId) { changedFields |= NEW_FOLDER; this.newName = newName; this.newParentId = parentId; } /*-------------------------------------------------------------------------------------*/ /** * Record the removal of this package. * * @param oldName The package's current name. * @param oldParentId The package's current parent ID. */ public void recordRemovePackage(String oldName, int oldParentId) { changedFields |= REMOVE_PACKAGE; this.oldName = oldName; this.oldParentId = oldParentId; } /*-------------------------------------------------------------------------------------*/ /** * Record the removal of this folder. * * @param oldName The folder's current name. * @param oldParentId The folder's current parent ID. */ public void recordRemoveFolder(String oldName, int oldParentId) { changedFields |= REMOVE_FOLDER; this.oldName = oldName; this.oldParentId = oldParentId; } /*-------------------------------------------------------------------------------------*/ /** * Record the package/folder's name change. * * @param oldName The current name for the package/folder. * @param newName The new name for the package/folder. */ public void recordRename(String oldName, String newName) { if (oldName.equals(newName)) { return; } changedFields |= RENAME; this.newName = newName; this.oldName = oldName; } /*-------------------------------------------------------------------------------------*/ /** * Record the package/folder's new parent. * * @param oldParentId The package/folder's old parent ID. * @param newParentId The package/folder's new parent ID. */ public void recordMove(int oldParentId, int newParentId) { if (oldParentId == newParentId) { return; } changedFields |= MOVE; this.oldParentId = oldParentId; this.newParentId = newParentId; } /*-------------------------------------------------------------------------------------*/ /** * Record a change in the package's roots. * * @param oldSrcRootPathId The existing source root path ID. * @param oldGenRootPathId The existing generated root path ID. * @param newSrcRootPathId The new source root path ID. * @param newGenRootPathId The new generated root path ID. */ public void recordRootChange( int oldSrcRootPathId, int oldGenRootPathId, int newSrcRootPathId, int newGenRootPathId) { if ((oldSrcRootPathId == newSrcRootPathId) && (oldGenRootPathId == newGenRootPathId)) { return; } changedFields |= CHANGE_ROOTS; this.oldSrcRootPathId = oldSrcRootPathId; this.oldGenRootPathId = oldGenRootPathId; this.newSrcRootPathId = newSrcRootPathId; this.newGenRootPathId = newGenRootPathId; } /*=====================================================================================* * PUBLIC METHODS *=====================================================================================*/ /* (non-Javadoc) * @see com.buildml.model.undo.IUndoOp#undo() */ @Override public boolean undo() { /* undo the NEW_PACKAGE command */ if ((changedFields & NEW_PACKAGE) != 0) { pkgMgr.remove(pkgId); } /* undo the NEW_FOLDER command */ if ((changedFields & NEW_FOLDER) != 0) { pkgMgr.remove(pkgId); } /* undo the RENAME command */ if ((changedFields & RENAME) != 0) { pkgMgr.setName(pkgId, oldName); } /* undo the REMOVE_PACKAGE command */ if ((changedFields & REMOVE_PACKAGE) != 0) { pkgId = pkgMgr.addPackage(oldName); if (pkgId >= 0) { pkgMgr.setParent(pkgId, oldParentId); } } /* undo the REMOVE_FOLDER command */ if ((changedFields & REMOVE_FOLDER) != 0) { pkgId = pkgMgr.addFolder(oldName); if (pkgId >= 0) { pkgMgr.setParent(pkgId, oldParentId); } } /* undo the MOVE command */ if ((changedFields & MOVE) != 0) { pkgMgr.setParent(pkgId, oldParentId); } /* undo the CHANGE_ROOTS command */ if ((changedFields & CHANGE_ROOTS) != 0) { pkgRootMgr.setPackageRoot(pkgId, IPackageRootMgr.SOURCE_ROOT, oldSrcRootPathId); pkgRootMgr.setPackageRoot(pkgId, IPackageRootMgr.GENERATED_ROOT, oldGenRootPathId); } return (changedFields != 0); } /*-------------------------------------------------------------------------------------*/ /* (non-Javadoc) * @see com.buildml.model.undo.IUndoOp#redo() */ @Override public boolean redo() { /* do/redo the NEW_PACKAGE command */ if ((changedFields & NEW_PACKAGE) != 0) { pkgId = pkgMgr.addPackage(newName); if (pkgId >= 0) { pkgMgr.setParent(pkgId, newParentId); } } /* do/redo the NEW_FOLDER command */ if ((changedFields & NEW_FOLDER) != 0) { pkgId = pkgMgr.addFolder(newName); if (pkgId >= 0) { pkgMgr.setParent(pkgId, newParentId); } } /* do/redo the RENAME command */ if ((changedFields & RENAME) != 0) { pkgMgr.setName(pkgId, newName); } /* do/redo the REMOVE_PACKAGE command */ if ((changedFields & REMOVE_PACKAGE) != 0) { pkgMgr.remove(pkgId); } /* do/redo the REMOVE_FOLDER command */ if ((changedFields & REMOVE_FOLDER) != 0) { pkgMgr.remove(pkgId); } /* do/redo the MOVE command */ if ((changedFields & MOVE) != 0) { pkgMgr.setParent(pkgId, newParentId); } /* do/redo the CHANGE_ROOTS command */ if ((changedFields & CHANGE_ROOTS) != 0) { pkgRootMgr.setPackageRoot(pkgId, IPackageRootMgr.SOURCE_ROOT, newSrcRootPathId); pkgRootMgr.setPackageRoot(pkgId, IPackageRootMgr.GENERATED_ROOT, newGenRootPathId); } return (changedFields != 0); } /*-------------------------------------------------------------------------------------*/ }