diff options
author | Malgorzata Janczarska | 2012-03-13 13:51:46 +0000 |
---|---|---|
committer | Malgorzata Janczarska | 2012-03-13 13:51:46 +0000 |
commit | 78b06e932f107395de4ac4bad9a6113a78639766 (patch) | |
tree | 0de82b0acae224f540305bf67e1d09dc188ac040 | |
parent | 9dc5b700ad5d2dc49a8ff00037ec8f5763cdc2b4 (diff) | |
download | eclipse.platform.team-78b06e932f107395de4ac4bad9a6113a78639766.tar.gz eclipse.platform.team-78b06e932f107395de4ac4bad9a6113a78639766.tar.xz eclipse.platform.team-78b06e932f107395de4ac4bad9a6113a78639766.zip |
CVS cache does not contain precise information about tagsv20120313-1351
Bug: 372862
Change-Id: I80044e6df28f42c3973b7d16d5d7c92f54bcd8cb
7 files changed, 874 insertions, 289 deletions
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSTagElement.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSTagElement.java index 900c9395c..b1069b007 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSTagElement.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSTagElement.java @@ -11,9 +11,10 @@ package org.eclipse.team.internal.ccvs.ui.model; import java.lang.reflect.InvocationTargetException; -import java.util.*; +import java.util.Date; +import java.util.Locale; -import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.osgi.util.NLS; @@ -24,7 +25,6 @@ import org.eclipse.team.internal.ccvs.ui.*; import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ccvs.ui.operations.FetchMembersOperation; import org.eclipse.team.internal.ccvs.ui.operations.FetchMembersOperation.RemoteFolderFilter; -import org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot; import org.eclipse.ui.progress.IDeferredWorkbenchAdapter; import org.eclipse.ui.progress.IElementCollector; @@ -115,66 +115,13 @@ public class CVSTagElement extends CVSModelElement implements IDeferredWorkbench return ((CVSTagElement) o).root; } - protected Object[] fetchChildren(Object o, IProgressMonitor monitor) - throws TeamException { - if (tag.getType() == CVSTag.BRANCH) { - monitor = Policy.monitorFor(monitor); - monitor.beginTask(NLS.bind( - CVSUIMessages.RemoteFolderElement_fetchingRemoteChildren, - new String[] { root.toString() }), 100); - try { - ICVSRemoteResource[] children = CVSUIPlugin - .getPlugin() - .getRepositoryManager() - .getFoldersForTag(root, tag, - Policy.subMonitorFor(monitor, 50)); - if (getWorkingSet() != null) - children = CVSUIPlugin.getPlugin().getRepositoryManager() - .filterResources(getWorkingSet(), children); - return getTopLevelRemoteFolders(children, - Policy.subMonitorFor(monitor, 50)); - } finally { - monitor.done(); - } - } + protected Object[] fetchChildren(Object o, IProgressMonitor monitor) throws TeamException { ICVSRemoteResource[] children = CVSUIPlugin.getPlugin().getRepositoryManager().getFoldersForTag(root, tag, monitor); if (getWorkingSet() != null) children = CVSUIPlugin.getPlugin().getRepositoryManager().filterResources(getWorkingSet(), children); return children; } - private ICVSRemoteResource[] getTopLevelRemoteFolders( - ICVSRemoteResource[] children, IProgressMonitor monitor) - throws CVSException { - Set result = new HashSet(); - monitor.beginTask(NLS.bind( - CVSUIMessages.RemoteFolderElement_fetchingRemoteChildren, - new String[] { root.toString() }), children.length); - try { - RepositoryRoot repositoryRoot = CVSUIPlugin.getPlugin() - .getRepositoryManager().getRepositoryRootFor(root); - for (int i = 0; i < children.length; i++) { - result.add(getTopLevelRemoteFolder(children[i], repositoryRoot, - Policy.subMonitorFor(monitor, 1))); - } - return (ICVSRemoteResource[]) result - .toArray(new ICVSRemoteResource[result.size()]); - } finally { - monitor.done(); - } - } - - private ICVSRemoteResource getTopLevelRemoteFolder( - ICVSRemoteResource remoteResource, RepositoryRoot repositoryRoot, - IProgressMonitor monitor) throws CVSException { - IPath repositoryPath = new Path( - remoteResource.getRepositoryRelativePath()); - if (repositoryPath.segmentCount() == 1) - return remoteResource; - return repositoryRoot.getRemoteFolder(repositoryPath.segment(0), tag, - monitor); - } - public void fetchDeferredChildren(Object o, IElementCollector collector, IProgressMonitor monitor) { if (tag.getType() == CVSTag.HEAD || tag.getType() == CVSTag.DATE) { try { diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteFolderElement.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteFolderElement.java index e5c794650..52a3bb65a 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteFolderElement.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteFolderElement.java @@ -11,11 +11,7 @@ package org.eclipse.team.internal.ccvs.ui.model; import java.lang.reflect.InvocationTargetException; -import java.util.HashSet; -import java.util.Set; - import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.osgi.util.NLS; @@ -24,7 +20,6 @@ import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.ui.*; import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ccvs.ui.operations.FetchMembersOperation; -import org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.IDeferredWorkbenchAdapter; @@ -62,68 +57,50 @@ public class RemoteFolderElement extends RemoteResourceElement implements IDefer public Object[] fetchChildren(Object o, IProgressMonitor monitor) throws TeamException { if (!(o instanceof ICVSRemoteFolder)) return new Object[0]; - ICVSRemoteFolder remoteFolder = (ICVSRemoteFolder) o; - if (remoteFolder.getTag() != null - && remoteFolder.getTag().getType() == CVSTag.BRANCH) { + try { monitor = Policy.monitorFor(monitor); monitor.beginTask(NLS.bind( CVSUIMessages.RemoteFolderElement_fetchingRemoteChildren, - new String[] { getLabel(remoteFolder) }), 100); - try { - ICVSRemoteResource[] cachedFolders = CVSUIPlugin - .getPlugin() - .getRepositoryManager() - .getFoldersForTag(remoteFolder.getRepository(), - remoteFolder.getTag(), - Policy.subMonitorFor(monitor, 50)); - if (!hasCachedParent(cachedFolders, remoteFolder)) { - return getCachedChildren(cachedFolders, remoteFolder, - Policy.subMonitorFor(monitor, 50)); - } - return remoteFolder.members(Policy.subMonitorFor(monitor, 50)); - } finally { - monitor.done(); + new String[] { getLabel(o) }), 100); + ICVSRemoteFolder folder = (ICVSRemoteFolder) o; + ICVSRemoteResource[] cachedChildren = CVSUIPlugin + .getPlugin() + .getRepositoryManager() + .getCachedChildrenForTag(folder.getRepository(), folder, + folder.getTag(), Policy.subMonitorFor(monitor, 50)); + if (cachedChildren.length > 0) { + return cachedChildren; } + return folder.members(Policy.subMonitorFor(monitor, 50)); + } finally { + monitor.done(); } - return remoteFolder.members(monitor); - } + } public void fetchDeferredChildren(Object o, IElementCollector collector, IProgressMonitor monitor) { // If it's not a folder, return an empty array if (!(o instanceof ICVSRemoteFolder)) { collector.add(new Object[0], monitor); } - try { - monitor = Policy.monitorFor(monitor); - ICVSRemoteFolder remoteFolder = (ICVSRemoteFolder) o; - if (remoteFolder.getTag() != null - && remoteFolder.getTag().getType() == CVSTag.BRANCH) { - monitor.beginTask( - NLS.bind( - CVSUIMessages.RemoteFolderElement_fetchingRemoteChildren, - new String[] { getLabel(o) }), 200); - ICVSRemoteResource[] cachedFolders = CVSUIPlugin - .getPlugin() - .getRepositoryManager() - .getFoldersForTag(remoteFolder.getRepository(), - remoteFolder.getTag(), - Policy.subMonitorFor(monitor, 100)); - if (!hasCachedParent(cachedFolders, remoteFolder)) { - collector.add( - getCachedChildren(cachedFolders, remoteFolder, - Policy.subMonitorFor(monitor, 90)), Policy - .subMonitorFor(monitor, 10)); - return; - } - } else { - monitor.beginTask( - NLS.bind( - CVSUIMessages.RemoteFolderElement_fetchingRemoteChildren, - new String[] { getLabel(o) }), 100); + try { + monitor = Policy.monitorFor(monitor); + monitor.beginTask(NLS.bind( + CVSUIMessages.RemoteFolderElement_fetchingRemoteChildren, + new String[] { getLabel(o) }), 100); + ICVSRemoteFolder folder = (ICVSRemoteFolder) o; + ICVSRemoteResource[] cachedChildren = CVSUIPlugin + .getPlugin() + .getRepositoryManager() + .getCachedChildrenForTag(folder.getRepository(), folder, + folder.getTag(), Policy.subMonitorFor(monitor, 50)); + if (cachedChildren.length > 0) { + collector.add(cachedChildren, monitor); + return; } - FetchMembersOperation operation = new FetchMembersOperation(null, (ICVSRemoteFolder)o, collector); - operation.run(Policy.subMonitorFor(monitor, 100)); - } catch (InvocationTargetException e) { + FetchMembersOperation operation = new FetchMembersOperation(null, + folder, collector); + operation.run(Policy.subMonitorFor(monitor, 50)); + } catch (InvocationTargetException e) { handle(collector, e); } catch (InterruptedException e) { // Cancelled by the user; @@ -134,50 +111,6 @@ public class RemoteFolderElement extends RemoteResourceElement implements IDefer } } - private boolean hasCachedParent(ICVSRemoteResource[] cachedFolders, - ICVSRemoteFolder remoteFolder) { - for (int i = 0; i < cachedFolders.length; i++) { - if (remoteFolder.getRepositoryRelativePath().startsWith( - cachedFolders[i].getRepositoryRelativePath())) { - return true; - } - } - return false; - } - - private ICVSRemoteResource[] getCachedChildren( - ICVSRemoteResource[] cachedFolders, ICVSRemoteFolder remoteFolder, - IProgressMonitor monitor) { - Set remoteResources = new HashSet(); - monitor = Policy.monitorFor(monitor); - monitor.beginTask(NLS.bind( - CVSUIMessages.RemoteFolderElement_fetchingRemoteChildren, - new String[] { getLabel(remoteFolder) }), cachedFolders.length); - try { - RepositoryRoot repositoryRoot = CVSUIPlugin.getPlugin() - .getRepositoryManager() - .getRepositoryRootFor(remoteFolder.getRepository()); - for (int i = 0; i < cachedFolders.length; i++) { - if (cachedFolders[i].getRepositoryRelativePath().startsWith( - remoteFolder.getRepositoryRelativePath())) { - String path = new Path( - cachedFolders[i].getRepositoryRelativePath()) - .uptoSegment( - new Path(remoteFolder - .getRepositoryRelativePath()) - .segmentCount() + 1).toString(); - remoteResources.add(repositoryRoot.getRemoteFolder(path, - remoteFolder.getTag(), - Policy.subMonitorFor(monitor, 1))); - } - } - return (ICVSRemoteResource[]) remoteResources - .toArray(new ICVSRemoteResource[remoteResources.size()]); - } finally { - monitor.done(); - } - } - public ISchedulingRule getRule(Object element) { ICVSRepositoryLocation location = getRepositoryLocation(element); return new RepositoryLocationSchedulingRule(location); diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java index 829a4cc10..948ec1e40 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * 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 @@ -142,15 +142,11 @@ public class RepositoryManager { Set result = new HashSet(); RepositoryRoot root = (RepositoryRoot)repositoryRoots.get(location.getLocation(false)); if (root != null) { - String[] paths = root.getKnownRemotePaths(); - for (int i = 0; i < paths.length; i++) { - String path = paths[i]; - CVSTag[] tags = root.getAllKnownTags(path); - for (int j = 0; j < tags.length; j++) { - CVSTag tag = tags[j]; - if (tag.getType() == tagType) - result.add(tag); - } + CVSTag[] tags = root.getAllKnownTags(); + for (int i = 0; i < tags.length; i++) { + CVSTag tag = tags[i]; + if (tag.getType() == tagType) + result.add(tag); } } return (CVSTag[])result.toArray(new CVSTag[0]); @@ -225,20 +221,72 @@ public class RepositoryManager { Set result = new HashSet(); // Get the tags for the location RepositoryRoot root = getRepositoryRootFor(location); - String[] paths = root.getKnownRemotePaths(); + String[] paths = root.getRemoteChildrenForTag(null, tag); for (int i = 0; i < paths.length; i++) { String path = paths[i]; - List tags = Arrays.asList(root.getAllKnownTags(path)); - if (tags.contains(tag)) { - ICVSRemoteFolder remote = root.getRemoteFolder(path, tag, Policy.subMonitorFor(monitor, 100)); - result.add(remote); - } + ICVSRemoteFolder remote = root.getRemoteFolder(path, tag, + Policy.subMonitorFor(monitor, 100)); + result.add(remote); } return (ICVSRemoteResource[])result.toArray(new ICVSRemoteResource[result.size()]); } finally { monitor.done(); } } + + /** + * Returns a list of child resources for given folder that are known to + * contain given tag. If the return list is empty than given tag exists + * directly in given folder and its children should be retrieved directly + * from the repository. + * + * NOTE: Resources are cached only for tags of type CVSTag.Branch and + * CVSTag.Version. Other types of tags will always return empty list. + * + * @param location + * CVS repository location + * @param parentFolder + * folder to check tags for + * @param tag + * @param monitor + * @return a list of remote resources that are known to contain given tag or + * empty list if resources should be retrieved from the repository + * @throws CVSException + */ + public ICVSRemoteResource[] getCachedChildrenForTag( + ICVSRepositoryLocation location, ICVSRemoteFolder parentFolder, + CVSTag tag, IProgressMonitor monitor) throws CVSException { + if (tag == null || tag.getType() == CVSTag.HEAD + || tag.getType() == CVSTag.DATE) { + // folders are kept in cache only for tags and versions + return new ICVSRemoteResource[0]; + } + monitor = Policy.monitorFor(monitor); + Set result = new HashSet(); + RepositoryRoot root = getRepositoryRootFor(location); + // if remote folder is null return the subfolders of repository root + String[] paths = root.getRemoteChildrenForTag( + parentFolder == null ? null : RepositoryRoot + .getRemotePathFor(parentFolder), tag); + monitor.beginTask(NLS + .bind(CVSUIMessages.RemoteFolderElement_fetchingRemoteChildren, + new String[] { NLS.bind( + CVSUIMessages.RemoteFolderElement_nameAndTag, + new String[] { parentFolder.getName(), + tag.getName() }) }), 10 * paths.length); + try { + for (int i = 0; i < paths.length; i++) { + String path = paths[i]; + ICVSRemoteFolder remote = root.getRemoteFolder(path, tag, + Policy.subMonitorFor(monitor, 10)); + result.add(remote); + } + return (ICVSRemoteResource[]) result + .toArray(new ICVSRemoteResource[result.size()]); + } finally { + monitor.done(); + } + } /* * Fetches tags from auto-refresh files if they exist. Then fetches tags from the user defined auto-refresh file diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryRoot.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryRoot.java index cc414aba9..7b45f7106 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryRoot.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryRoot.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * 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 @@ -33,8 +33,7 @@ public class RepositoryRoot extends PlatformObject { ICVSRepositoryLocation root; String name; - // Map of String (remote folder path) -> TagCacheEntry - Map versionAndBranchTags = new HashMap(); + TagCacheEntry rootTagCacheEntry = new TagCacheEntry(Path.ROOT, null); // Map of String (remote folder path) -> Set (file paths that are project relative) Map autoRefreshFiles = new HashMap(); // Map of String (module name) -> ICVSRemoteFolder (that is a defined module) @@ -44,12 +43,34 @@ public class RepositoryRoot extends PlatformObject { List dateTags = new ArrayList(); public static class TagCacheEntry { - Set tags = new HashSet(); - long lastAccessTime; - private static final int CACHE_LIFESPAN_IN_DAYS = 7; - public TagCacheEntry() { - accessed(); - } + IPath path; + // Set of tags found for this path + private Set tags = new HashSet(); + // String(last path segment) -> TagCacheEntry for child paths + Map children = new HashMap(); + TagCacheEntry parent; + long lastAccessTime; + private static final int CACHE_LIFESPAN_IN_DAYS = 7; + + public TagCacheEntry(IPath path, TagCacheEntry parent) { + this.path = path; + this.parent = parent; + accessed(); + } + + public Set getTags() { + accessed(); + return tags; + } + + public Iterator getChildrenIterator() { + return this.children.values().iterator(); + } + + public boolean isEmpty() { + return getTags().isEmpty() && children.isEmpty(); + } + public boolean isExpired() { long currentTime = System.currentTimeMillis(); long ms = currentTime - lastAccessTime; @@ -58,9 +79,10 @@ public class RepositoryRoot extends PlatformObject { int days = hours / 24; return days > CACHE_LIFESPAN_IN_DAYS; } - public void accessed() { - lastAccessTime = System.currentTimeMillis(); - } + + private void accessed() { + lastAccessTime = System.currentTimeMillis(); + } } public RepositoryRoot(ICVSRepositoryLocation root) { @@ -189,7 +211,10 @@ public class RepositoryRoot extends PlatformObject { * * It is the responsibility of the caller to ensure that the given remote path is valid. */ - public void addTags(String remotePath, CVSTag[] tags) { + public void addTags(String remotePath, CVSTag[] tags) { + if (tags.length == 0) { + return; + } addDateTags(tags); addVersionAndBranchTags(remotePath, tags); } @@ -201,23 +226,19 @@ public class RepositoryRoot extends PlatformObject { } } } + private void addVersionAndBranchTags(String remotePath, CVSTag[] tags) { - // Get the name to cache the version tags with - String name = getCachePathFor(remotePath); - - // Make sure there is a table for the ancestor that holds the tags - TagCacheEntry entry = (TagCacheEntry)versionAndBranchTags.get(name); - if (entry == null) { - entry = new TagCacheEntry(); - versionAndBranchTags.put(name, entry); - } else { - entry.accessed(); - } - + TagCacheEntry entry = getTagCacheEntryFor(remotePath, true); + // Store the tag with the appropriate ancestor for (int i = 0; i < tags.length; i++) { - if(tags[i].getType() != CVSTag.DATE){ - entry.tags.add(tags[i]); + if (tags[i].getType() != CVSTag.DATE) { + Set parentTags = new HashSet(); + addAllKnownTagsForParents(entry, parentTags); + if (!parentTags.contains(tags[i])) { + entry.getTags().add(tags[i]); + removeTagFromChildrenCacheEntries(entry, tags[i]); + } } } } @@ -263,20 +284,42 @@ public class RepositoryRoot extends PlatformObject { } private void removeVersionAndBranchTags(String remotePath, CVSTag[] tags) { - // Get the name to cache the version tags with - String name = getCachePathFor(remotePath); - - // Make sure there is a table for the ancestor that holds the tags - TagCacheEntry entry = (TagCacheEntry)versionAndBranchTags.get(name); - if (entry == null) { - return; + TagCacheEntry entry = getTagCacheEntryFor(remotePath, false); + // remove tags from this path and its children + if (entry != null) { + removeTagsFromChildrenCacheEntries(entry, tags); } - - // Store the tag with the appropriate ancestor + + // remove tags from all parents of this path + entry = getKnownParentTagCacheEntryFor(remotePath); for (int i = 0; i < tags.length; i++) { - entry.tags.remove(tags[i]); + if (entry.getTags().contains(tags[i])) { + entry.getTags().remove(tags[i]); + continue; + } + TagCacheEntry currentEntry = entry; + while (currentEntry.parent != null) { + if (currentEntry.parent.getTags().contains(tags[i])) { + // remove tag from parent and add it to siblings + currentEntry.parent.getTags().remove(tags[i]); + Iterator siblingIterator = currentEntry.parent + .getChildrenIterator(); + while (siblingIterator.hasNext()) { + TagCacheEntry sibling = (TagCacheEntry) siblingIterator + .next(); + if (!sibling.equals(currentEntry)) { + sibling.getTags().add(tags[i]); + } + } + break; + } else { + currentEntry = currentEntry.parent; + } + } + } + if (entry.isEmpty()) { + removeTagCacheEntry(entry); } - entry.accessed(); } /** @@ -286,8 +329,7 @@ public class RepositoryRoot extends PlatformObject { * @return String[] */ public String[] getAutoRefreshFiles(String remotePath) { - String name = getCachePathFor(remotePath); - Set files = (Set)autoRefreshFiles.get(name); + Set files = (Set) autoRefreshFiles.get(remotePath); if (files == null || files.isEmpty()) { // convert the default relative file paths to full paths if (isDefinedModuleName(remotePath)) { @@ -323,44 +365,64 @@ public class RepositoryRoot extends PlatformObject { } } if (isDefault) { - this.autoRefreshFiles.remove(getCachePathFor(remotePath)); + this.autoRefreshFiles.remove(remotePath); return; } } - this.autoRefreshFiles.put(getCachePathFor(remotePath), newFiles); + this.autoRefreshFiles.put(remotePath, newFiles); } /** * Fetches tags from auto-refresh files. */ - public CVSTag[] refreshDefinedTags(ICVSFolder folder, boolean recurse, IProgressMonitor monitor) throws TeamException { + public CVSTag[] refreshDefinedTags(ICVSFolder folder, boolean recurse, + IProgressMonitor monitor) throws TeamException { monitor = Policy.monitorFor(monitor); - monitor.beginTask(null, 100); - CVSTag[] tags = null; - if (!recurse && !folder.getFolderSyncInfo().isVirtualDirectory()) { - // Only try the auto-refresh file(s) if we are not recursing into sub-folders - tags = fetchTagsUsingAutoRefreshFiles(folder, Policy.subMonitorFor(monitor, 50)); - } - if (tags == null || tags.length == 0) { - // There we're no tags found on the auto-refresh files or we we're aksed to go deep - // Try using the log command - tags = fetchTagsUsingLog(folder, recurse, Policy.subMonitorFor(monitor, 50)); - } - if (tags != null && tags.length > 0) { - String remotePath = getRemotePathFor(folder); - addTags(remotePath, tags); + monitor.beginTask(null, recurse ? 210 : 100); + try { + CVSTag[] tags = null; + if (!folder.getFolderSyncInfo().isVirtualDirectory()) { + // Only try the auto-refresh file(s) if we are not recursing + // into sub-folders + tags = fetchTagsUsingAutoRefreshFiles(folder, + Policy.subMonitorFor(monitor, 50)); + } + if (tags == null || tags.length == 0) { + // There we're no tags found on the auto-refresh files or we + // we're asked to go deep + // Try using the log command + tags = fetchTagsUsingLog(folder, + Policy.subMonitorFor(monitor, 50)); + } + if (tags != null && tags.length > 0) { + String remotePath = getRemotePathFor(folder); + addTags(remotePath, tags); + return tags; + } + if (recurse) { + Set tagsSet = new HashSet(); + folder.fetchChildren(Policy.subMonitorFor(monitor, 10)); + ICVSResource[] children = folder + .members(ICVSFolder.FOLDER_MEMBERS); + for (int i = 0; i < children.length; i++) { + tagsSet.addAll(Arrays.asList(refreshDefinedTags( + (ICVSFolder) children[i], recurse, Policy + .subMonitorFor(monitor, + 100 / children.length)))); + } + tags = (CVSTag[]) tagsSet.toArray(new CVSTag[tagsSet.size()]); + } + return tags; + } finally { + monitor.done(); } - monitor.done(); - return tags; } - - private CVSTag[] fetchTagsUsingLog(ICVSFolder folder, final boolean recurse, IProgressMonitor monitor) throws CVSException { + + private CVSTag[] fetchTagsUsingLog(ICVSFolder folder, IProgressMonitor monitor) throws CVSException { LogEntryCache logEntries = new LogEntryCache(); RemoteLogOperation operation = new RemoteLogOperation(null, new ICVSRemoteResource[] { asRemoteResource(folder) }, null, null, logEntries) { protected Command.LocalOption[] getLocalOptions(CVSTag tag1,CVSTag tag2) { Command.LocalOption[] options = new Command.LocalOption[] {}; - if (recurse) - return options; Command.LocalOption[] newOptions = new Command.LocalOption[options.length + 1]; System.arraycopy(options, 0, newOptions, 0, options.length); newOptions[options.length] = Command.DO_NOT_RECURSE; @@ -442,16 +504,85 @@ public class RepositoryRoot extends PlatformObject { } return (CVSTag[])tagSet.toArray(new CVSTag[0]); } - - /* - * Return the cache key (path) for the given folder path. - * This has been changed to cache the tags directly - * with the folder to better support non-root projects. - * However, resources in the local workspace use the folder - * the project is mapped to as the tag source (see TagSource) - */ - private String getCachePathFor(String remotePath) { - return remotePath; + + private TagCacheEntry getTagCacheEntryFor(String remotePath, boolean create) { + String[] segments = new Path(null, remotePath).segments(); + TagCacheEntry currentTagCacheEntry = rootTagCacheEntry; + for (int i = 0; i < segments.length; i++) { + String segment = segments[i]; + if (currentTagCacheEntry.children.containsKey(segment)) { + currentTagCacheEntry = (TagCacheEntry) currentTagCacheEntry.children + .get(segment); + continue; + } + if (!create) { + return null; + } + TagCacheEntry newTagCacheEntry = new TagCacheEntry(new Path(null, + remotePath).removeLastSegments(segments.length - (i + 1)), + currentTagCacheEntry); + currentTagCacheEntry.children.put(segment, newTagCacheEntry); + currentTagCacheEntry = newTagCacheEntry; + } + return currentTagCacheEntry; + } + + private TagCacheEntry getKnownParentTagCacheEntryFor(String remotePath) { + String[] segments = new Path(null, remotePath).segments(); + TagCacheEntry currentTagCacheEntry = rootTagCacheEntry; + for (int i = 0; i < segments.length; i++) { + String segment = segments[i]; + if (currentTagCacheEntry.children.containsKey(segment)) { + currentTagCacheEntry = (TagCacheEntry) currentTagCacheEntry.children + .get(segment); + } else { + break; // we reached the last existing parent + } + } + return currentTagCacheEntry; + } + + private void removeTagsFromChildrenCacheEntries(TagCacheEntry entry, + CVSTag[] tags) { + for (int i = 0; i < tags.length; i++) { + removeTagFromChildrenCacheEntries(entry, tags[i]); + } + entry.getTags().removeAll(Arrays.asList(tags)); + if (entry.isEmpty()) { + // remove this entry when the last tags where removed + // keep the entry if there are any children that have tags + removeTagCacheEntry(entry); + } + } + + private void removeTagCacheEntry(TagCacheEntry entry) { + if (entry.parent == null) { + // We cannot remove root tag cache entry + return; + } + Map newParentChildren = new HashMap(); + newParentChildren.putAll(entry.parent.children); + newParentChildren.remove(entry.path.lastSegment()); + entry.parent.children = newParentChildren; + if (entry.parent.isEmpty()) { + // remove parents if they no longer carry any value + removeTagCacheEntry(entry.parent); + } + } + + private void removeTagFromChildrenCacheEntries(TagCacheEntry entry, + CVSTag tag) { + Iterator childrenIterator = entry.getChildrenIterator(); + while (childrenIterator.hasNext()) { + TagCacheEntry child = (TagCacheEntry) childrenIterator.next(); + removeTagFromChildrenCacheEntries(child, tag); + child.getTags().remove(tag); + if (child.isEmpty()) { + // remove this entry when the last tag was removed + // keep the entry if there are any children that have tags + removeTagCacheEntry(child); + } + } } /** @@ -496,13 +627,13 @@ public class RepositoryRoot extends PlatformObject { attributes.put(RepositoriesViewContentHandler.TYPE_ATTRIBUTE, RepositoriesViewContentHandler.DEFINED_MODULE_TYPE); } attributes.put(RepositoriesViewContentHandler.PATH_ATTRIBUTE, name); - TagCacheEntry entry = (TagCacheEntry)versionAndBranchTags.get(path); + TagCacheEntry entry = getTagCacheEntryFor(path, false); boolean writeOutTags = entry != null && !entry.isExpired(); if (writeOutTags) attributes.put(RepositoriesViewContentHandler.LAST_ACCESS_TIME_ATTRIBUTE, Long.toString(entry.lastAccessTime)); writer.startTag(RepositoriesViewContentHandler.MODULE_TAG, attributes, true); if (writeOutTags) { - Iterator tagIt = entry.tags.iterator(); + Iterator tagIt = entry.getTags().iterator(); while (tagIt.hasNext()) { CVSTag tag = (CVSTag)tagIt.next(); writeATag(writer, attributes, tag, RepositoriesViewContentHandler.TAG_TAG); @@ -530,34 +661,81 @@ public class RepositoryRoot extends PlatformObject { writer.startAndEndTag(s, attributes, true); } + private void addAllKnownTagsForParents(TagCacheEntry entry, Set tags) { + if (entry.parent != null) { + addAllKnownTagsForParents(entry.parent, tags); + } + tags.addAll(entry.getTags()); + } + + private void addAllKnownTagsForChildren(TagCacheEntry entry, Set tags) { + Iterator childrenIterator = entry.getChildrenIterator(); + while (childrenIterator.hasNext()) { + TagCacheEntry child = (TagCacheEntry) childrenIterator.next(); + addAllKnownTagsForChildren(child, tags); + } + tags.addAll(entry.getTags()); + } + /** * Method getKnownTags. * @param remotePath * @return CVSTag[] */ public CVSTag[] getAllKnownTags(String remotePath) { - TagCacheEntry entry = (TagCacheEntry)versionAndBranchTags.get(getCachePathFor(remotePath)); - if(entry != null){ - entry.accessed(); - CVSTag [] tags1 = (CVSTag[]) entry.tags.toArray(new CVSTag[entry.tags.size()]); - CVSTag[] tags2 = getDateTags(); - int len = tags1.length + tags2.length; - CVSTag[] tags = new CVSTag[len]; - for(int i = 0; i < len; i++){ - if(i < tags1.length){ - tags[i] = tags1[i]; - }else{ - tags[i] = tags2[i-tags1.length]; - } + Set tags = new HashSet(); + addAllKnownTagsForParents(getKnownParentTagCacheEntryFor(remotePath), + tags); + TagCacheEntry entry = getTagCacheEntryFor(remotePath, false); + if (entry != null) { + addAllKnownTagsForChildren(entry, tags); + } + return (CVSTag[]) tags.toArray(new CVSTag[tags.size()]); + } + + public CVSTag[] getAllKnownTags() { + Set tags = new HashSet(); + addAllKnownTagsForChildren(rootTagCacheEntry, tags); + return (CVSTag[]) tags.toArray(new CVSTag[tags.size()]); + } + + public String[] getRemoteChildrenForTag(String remotePath, CVSTag tag) { + TagCacheEntry entry; + if (remotePath == null) { + entry = rootTagCacheEntry; + } else { + entry = getTagCacheEntryFor(remotePath, false); + } + if (entry == null) { + return new String[0]; + } + + Set paths = new HashSet(); + Iterator childrenIterator = entry.getChildrenIterator(); + while (childrenIterator.hasNext()) { + TagCacheEntry child = (TagCacheEntry) childrenIterator.next(); + Set childTags = new HashSet(); + addAllKnownTagsForChildren(child, childTags); + if (childTags.contains(tag)) { + paths.add(child.path.toString()); } - return tags; } - return getDateTags(); + return (String[]) paths.toArray(new String[paths.size()]); } - public String[] getKnownRemotePaths() { + private Set getKnownRemotePaths(TagCacheEntry entry) { Set paths = new HashSet(); - paths.addAll(versionAndBranchTags.keySet()); + Iterator childrenIterator = entry.getChildrenIterator(); + while (childrenIterator.hasNext()) { + paths.addAll(getKnownRemotePaths((TagCacheEntry) childrenIterator + .next())); + } + paths.add(entry.path.toString()); + return paths; + } + + public String[] getKnownRemotePaths() { + Set paths = getKnownRemotePaths(rootTagCacheEntry); paths.addAll(autoRefreshFiles.keySet()); return (String[]) paths.toArray(new String[paths.size()]); } @@ -577,7 +755,7 @@ public class RepositoryRoot extends PlatformObject { public boolean tagIsKnown(ICVSRemoteResource remoteResource) { if (remoteResource instanceof ICVSRemoteFolder) { ICVSRemoteFolder folder = (ICVSRemoteFolder) remoteResource; - String path = getCachePathFor(folder.getRepositoryRelativePath()); + String path = folder.getRepositoryRelativePath(); CVSTag[] tags = getAllKnownTags(path); CVSTag tag = folder.getTag(); for (int i = 0; i < tags.length; i++) { @@ -612,7 +790,7 @@ public class RepositoryRoot extends PlatformObject { * as it was read from the persistent store. */ /* package */ void setLastAccessedTime(String remotePath, long lastAccessTime) { - TagCacheEntry entry = (TagCacheEntry)versionAndBranchTags.get(getCachePathFor(remotePath)); + TagCacheEntry entry = getTagCacheEntryFor(remotePath, false); if(entry != null){ entry.lastAccessTime = lastAccessTime; } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/AllTestsProvider.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/AllTestsProvider.java index 90febe083..088227203 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/AllTestsProvider.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/AllTestsProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2007 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * 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 @@ -34,6 +34,7 @@ public class AllTestsProvider extends EclipseTest { suite.addTest(WatchEditTest.suite()); suite.addTest(LinkResourcesTest.suite()); suite.addTest(IsModifiedTests.suite()); + suite.addTest(RepositoryRootTest.suite()); return new CVSTestSetup(suite); } } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/RepositoryRootTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/RepositoryRootTest.java new file mode 100644 index 000000000..98c483863 --- /dev/null +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/RepositoryRootTest.java @@ -0,0 +1,397 @@ +/******************************************************************************* + * Copyright (c) 2012 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.tests.ccvs.core.provider; + +import java.util.Arrays; +import java.util.List; + +import junit.framework.Test; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.internal.ccvs.core.CVSException; +import org.eclipse.team.internal.ccvs.core.CVSTag; +import org.eclipse.team.internal.ccvs.core.ICVSFolder; +import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; +import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; +import org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot; +import org.eclipse.team.tests.ccvs.core.EclipseTest; + +public class RepositoryRootTest extends EclipseTest { + + private RepositoryRoot repositoryRoot; + private RepositoryManager repositoryManager; + + protected void setUp() throws Exception { + super.setUp(); + repositoryManager = CVSUIPlugin.getPlugin().getRepositoryManager(); + repositoryRoot = repositoryManager + .getRepositoryRootFor(getRepository()); + clearRepositoryRootCache(); + } + + public static Test suite() { + return suite(RepositoryRootTest.class); + } + + private void clearRepositoryRootCache() { + String remotePaths[] = repositoryRoot.getKnownRemotePaths(); + for (int i = 0; i < remotePaths.length; i++) { + repositoryRoot.removeTags(remotePaths[i], + repositoryRoot.getAllKnownTags(remotePaths[i])); + } + assertEquals("Repository cache was not cleaned.", 0, + repositoryRoot.getAllKnownTags().length); + } + + private CVSTag[] refreshTags(IProject project) throws TeamException { + return refreshTags(CVSWorkspaceRoot.getCVSFolderFor(project)); + } + + private CVSTag[] refreshTags(ICVSFolder folder) throws TeamException { + return repositoryManager.refreshDefinedTags(folder, true, true, + DEFAULT_MONITOR); + } + + private IProject createProject(String baseName, String repoPrefix) + throws CoreException { + // create project + IProject project = getUniqueTestProject(baseName); + // share project under module + shareProject(getRepository(), project, + repoPrefix == null ? project.getName() + : (repoPrefix + "/" + project.getName()), + DEFAULT_MONITOR); + assertValidCheckout(project); + // add some files + addResources(project, new String[] { "file1.txt" }, true); + return project; + } + + private void assertTags(List knownTags, CVSTag[] tagsToHave, + CVSTag[] tagsNotToHave) { + for (int i = 0; i < tagsToHave.length; i++) { + assertTrue("Missing tag " + tagsToHave[i].getName(), + knownTags.contains(tagsToHave[i])); + } + for (int i = 0; i < tagsNotToHave.length; i++) { + assertFalse("Extraneous tag " + tagsNotToHave[i].getName(), + knownTags.contains(tagsNotToHave[i])); + } + } + + private void assertProjectTags(CVSCacheTestData data) throws CVSException { + // Root should contain all known tags + List knownTags = Arrays.asList(repositoryRoot.getAllKnownTags()); + assertTags(knownTags, + new CVSTag[] { data.branch_1, data.branch_2, data.branch_3, + data.version_1, data.version_2, data.version_3 }, + new CVSTag[0]); + + // Project_1 should contain Branch_1 and Branch_2 + knownTags = Arrays.asList(repositoryManager + .getKnownTags(CVSWorkspaceRoot.getCVSFolderFor(data.project1))); + assertTags(knownTags, new CVSTag[] { data.branch_1, data.branch_2, + data.version_1, data.version_2 }, new CVSTag[] { data.branch_3, + data.version_3 }); + // Project_2 should contain Branch_1 and Branch_3 + knownTags = Arrays.asList(repositoryManager + .getKnownTags(CVSWorkspaceRoot.getCVSFolderFor(data.project2))); + assertTags(knownTags, new CVSTag[] { data.branch_1, data.branch_3, + data.version_1, data.version_3 }, new CVSTag[] { data.branch_2, + data.version_2 }); + } + + private class CVSCacheTestData { + IProject project1; // tagged with Branch_1 and Branch_2 + IProject project2; // tagged with Branch_1 and Branch_3 + CVSTag branch_1; + CVSTag branch_2; + CVSTag branch_3; + CVSTag version_1; + CVSTag version_2; + CVSTag version_3; + + private void init(String project1Path, String project2Path) + throws CoreException { + project1 = createProject("Project_1", project1Path); + project2 = createProject("Project_2", project2Path); + branch_1 = new CVSTag("Branch_1" + System.currentTimeMillis(), + CVSTag.BRANCH); + version_1 = new CVSTag("Root_" + branch_1.getName(), CVSTag.VERSION); + branch_2 = new CVSTag("Branch_2" + System.currentTimeMillis(), + CVSTag.BRANCH); + version_2 = new CVSTag("Root_" + branch_2.getName(), CVSTag.VERSION); + branch_3 = new CVSTag("Branch_3" + System.currentTimeMillis(), + CVSTag.BRANCH); + version_3 = new CVSTag("Root_" + branch_3.getName(), CVSTag.VERSION); + + makeBranch(new IResource[] { project1, project2 }, version_1, + branch_1, true); + makeBranch(new IResource[] { project1 }, version_2, branch_2, true); + makeBranch(new IResource[] { project2 }, version_3, branch_3, true); + } + + public CVSCacheTestData(String project1Path, String project2Path) + throws CoreException { + init(project1Path, project2Path); + } + } + + public void testProjectsAtRoot() throws CoreException { + CVSCacheTestData data = new CVSCacheTestData(null, null); + + // verify that tags are correct after creating branches + assertProjectTags(data); + + clearRepositoryRootCache(); + refreshTags(data.project1); + refreshTags(data.project2); + assertProjectTags(data); + } + + public void testProjectsInSubmodule() throws CoreException { + String submodule = "Submodule_1" + System.currentTimeMillis(); + CVSCacheTestData data = new CVSCacheTestData(submodule, submodule); + ICVSFolder submoduleFolder = repositoryRoot.getRemoteFolder(submodule, + null, getMonitor()); + + // verify that tags are correct after creating branches + assertProjectTags(data); + + clearRepositoryRootCache(); + refreshTags(data.project1); + refreshTags(data.project2); + assertProjectTags(data); + // verify that parent module has tags from both projects + List knownTags = Arrays.asList(repositoryManager + .getKnownTags(submoduleFolder)); + assertTags(knownTags, + new CVSTag[] { data.branch_1, data.branch_2, data.branch_3, + data.version_1, data.version_2, data.version_3 }, + new CVSTag[0]); + + clearRepositoryRootCache(); + refreshTags(submoduleFolder); + assertProjectTags(data); + // verify that parent module has tags from both projects + knownTags = Arrays.asList(repositoryManager + .getKnownTags(submoduleFolder)); + assertTags(knownTags, + new CVSTag[] { data.branch_1, data.branch_2, data.branch_3, + data.version_1, data.version_2, data.version_3 }, + new CVSTag[0]); + } + + public void testProjectsInTwoSubmodules() throws CoreException { + String submodule1 = "Submodule_1" + System.currentTimeMillis(); + String submodule2 = "Submodule_2" + System.currentTimeMillis(); + CVSCacheTestData data = new CVSCacheTestData(submodule1, submodule2); + ICVSFolder submoduleFolder1 = repositoryRoot.getRemoteFolder( + submodule1, null, getMonitor()); + ICVSFolder submoduleFolder2 = repositoryRoot.getRemoteFolder( + submodule2, null, getMonitor()); + + // verify that tags are correct after creating branches + assertProjectTags(data); + + clearRepositoryRootCache(); + refreshTags(data.project1); + refreshTags(data.project2); + assertProjectTags(data); + // verify that parent modules have tags from subordinate project, but + // not the other project + List knownTags = Arrays.asList(repositoryManager + .getKnownTags(submoduleFolder1)); + assertTags(knownTags, new CVSTag[] { data.branch_1, data.branch_2, + data.version_1, data.version_2 }, new CVSTag[] { data.branch_3, + data.version_3 }); + knownTags = Arrays.asList(repositoryManager + .getKnownTags(submoduleFolder2)); + assertTags(knownTags, new CVSTag[] { data.branch_1, data.branch_3, + data.version_1, data.version_3 }, new CVSTag[] { data.branch_2, + data.version_2 }); + // clear the cache, refresh it only one for submodule and verify if tags + // are correct + clearRepositoryRootCache(); + refreshTags(submoduleFolder1); + + // verify that correct tags where added to this submodule + knownTags = Arrays.asList(repositoryManager + .getKnownTags(submoduleFolder1)); + assertTags(knownTags, new CVSTag[] { data.branch_1, data.branch_2, + data.version_1, data.version_2 }, new CVSTag[] { data.branch_3, + data.version_3 }); + // verify if only tags from the first submodule are known + knownTags = Arrays.asList(repositoryRoot.getAllKnownTags()); + assertTags(knownTags, new CVSTag[] { data.branch_1, data.branch_2, + data.version_1, data.version_2 }, new CVSTag[] { data.branch_3, + data.version_3 }); + + refreshTags(submoduleFolder2); + // verify tags for the second submodule + knownTags = Arrays.asList(repositoryManager + .getKnownTags(submoduleFolder2)); + assertTags(knownTags, new CVSTag[] { data.branch_1, data.branch_3, + data.version_1, data.version_3 }, new CVSTag[] { data.branch_2, + data.version_2 }); + // verify if tags are merged correctly + assertProjectTags(data); + } + + public void testNestedProjects() throws CoreException { + IProject superProject = createProject("SuperProject", (String) null); + CVSTag superProjectBranch = new CVSTag("Branch_" + + superProject.getName(), CVSTag.BRANCH); + CVSTag superProjectVersion = new CVSTag("Root_" + + superProjectBranch.getName(), CVSTag.VERSION); + makeBranch(new IResource[] { superProject }, superProjectVersion, + superProjectBranch, true); + // subProject1 and subProject2 are nested in superProject + // each of them has its own tags + IProject subProject1 = createProject("SubProject_1", + superProject.getName()); + CVSTag subProject1Branch = new CVSTag( + "Branch_" + subProject1.getName(), CVSTag.BRANCH); + CVSTag subProject1Version = new CVSTag("Root_" + + subProject1Branch.getName(), CVSTag.VERSION); + makeBranch(new IResource[] { subProject1 }, subProject1Version, + subProject1Branch, true); + IProject subProject2 = createProject("SubProject_2", + superProject.getName()); + CVSTag subProject2Branch = new CVSTag( + "Branch_" + subProject2.getName(), CVSTag.BRANCH); + CVSTag subProject2Version = new CVSTag("Root_" + + subProject2Branch.getName(), CVSTag.VERSION); + makeBranch(new IResource[] { subProject2 }, subProject2Version, + subProject2Branch, true); + // check if subProjects have tags from superProject but not tags from + // each other, check if superProject has tags from all subProjects + List knownTags = Arrays.asList(repositoryManager + .getKnownTags(CVSWorkspaceRoot.getCVSFolderFor(superProject))); + assertTags(knownTags, new CVSTag[] { superProjectBranch, + superProjectVersion, subProject1Branch, subProject1Version, + subProject2Branch, subProject2Version }, new CVSTag[0]); + knownTags = Arrays.asList(repositoryManager + .getKnownTags(CVSWorkspaceRoot.getCVSFolderFor(subProject1))); + assertTags(knownTags, new CVSTag[] { superProjectBranch, + superProjectVersion, subProject1Branch, subProject1Version }, + new CVSTag[] { subProject2Branch, subProject2Version }); + knownTags = Arrays.asList(repositoryManager + .getKnownTags(CVSWorkspaceRoot.getCVSFolderFor(subProject2))); + assertTags(knownTags, new CVSTag[] { superProjectBranch, + superProjectVersion, subProject2Branch, subProject2Version }, + new CVSTag[] { subProject1Branch, subProject1Version }); + // remove tag from one of the subProjects, check if it was not removed + // from the other subProject, check if superProject still has this tag + repositoryManager.removeTags( + CVSWorkspaceRoot.getCVSFolderFor(subProject1), new CVSTag[] { + superProjectBranch, superProjectVersion }); + knownTags = Arrays.asList(repositoryManager + .getKnownTags(CVSWorkspaceRoot.getCVSFolderFor(superProject))); + assertTags(knownTags, new CVSTag[] { superProjectBranch, + superProjectVersion, subProject1Branch, subProject1Version, + subProject2Branch, subProject2Version }, new CVSTag[0]); + knownTags = Arrays.asList(repositoryManager + .getKnownTags(CVSWorkspaceRoot.getCVSFolderFor(subProject1))); + assertTags(knownTags, new CVSTag[] { subProject1Branch, + subProject1Version }, new CVSTag[] { subProject2Branch, + subProject2Version }); + knownTags = Arrays.asList(repositoryManager + .getKnownTags(CVSWorkspaceRoot.getCVSFolderFor(subProject2))); + assertTags(knownTags, new CVSTag[] { superProjectBranch, + superProjectVersion, subProject2Branch, subProject2Version }, + new CVSTag[] { subProject1Branch, subProject1Version }); + } + + public void testTagsForSubfolder() throws TeamException, CoreException { + IProject project = createProject("Project_1", (String) null); + String folderName = "testFolder"; + addResources(project, new String[] { folderName + "/", + folderName + "/testFile.txt" }, true); + IFolder folder = project.getFolder(folderName); + CVSTag branch1 = new CVSTag("Branch_1" + System.currentTimeMillis(), + CVSTag.BRANCH); + CVSTag version1 = new CVSTag("Root_" + branch1.getName(), + CVSTag.VERSION); + makeBranch(new IResource[] { project }, version1, branch1, true); + // verify if project's tags are known for subfolder + ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(folder); + List knownTags = Arrays.asList(repositoryManager + .getKnownTags(cvsFolder)); + assertTags(knownTags, new CVSTag[] { branch1, version1 }, new CVSTag[0]); + // verify if removing tags from subfolder is correctly handled + repositoryManager.removeTags(cvsFolder, new CVSTag[] { branch1, + version1 }); + knownTags = Arrays.asList(repositoryManager.getKnownTags(cvsFolder)); + assertTags(knownTags, new CVSTag[0], new CVSTag[] { branch1, version1 }); + // verify if after refreshing tags are back for both project and its + // subfolder + refreshTags(cvsFolder); + knownTags = Arrays.asList(repositoryManager.getKnownTags(cvsFolder)); + assertTags(knownTags, new CVSTag[] { branch1, version1 }, new CVSTag[0]); + knownTags = Arrays.asList(repositoryManager + .getKnownTags(CVSWorkspaceRoot.getCVSFolderFor(project))); + assertTags(knownTags, new CVSTag[] { branch1, version1 }, new CVSTag[0]); + } + + public void testRefreshProjectUsingAutoRefreshFile() throws CoreException { + IProject project = createProject("Project_1", (String) null); + String autoRefreshFileName = "sampleAuthoRefresh.txt"; + String notAutoRefreshFileName = "notAutoRefresh.txt"; + addResources(project, new String[] { autoRefreshFileName, + notAutoRefreshFileName }, true); + IFile autoRefreshFile = project.getFile(autoRefreshFileName); + IFile notAutoRefreshFile = project.getFile(notAutoRefreshFileName); + repositoryManager.setAutoRefreshFiles( + CVSWorkspaceRoot.getCVSFolderFor(project), + new String[] { CVSWorkspaceRoot.getCVSResourceFor( + autoRefreshFile).getRepositoryRelativePath() }); + CVSTag branch1 = new CVSTag("Branch_1" + System.currentTimeMillis(), + CVSTag.BRANCH); + CVSTag version1 = new CVSTag("Root_" + branch1.getName(), + CVSTag.VERSION); + // branch the auto refresh file + makeBranch(new IResource[] { autoRefreshFile }, version1, branch1, true); + CVSTag branch2 = new CVSTag("Branch_2" + System.currentTimeMillis(), + CVSTag.BRANCH); + CVSTag version2 = new CVSTag("Root_" + branch2.getName(), + CVSTag.VERSION); + // branch not auto refresh file + makeBranch(new IResource[] { notAutoRefreshFile }, version2, branch2, + true); + + clearRepositoryRootCache(); + refreshTags(project); + + // cache should contain branches from auto refresh file, but no branches + // from other files + List knownTags = Arrays.asList(repositoryManager + .getKnownTags(CVSWorkspaceRoot.getCVSFolderFor(project))); + assertTags(knownTags, new CVSTag[] { branch1, version1 }, new CVSTag[] { + branch2, version2 }); + } + + public void testProjectWithNoTags() throws CoreException { + IProject project = createProject("Project_1", (String) null); + CVSTag knownTags[] = repositoryManager.getKnownTags(CVSWorkspaceRoot + .getCVSFolderFor(project)); + assertEquals(0, knownTags.length); + knownTags = refreshTags(project); + assertEquals(0, knownTags.length); + } + +} diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/RepositoriesViewTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/RepositoriesViewTests.java index 3e9528d42..a710e1d8a 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/RepositoriesViewTests.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/RepositoriesViewTests.java @@ -1,5 +1,5 @@ /*******************************************************************************
- * Copyright (c) 2011 IBM Corporation and others.
+ * Copyright (c) 2011, 2012 IBM Corporation and others.
* 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
@@ -20,7 +20,6 @@ import org.eclipse.team.core.TeamException; import org.eclipse.team.internal.ccvs.core.CVSTag;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder;
import org.eclipse.team.internal.ccvs.core.resources.RemoteResource;
-import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.team.internal.ccvs.ui.model.AllRootsElement;
import org.eclipse.team.internal.ccvs.ui.model.BranchCategory;
import org.eclipse.team.internal.ccvs.ui.model.CVSTagElement;
@@ -87,23 +86,14 @@ public class RepositoriesViewTests extends EclipseTest { moduleName + "/" + project.getName(), DEFAULT_MONITOR);
assertValidCheckout(project);
- // make some changes
- addResources(project, new String[] { "folder1/c.txt" }, false);
+ // add some files
+ addResources(project, new String[] { "file1.txt" }, true);
// make branch
CVSTag version = new CVSTag(versionName, CVSTag.VERSION);
CVSTag branch = new CVSTag(branchName, CVSTag.BRANCH);
makeBranch(new IResource[] { project }, version, branch, true);
- commitProject(project);
-
- // refresh branches
- CVSUIPlugin
- .getPlugin()
- .getRepositoryManager()
- .refreshDefinedTags(
- getRepository().getRemoteFolder(moduleName, null),
- true, true, DEFAULT_MONITOR);
// check if module is the only branch child
RemoteContentProvider rcp = new RemoteContentProvider();
@@ -117,6 +107,15 @@ public class RepositoriesViewTests extends EclipseTest { Object[] modules = rcp.getChildren(branches[0]);
assertEquals(1, modules.length);
assertEquals(moduleName, ((RemoteResource) modules[0]).getName());
+
+ // check if after refresh module is still the only branch child
+ branches = rcp.getChildren(categories[1]);
+ assertEquals(1, branches.length);
+ assertEquals(branchName, ((CVSTagElement) (branches[0])).getTag()
+ .getName());
+ modules = rcp.getChildren(branches[0]);
+ assertEquals(1, modules.length);
+ assertEquals(moduleName, ((RemoteResource) modules[0]).getName());
}
public void testTagSubmoduleChildren() throws TeamException, CoreException {
@@ -140,15 +139,6 @@ public class RepositoriesViewTests extends EclipseTest { tagProject(project, tag, true);
- // refresh branches for module
- // TODO Remove when Bug 372862 is committed, adding tag for submodule
- // should automatically add it to module
- CVSUIPlugin
- .getPlugin()
- .getRepositoryManager()
- .refreshDefinedTags(
- getRepository().getRemoteFolder(moduleName, null),
- true, true, DEFAULT_MONITOR);
RemoteContentProvider rcp = new RemoteContentProvider();
Object[] categories = rcp.getChildren(getRepositoryRoot());
@@ -170,4 +160,95 @@ public class RepositoriesViewTests extends EclipseTest { }
fail(moduleName + " not found");
}
+
+ public void testTagsOnDifferentLevels() throws CoreException {
+ String time = Long.toString(System.currentTimeMillis());
+ String firstModule = "Module_1" + time;
+ String secondModule = "Module_2" + time;
+ String secondModulePath = firstModule + "/" + secondModule;
+ // Create repository data
+ // Module_1/Project_1
+ IProject project1 = getUniqueTestProject("Project_1");
+ shareProject(getRepository(), project1,
+ firstModule + "/" + project1.getName(), DEFAULT_MONITOR);
+ // Module_1/Module_2/Project_2
+ IProject project2 = getUniqueTestProject("Project_2");
+ shareProject(getRepository(), project2, secondModulePath + "/"
+ + project2.getName(), DEFAULT_MONITOR);
+ // Module_1/Module_2/Project_3
+ IProject project3 = getUniqueTestProject("Project_3");
+ shareProject(getRepository(), project3, secondModulePath + "/"
+ + project3.getName(), DEFAULT_MONITOR);
+ // Module_1/Project_4
+ IProject project4 = getUniqueTestProject("Project_4");
+ shareProject(getRepository(), project4,
+ firstModule + "/" + project4.getName(), DEFAULT_MONITOR);
+
+ // Create branches
+ String branch1 = "Branch_1" + time;
+ String version1 = "Root_" + branch1;
+ String branch2 = "Branch_2" + time;
+ String version2 = "Root_" + branch2;
+
+ // Tag projects:
+ // Module_1/Project_1 -> [Branch_1][Branch_2]
+ // Module_1/Module_2/Project_2 -> [Branch_1][Branch_2]
+ // Module_1/Module_2/Project_3 -> [Branch_2]
+ // Module_1/Project_4 -> [Branch_4]
+ makeBranch(new IResource[] { project1, project2 }, new CVSTag(version1,
+ CVSTag.VERSION), new CVSTag(branch1, CVSTag.BRANCH), true);
+ makeBranch(new IResource[] { project1, project2, project2, project4 },
+ new CVSTag(version2, CVSTag.VERSION), new CVSTag(branch2,
+ CVSTag.BRANCH), true);
+
+ // verify if tree structure is built from cache
+ RemoteContentProvider rcp = new RemoteContentProvider();
+ Object[] categories = rcp.getChildren(getRepositoryRoot());
+ assertEquals(4, categories.length);
+ assertTrue(categories[1] instanceof BranchCategory);
+ Object[] branches = rcp.getChildren(categories[1]);
+ assertEquals(2, branches.length); // should be [Branch_1] and [Branch_2]
+ CVSTagElement branch1Element;
+ CVSTagElement branch2Element;
+ if (((CVSTagElement) branches[0]).getTag().getName().equals(branch1)) {
+ branch1Element = (CVSTagElement) branches[0];
+ branch2Element = (CVSTagElement) branches[1];
+ } else {
+ branch1Element = (CVSTagElement) branches[1];
+ branch2Element = (CVSTagElement) branches[0];
+ }
+ Object[] modules = rcp.getChildren(branch1Element);
+ assertEquals(1, modules.length); // should be [Branch_1]/Module_1
+ assertEquals(firstModule, ((RemoteResource) modules[0]).getName());
+ modules = rcp.getChildren(modules[0]);
+ // should contain:
+ // [Branch_1]/Module_1/Project_1
+ // [Branch_1]/Module_1/Module_2
+ assertEquals(2, modules.length);
+ for (int i = 0; i < modules.length; i++) {
+ if (((RemoteResource) (modules[i])).getName().equals(
+ project1.getName())) {
+ // Project_1 should have contents retrieved from CVS
+ assertTrue(rcp.hasChildren(modules[i]));
+ } else if (((RemoteResource) (modules[i])).getName().equals(
+ secondModule)) {
+ // should be only [Branch_1]/Module_1/Module_2/Project_2.
+ // [Branch_1]/Module_1/Module_2/Project_3 should NOT be on the
+ // list, it is not branched with Branch_1
+ Object[] module2Children = rcp.getChildren(modules[i]);
+ assertEquals(1, module2Children.length);
+ assertEquals(project2.getName(),
+ ((RemoteResource) module2Children[0]).getName());
+ }
+ }
+ modules = rcp.getChildren(branch2Element);
+ assertEquals(1, modules.length); // should be [Branch_2]/Module_1
+ assertEquals(firstModule, ((RemoteResource) modules[0]).getName());
+ // should contain:
+ // [Branch_2]/Module_1/Project_1
+ // [Branch_2]/Module_1/Module_2
+ // [Branch_2]/Module_1/Project_4
+ modules = rcp.getChildren(modules[0]);
+ assertEquals(3, modules.length);
+ }
}
|