blob: 5767e113111802e5bd8534c07f1005b2225af663 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.team.tests.ccvs.core.subscriber;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import junit.framework.AssertionFailedError;
import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.subscribers.ISubscriberChangeEvent;
import org.eclipse.team.core.subscribers.ISubscriberChangeListener;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.core.subscribers.SubscriberChangeEvent;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.internal.ccvs.core.CVSSyncTreeSubscriber;
import org.eclipse.team.internal.ccvs.ui.subscriber.ConfirmMergedOperation;
import org.eclipse.team.internal.ui.synchronize.SyncInfoModelElement;
import org.eclipse.team.tests.ccvs.core.EclipseTest;
import org.eclipse.team.tests.ccvs.ui.SynchronizeViewTestAdapter;
/**
* Provides test methods common to CVS sync subscribers
*/
public abstract class CVSSyncSubscriberTest extends EclipseTest {
private ISubscriberChangeListener listener;
private List accumulatedTeamDeltas = new ArrayList();
private static SyncInfoSource source = new SynchronizeViewTestAdapter();
public CVSSyncSubscriberTest() {
super();
}
public CVSSyncSubscriberTest(String name) {
super(name);
}
public static void setSyncSource(SyncInfoSource newSource) {
source = newSource;
}
protected Subscriber getWorkspaceSubscriber() throws TeamException {
return getSyncInfoSource().createWorkspaceSubscriber();
}
public SyncInfoSource getSyncInfoSource() {
assertNotNull(source);
return source;
}
protected void refresh(Subscriber subscriber, IResource resource) throws TeamException {
getSyncInfoSource().refresh(subscriber, resource);
}
/*
* Assert that the specified resources in the subscriber have the specified sync kind
* Ignore conflict types if they are not specified in the assert statement
*/
protected void assertSyncEquals(String message, Subscriber subscriber, IContainer root, String[] resourcePaths, boolean refresh, int[] syncKinds) throws CoreException, TeamException {
assertTrue(resourcePaths.length == syncKinds.length);
if (refresh) refresh(subscriber, root);
IResource[] resources = getResources(root, resourcePaths);
for (int i=0;i<resources.length;i++) {
assertSyncEquals(message, subscriber, resources[i], syncKinds[i]);
}
}
protected void assertSyncEquals(String message, Subscriber subscriber, IResource resource, int syncKind) throws TeamException {
int conflictTypeMask = 0x0F; // ignore manual and auto merge sync types for now.
SyncInfo info = getSyncInfo(subscriber, resource);
int kind;
int kindOther = syncKind & conflictTypeMask;
if (info == null) {
kind = SyncInfo.IN_SYNC;
} else {
kind = info.getKind() & conflictTypeMask;
}
// Special handling for folders
if (kind != kindOther && resource.getType() == IResource.FOLDER) {
// The only two states for folders are outgoing addition and in-sync.
// Other additions will appear as in-sync
if (info.getKind() == SyncInfo.IN_SYNC
&& (syncKind & SyncInfo.ADDITION) != 0) {
return;
}
}
assertTrue(message + ": improper sync state for " + resource + " expected " +
SyncInfo.kindToString(kindOther) + " but was " +
SyncInfo.kindToString(kind), kind == kindOther);
}
protected SyncInfo getSyncInfo(Subscriber subscriber, IResource resource) throws TeamException {
return getSyncInfoSource().getSyncInfo(subscriber, resource);
}
/**
* @param changes
* @param resources
*/
protected void assertSyncChangesMatch(ISubscriberChangeEvent[] changes, IResource[] resources) {
// First, ensure that all the resources appear in the delta
for (int i = 0; i < resources.length; i++) {
IResource resource = resources[i];
boolean found = false;
for (int j = 0; j < changes.length; j++) {
ISubscriberChangeEvent delta = changes[j];
if (delta.getResource().equals(resource)) {
found = true;
break;
}
}
assertTrue("No change reported for " + resource, found);
}
// TODO: We'll worry about extra deltas later
// // Next, ensure there are no extra deltas
// List changedResources = new ArrayList(resources.length);
// changedResources.addAll(Arrays.asList(resources));
// for (int i = 0; i < changes.length; i++) {
// TeamDelta change = changes[i];
// IResource resource = change.getResource();
// assertTrue("Unanticipated change reported for " + resource, changedResources.contains(resource));
// }
}
/*
* Assert that the named resources have no local resource or sync info
*/
protected void assertDeleted(String message, IContainer root, String[] resourcePaths) throws CoreException, TeamException {
IResource[] resources = getResources(root, resourcePaths);
for (int i=0;i<resources.length;i++) {
try {
if (! resources[i].exists())
break;
} catch (AssertionFailedError e) {
break;
}
assertTrue(message + ": resource " + resources[i] + " still exists in some form", false);
}
}
public static class ResourceCondition {
public boolean matches(IResource resource) throws CoreException, TeamException {
return true;
}
}
protected IResource[] collect(IResource[] resources, final ResourceCondition condition, int depth) throws CoreException, TeamException {
final Set affected = new HashSet();
for (int i = 0; i < resources.length; i++) {
IResource resource = resources[i];
if (resource.exists() || resource.isPhantom()) {
resource.accept(new IResourceVisitor() {
public boolean visit(IResource r) throws CoreException {
try {
if (condition.matches(r)) {
affected.add(r);
}
} catch (TeamException e) {
throw new CoreException(e.getStatus());
}
return true;
}
}, depth, true /* include phantoms */);
} else {
if (condition.matches(resource)) {
affected.add(resource);
}
}
}
return (IResource[]) affected.toArray(new IResource[affected.size()]);
}
/**
* @param resources
* @param condition
* @return
*/
protected IResource[] collectAncestors(IResource[] resources, ResourceCondition condition) throws CoreException, TeamException {
Set affected = new HashSet();
for (int i = 0; i < resources.length; i++) {
IResource resource = resources[i];
while (resource.getType() != IResource.ROOT) {
if (condition.matches(resource)) {
affected.add(resource);
} else {
break;
}
resource = resource.getParent();
}
}
return (IResource[]) affected.toArray(new IResource[affected.size()]);
}
protected ISubscriberChangeEvent[] deregisterSubscriberListener(Subscriber subscriber) throws TeamException {
subscriber.removeListener(listener);
return (ISubscriberChangeEvent[]) accumulatedTeamDeltas.toArray(new SubscriberChangeEvent[accumulatedTeamDeltas.size()]);
}
protected ISubscriberChangeListener registerSubscriberListener(Subscriber subscriber) throws TeamException {
listener = new ISubscriberChangeListener() {
public void subscriberResourceChanged(ISubscriberChangeEvent[] deltas) {
accumulatedTeamDeltas.addAll(Arrays.asList(deltas));
}
};
accumulatedTeamDeltas.clear();
subscriber.addListener(listener);
return listener;
}
protected SyncInfo[] createSyncInfos(Subscriber subscriber, IResource[] resources) throws TeamException {
SyncInfo[] result = new SyncInfo[resources.length];
for (int i = 0; i < resources.length; i++) {
IResource resource = resources[i];
result[i] = getSyncInfo(subscriber, resource);
}
return result;
}
protected void assertProjectRemoved(Subscriber subscriber, IProject project) throws TeamException {
getSyncInfoSource().assertProjectRemoved(subscriber, project);
}
protected void markAsMerged(CVSSyncTreeSubscriber subscriber, IProject project, String[] resourcePaths) throws CoreException, TeamException, InvocationTargetException, InterruptedException {
IResource[] resources = getResources(project, resourcePaths);
SyncInfo[] infos = createSyncInfos(subscriber, resources);
new ConfirmMergedOperation(null, getElements(infos)).run(DEFAULT_MONITOR);
}
protected IDiffElement[] getElements(SyncInfo[] infos) {
SyncInfoModelElement[] elements = new SyncInfoModelElement[infos.length];
for (int i = 0; i < elements.length; i++) {
elements[i] = new SyncInfoModelElement(null, infos[i]);
}
return elements;
}
}