/***************************************************************************** This file is part of Git-Starteam. Git-Starteam is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Git-Starteam is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Git-Starteam. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package org.sync; import java.util.HashMap; import java.util.Map; import com.starbase.starteam.File; import com.starbase.starteam.Folder; import com.starbase.starteam.Item; import com.starbase.starteam.View; import com.starbase.util.FileUtils; /** * RenameFinder searches for rename events and caches results. * History items are not stored in the StarTeam cache and result in terrible performance, * so this class provides the necessary caching. * * This class is not threadsafe. */ public class RenameFinder { private Map<Folder, Folder> folderCache = new HashMap<Folder, Folder>(); /** * Returns the item after startTime when oldPath was renamed to file in view. * Searches file and it's folders for a rename event between those two times. * Returns null if a rename event is not found. */ public Item findEventItem(View view, String oldPath, String newPath, File file, long startTime) { String oldFolderName = FileUtils.getParent(oldPath, "/"); String folderName = FileUtils.getParent(newPath, "/"); String oldFileName = FileUtils.getName(oldPath, "/"); // We could try to be clever here and use an ItemList to populate all of the history // item properties in a single trip, but each .getHistory() call will trigger a // round trip. There's a good chance we won't even need the history, so don't bother. // file was probably renamed during the time period if (!oldFileName.equals(file.getName())) { Item[] hist = file.getHistory(); for (int i = 0; i < hist.length; i++) { File item = (File) hist[i]; long time = item.getModifiedTime().getLongValue(); if (time < startTime) { break; } if (i+1 < hist.length && item.getName().equals(file.getName()) && ((File)hist[i+1]).getName().equals(oldFileName)) { return item; } } } // some folder was probably renamed during the time period if (null != oldFolderName && !oldFolderName.equals(folderName)) { for (Folder folder = file.getParentFolder(); folder != null; folder = folder.getParentFolder()) { Folder item = folderCache.get(folder); if (item != null) { return item; } Item[] hist = folder.getHistory(); for (int i = 0; i < hist.length; i++) { item = (Folder) hist[i]; long time = item.getModifiedTime().getLongValue(); if (time < startTime) { break; } if (i + 1 < hist.length && !item.getName().equals(((Folder) hist[i + 1]).getName())) { cacheFolders(file.getParentFolder(), folder, item); return item; } } } } return null; } private void cacheFolders(Folder start, Folder end, Folder item) { for (Folder f = start; !f.equals(end); f = f.getParentFolder()) { folderCache.put(f, item); } folderCache.put(end, item); } }