### Eclipse Workspace Patch 1.0 #P org.eclipse.team.cvs.core Index: plugin.xml =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.team.cvs.core/plugin.xml,v retrieving revision 1.55 diff -u -r1.55 plugin.xml --- plugin.xml 13 Mar 2007 16:26:13 -0000 1.55 +++ plugin.xml 19 Apr 2007 14:56:59 -0000 @@ -5,9 +5,9 @@ + - Ensures that all repositories from imported project set are known. If + * yes, return true. If not, checks whether there is an + * alternative known repository for one from project set.

+ *

Cached repository is matched as an alternative when it's:

+ * + *
    + *
  • host equals to the one from the project set
  • + *
  • port equals to the one from the project set
  • + *
  • root directory equals to the one from the project set
  • + *
+ * + * @param infoMap + * @return + */ + private static boolean isAlternativeRepositoryNeeded(final Map infoMap, Map alternativeMap) { + + if (infoMap == null) + return false; + + Set projectSetRepositories = new HashSet(); + for (Iterator iterator = infoMap.keySet().iterator(); iterator.hasNext();) { + IProject project = (IProject) iterator.next(); + LoadInfo loadInfo = (LoadInfo) infoMap.get(project); + projectSetRepositories.add(loadInfo.repositoryLocation); + } + + //TODO: use match criteria from plugin.xml (method,port,*,none)? + List knownRepositories = Arrays.asList(KnownRepositories.getInstance().getRepositories()); + + // not all repositories from the project set being imported are known + if (!knownRepositories.containsAll(projectSetRepositories)) { + + for (Iterator iterator = projectSetRepositories.iterator(); iterator + .hasNext();) { + ICVSRepositoryLocation projectSetRepositoryLocation = (ICVSRepositoryLocation) iterator.next(); + + ICVSRepositoryLocation[] alternativeArray = new ICVSRepositoryLocation[4]; + int alternativesCounter = 0; + for (Iterator iterator2 = knownRepositories.iterator(); iterator2 + .hasNext();) { + ICVSRepositoryLocation knownRepositoryLocation = (ICVSRepositoryLocation) iterator2.next(); + + // the closest match here + if (projectSetRepositoryLocation.getHost().equals(knownRepositoryLocation.getHost()) + && projectSetRepositoryLocation.getPort() == knownRepositoryLocation.getPort() + && projectSetRepositoryLocation.getRootDirectory().equals(knownRepositoryLocation.getRootDirectory())) { + // only connection method doesn't match + alternativeArray[0] = knownRepositoryLocation; + alternativesCounter++; + } else if (projectSetRepositoryLocation.getHost().equals(knownRepositoryLocation.getHost()) + && projectSetRepositoryLocation.getPort() == knownRepositoryLocation.getPort() ) { + // root directory doesn't match + alternativeArray[1]= knownRepositoryLocation; + alternativesCounter++; + } else if (projectSetRepositoryLocation.getHost().equals(knownRepositoryLocation.getHost()) + && projectSetRepositoryLocation.getRootDirectory().equals(knownRepositoryLocation.getRootDirectory())){ + // port doesn't match + alternativeArray[2]= knownRepositoryLocation; + alternativesCounter++; + } else if (projectSetRepositoryLocation.getHost().equals(knownRepositoryLocation.getHost())) { + // only host matches + alternativeArray[3]= knownRepositoryLocation; + alternativesCounter++; + } + // the furthest match here + } + + // convert alternative array into ordered list, closer match first + if (alternativesCounter > 0) { + ArrayList alternativeList = new ArrayList( + alternativesCounter); + + for (int i = alternativeArray.length-1; i >= 0; i--) { + if (alternativeArray[i] != null) + alternativeList.add(alternativeArray[i]); + } + + alternativeMap.put(projectSetRepositoryLocation, + alternativeList); + } + } + } + + return alternativeMap.size() > 0; + } + + private Object promptForAlternativeRespository(Map alternativeMap) { + IAlternativeRepositoryPrompter prompter = getAlternativeRepositoryPrompter(); + return prompter.promptForAlternativeRepository(alternativeMap); + } + + private IAlternativeRepositoryPrompter getAlternativeRepositoryPrompter() { + if (alternativeRepositoryPrompter == null) { + alternativeRepositoryPrompter = getPluggedInAlternativeRepositoryPrompter(); + } + return alternativeRepositoryPrompter; + } + private static IAlternativeRepositoryPrompter getPluggedInAlternativeRepositoryPrompter() { + IExtension[] extensions = Platform.getExtensionRegistry().getExtensionPoint(CVSProviderPlugin.ID, CVSProviderPlugin.PT_ALTERNATIVE_REPOSITORY_PROMPTER).getExtensions(); + if (extensions.length == 0) + return null; + IExtension extension = extensions[0]; + IConfigurationElement[] configs = extension.getConfigurationElements(); + if (configs.length == 0) { + CVSProviderPlugin.log(IStatus.ERROR, NLS.bind("Alternative Repository Prompter {0} is missing required fields", (new Object[] {extension.getUniqueIdentifier()})), null);//$NON-NLS-1$ + return null; + } + try { + IConfigurationElement config = configs[0]; + return (IAlternativeRepositoryPrompter) config.createExecutableExtension("run");//$NON-NLS-1$ + } catch (CoreException ex) { + CVSProviderPlugin.log(IStatus.ERROR, NLS.bind("Unable to instantiate Alternative Repository Prompter {0}", (new Object[] {extension.getUniqueIdentifier()})), ex);//$NON-NLS-1$ + return null; + } + } } Index: src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java,v retrieving revision 1.111 diff -u -r1.111 CVSProviderPlugin.java --- src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java 16 Mar 2007 21:03:50 -0000 1.111 +++ src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java 19 Apr 2007 14:56:59 -0000 @@ -67,6 +67,7 @@ public static final QualifiedName CVS_WORKSPACE_SUBSCRIBER_ID = new QualifiedName("org.eclipse.team.cvs.ui.cvsworkspace-participant", "syncparticipant"); //$NON-NLS-1$ //$NON-NLS-2$ public static final String PT_AUTHENTICATOR = "authenticator"; //$NON-NLS-1$ + public static final String PT_ALTERNATIVE_REPOSITORY_PROMPTER = "alternativerepositoryprompter"; //$NON-NLS-1$ public static final String PT_CONNECTIONMETHODS = "connectionmethods"; //$NON-NLS-1$ public static final String PT_FILE_MODIFICATION_VALIDATOR = "filemodificationvalidator"; //$NON-NLS-1$ Index: schema/alternativerepositoryprompter.exsd =================================================================== RCS file: schema/alternativerepositoryprompter.exsd diff -N schema/alternativerepositoryprompter.exsd --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ schema/alternativerepositoryprompter.exsd 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,97 @@ + + + + + + + + + This extension point is internal use only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.0 + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + This extension point is for internal use only + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + + + + + Copyright (c) 2004 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 <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a> + + + + Index: src/org/eclipse/team/internal/ccvs/core/IAlternativeRepositoryPrompter.java =================================================================== RCS file: src/org/eclipse/team/internal/ccvs/core/IAlternativeRepositoryPrompter.java diff -N src/org/eclipse/team/internal/ccvs/core/IAlternativeRepositoryPrompter.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/team/internal/ccvs/core/IAlternativeRepositoryPrompter.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2007 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.internal.ccvs.core; + +import java.util.Map; + +public interface IAlternativeRepositoryPrompter { + + public abstract Object promptForAlternativeRepository(Map alternativeMap); +} #P org.eclipse.team.tests.cvs.core Index: src/org/eclipse/team/tests/ccvs/core/CVSProjectSetCapabilityTest.java =================================================================== RCS file: src/org/eclipse/team/tests/ccvs/core/CVSProjectSetCapabilityTest.java diff -N src/org/eclipse/team/tests/ccvs/core/CVSProjectSetCapabilityTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/team/tests/ccvs/core/CVSProjectSetCapabilityTest.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,195 @@ +package org.eclipse.team.tests.ccvs.core; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.eclipse.core.resources.IProject; +import org.eclipse.team.internal.ccvs.core.CVSProjectSetCapability; +import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; +import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; +import org.eclipse.team.internal.ccvs.core.util.KnownRepositories; + +public class CVSProjectSetCapabilityTest extends /* EclipseTest */TestCase { + private ICVSRepositoryLocation[] savedRepositories; + + protected void setUp() throws Exception { + // save already cached repositories + savedRepositories = KnownRepositories.getInstance().getRepositories(); + for (int i = 0; i < KnownRepositories.getInstance().getRepositories().length; i++) { + KnownRepositories.getInstance().disposeRepository( + KnownRepositories.getInstance().getRepositories()[i]); + } + assertEquals(0, + KnownRepositories.getInstance().getRepositories().length); + } + + protected void tearDown() throws Exception { + // clear testing repositories + for (int i = 0; i < KnownRepositories.getInstance().getRepositories().length; i++) { + KnownRepositories.getInstance().disposeRepository( + KnownRepositories.getInstance().getRepositories()[i]); + } + + // load saved repositories + for (int i = 0; i < savedRepositories.length; i++) { + KnownRepositories.getInstance().addRepository(savedRepositories[i], + true); + } + } + + public void testIsAlternativeRepositoryNeeded_infoMapIsNull() + throws Exception { + Map infoMap = null; + Map alternativeMap = new HashMap(); + boolean isAlternativeRepositoryNeeded = invokeIsAlternativeRepositoryNeeded( + infoMap, alternativeMap); + assertEquals(false, isAlternativeRepositoryNeeded); + } + + public void testIsAlternativeRepositoryNeeded_infoMapIsEmpty() + throws Exception { + Map infoMap = new HashMap(); + Map alternativeMap = new HashMap(); + boolean isAlternativeRepositoryNeeded = invokeIsAlternativeRepositoryNeeded( + infoMap, alternativeMap); + assertEquals(false, isAlternativeRepositoryNeeded); + } + + public void testIsAlternativeRepositoryNeeded_knownRepository() throws Exception { + Map infoMap = new HashMap(); + Map alternativeMap = new HashMap(); + + String repo = ":pserver:user:password@hostname:1/path/to/repository"; + KnownRepositories.getInstance().addRepository( + CVSRepositoryLocation.fromString(repo), true); + assertEquals(1, + KnownRepositories.getInstance().getRepositories().length); + + invokeAsProjects( + new String[] { "1.0,:pserver:user:password@hostname:1/path/to/repository,module.name,project.name" }, + infoMap); + + boolean isAlternativeRepositoryNeeded = invokeIsAlternativeRepositoryNeeded( + infoMap, alternativeMap); + assertEquals(false, isAlternativeRepositoryNeeded); + } + + public void testIsAlternativeRepositoryNeeded_unknownHost() throws Exception { + Map infoMap = new HashMap(); + Map alternativeMap = new HashMap(); + + String repo = ":pserver:user:password@hostname:80/path/to/repository"; + KnownRepositories.getInstance().addRepository( + CVSRepositoryLocation.fromString(repo), true); + assertEquals(1, + KnownRepositories.getInstance().getRepositories().length); + + invokeAsProjects( + new String[] { "1.0,:pserver:user:password@UNKNOWN:80/path/to/repository,module.name,project.name" }, + infoMap); + + boolean isAlternativeRepositoryNeeded = invokeIsAlternativeRepositoryNeeded( + infoMap, alternativeMap); + assertEquals(false, isAlternativeRepositoryNeeded); + } + + public void testIsAlternativeRepositoryNeeded_differentMethod() throws Exception { + Map infoMap = new HashMap(); + Map alternativeMap = new HashMap(); + + String repo = ":pserver:user:password@hostname/path/to/repository"; + KnownRepositories.getInstance().addRepository( + CVSRepositoryLocation.fromString(repo), true); + assertEquals(1, + KnownRepositories.getInstance().getRepositories().length); + + invokeAsProjects( + new String[] { "1.0,:extssh:user:password@hostname/path/to/repository,module.name,project.name" }, + infoMap); + + boolean isAlternativeRepositoryNeeded = invokeIsAlternativeRepositoryNeeded( + infoMap, alternativeMap); + assertEquals(true, isAlternativeRepositoryNeeded); + } + + public void testIsAlternativeRepositoryNeeded_differentPort() throws Exception { + Map infoMap = new HashMap(); + Map alternativeMap = new HashMap(); + + String repo = ":pserver:user:password@hostname:80/path/to/repository"; + KnownRepositories.getInstance().addRepository( + CVSRepositoryLocation.fromString(repo), true); + assertEquals(1, + KnownRepositories.getInstance().getRepositories().length); + + invokeAsProjects( + new String[] { "1.0,:pserver:user:password@hostname:81/path/to/repository,module.name,project.name" }, + infoMap); + + boolean isAlternativeRepositoryNeeded = invokeIsAlternativeRepositoryNeeded( + infoMap, alternativeMap); + assertEquals(true, isAlternativeRepositoryNeeded); + } + + //TODO: add tests for alternatives repos order + + //TODO: add tests for prompter (in different class) + + // private utility methods + + private static boolean invokeIsAlternativeRepositoryNeeded(Map infoMap, + Map alternativeMap) throws InvocationTargetException { + + Class[] argClasses = { Map.class, Map.class }; + Object[] argObjects = { infoMap, alternativeMap }; + + Object isAlternativeRepositoryNeeded = invokeStaticMethod( + CVSProjectSetCapability.class, "isAlternativeRepositoryNeeded", + argClasses, argObjects); + return ((Boolean) isAlternativeRepositoryNeeded).booleanValue(); + } + + private static IProject[] invokeAsProjects(String[] referenceStrings, + Map infoMap) throws InvocationTargetException { + Class[] argClasses = { String[].class, Map.class }; + Object[] argObjects = { referenceStrings, infoMap }; + + Object projects = invokeMethod(new CVSProjectSetCapability(), + CVSProjectSetCapability.class, "asProjects", argClasses, + argObjects); + return (IProject[]) projects; + } + + private static Object invokeStaticMethod(Class targetClass, + String methodName, Class[] argClasses, Object[] argObjects) + throws InvocationTargetException { + return invokeMethod(null, targetClass, methodName, argClasses, + argObjects); + } + + private static Object invokeMethod(Object instance, Class targetClass, + String methodName, Class[] argClasses, Object[] argObjects) + throws InvocationTargetException { + + try { + Method method = targetClass.getDeclaredMethod(methodName, + argClasses); + method.setAccessible(true); + return method.invoke(instance, argObjects); + } catch (NoSuchMethodException e) { + fail(e.getMessage()); + } catch (SecurityException e) { + fail(e.getMessage()); + } catch (IllegalAccessException e) { + fail(e.getMessage()); + } catch (IllegalArgumentException e) { + fail(e.getMessage()); + } + return null; + } + +} #P org.eclipse.team.cvs.ui Index: src/org/eclipse/team/internal/ccvs/ui/CVSUIMessages.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIMessages.java,v retrieving revision 1.69 diff -u -r1.69 CVSUIMessages.java --- src/org/eclipse/team/internal/ccvs/ui/CVSUIMessages.java 18 Apr 2007 20:27:08 -0000 1.69 +++ src/org/eclipse/team/internal/ccvs/ui/CVSUIMessages.java 19 Apr 2007 14:57:03 -0000 @@ -336,6 +336,13 @@ public static String CommitWizardFileTypePage_0; public static String CommitWizardFileTypePage_2; public static String CommitWizardFileTypePage_3; + + public static String AlternativeRepositoryWizard_title; + public static String AlternativeRepositoryWizard_message; + public static String AlternativeRepositoryWizard_createLocation; + public static String AlternativeRepositoryWizard_createLocationTooltip; + public static String AlternativeRepositoryWizard_column0; + public static String AlternativeRepositoryWizard_column1; public static String CommitSyncAction_questionRelease; public static String CommitSyncAction_titleRelease; @@ -493,6 +500,14 @@ public static String NewLocationWizard_validationFailedText; public static String NewLocationWizard_validationFailedTitle; public static String NewLocationWizard_exception; + + public static String AlternativeLocationWizard_title; + public static String AlternativeLocationWizard_heading; + public static String AlternativeLocationWizard_description; + public static String AlternativeLocationWizard_validationFailedText; + public static String AlternativeLocationWizard_validationFailedTitle; + public static String AlternativeLocationWizard_exception; + public static String OpenLogEntryAction_deletedTitle; public static String OpenLogEntryAction_deleted; Index: src/org/eclipse/team/internal/ccvs/ui/messages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties,v retrieving revision 1.516 diff -u -r1.516 messages.properties --- src/org/eclipse/team/internal/ccvs/ui/messages.properties 18 Apr 2007 20:27:08 -0000 1.516 +++ src/org/eclipse/team/internal/ccvs/ui/messages.properties 19 Apr 2007 14:57:03 -0000 @@ -285,6 +285,13 @@ CommitWizardFileTypePage_2=Unknown new files detected. CommitWizardFileTypePage_3=New files with the following unknown names or extensions have been detected in the workspace. Please specify whether these files should be stored as text or binary and whether this decision should be remembered. +AlternativeRepositoryWizard_title=Select alternative repository +AlternativeRepositoryWizard_message=Select alternative repository +AlternativeRepositoryWizard_createLocation=Create Location +AlternativeRepositoryWizard_createLocationTooltip=Creates Location from a selected alternative repository +AlternativeRepositoryWizard_column0=Repository Location from the project set +AlternativeRepositoryWizard_column1=Alternative repository + CommitSyncAction_questionRelease=You have changes that conflict with the server. Release those changes? CommitSyncAction_titleRelease=Confirm Overwrite CommitSyncAction_releaseAll=Release all changes, overriding any conflicting changes on the server. @@ -449,6 +456,13 @@ NewLocationWizard_validationFailedTitle=Unable to Validate NewLocationWizard_exception=Unable to create repository location +AlternativeLocationWizard_title=Configure CVS Repository +AlternativeLocationWizard_heading=Configure an alternative CVS Repository +AlternativeLocationWizard_description=Configure an alternative CVS Repository +AlternativeLocationWizard_validationFailedText=Error validating location: "{0}"\n\nUse location anyway? +AlternativeLocationWizard_validationFailedTitle=Unable to Validate +AlternativeLocationWizard_exception=Unable to create repository location + OpenLogEntryAction_deletedTitle=Resource is Deleted OpenLogEntryAction_deleted=The selected revision represents a deletion. It cannot be opened. Index: src/org/eclipse/team/internal/ccvs/ui/wizards/NewLocationWizard.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/NewLocationWizard.java,v retrieving revision 1.28 diff -u -r1.28 NewLocationWizard.java --- src/org/eclipse/team/internal/ccvs/ui/wizards/NewLocationWizard.java 26 Jun 2006 19:31:25 -0000 1.28 +++ src/org/eclipse/team/internal/ccvs/ui/wizards/NewLocationWizard.java 19 Apr 2007 14:57:03 -0000 @@ -32,8 +32,8 @@ public class NewLocationWizard extends Wizard implements IWorkbenchWizard { - private ConfigurationWizardMainPage mainPage; - private Properties properties = null; + protected ConfigurationWizardMainPage mainPage; + protected Properties properties = null; private boolean switchPerspectives = true; /** Index: plugin.xml =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.team.cvs.ui/plugin.xml,v retrieving revision 1.277 diff -u -r1.277 plugin.xml --- plugin.xml 19 Apr 2007 14:26:06 -0000 1.277 +++ plugin.xml 19 Apr 2007 14:57:02 -0000 @@ -192,6 +192,15 @@
+ + + + + + + Index: src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryPrompter.java =================================================================== RCS file: src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryPrompter.java diff -N src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryPrompter.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryPrompter.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007 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.internal.ccvs.ui; + +import java.util.Map; + +import org.eclipse.swt.widgets.Display; +import org.eclipse.team.internal.ccvs.core.IAlternativeRepositoryPrompter; + +public class AlternativeRepositoryPrompter implements IAlternativeRepositoryPrompter { + + public AlternativeRepositoryPrompter() { + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.IAlternativeRepositoryPrompter#promptForAlternativeRepository(java.util.Map) + */ + public Object promptForAlternativeRepository(final Map alternativeMap) { + + final Object[] result = new Object[1]; + Display display = Display.getCurrent(); + if (display != null) { + result[0] = openAlternativeRepositoryDialog(alternativeMap); + } else { + // sync exec in default thread + Display.getDefault().syncExec(new Runnable() { + public void run() { + result[0] = openAlternativeRepositoryDialog(alternativeMap); + } + }); + } + + if (result[0] == null) { + //TODO: handle canceling the operation? + } + + return result[0]; + } + + private Object openAlternativeRepositoryDialog(Map alternativeMap) { + AlternativeRepositoryDialog dialog = new AlternativeRepositoryDialog(null, alternativeMap); + dialog.open(); + return dialog.getSelected(); + } +} Index: src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryTable.java =================================================================== RCS file: src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryTable.java diff -N src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryTable.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryTable.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,266 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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.internal.ccvs.ui; + +import java.util.*; +import java.util.List; + +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.TableEditor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; +import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; +import org.eclipse.team.internal.ui.PixelConverter; +import org.eclipse.team.internal.ui.SWTUtils; + + +public class AlternativeRepositoryTable implements ICellModifier, IStructuredContentProvider, ITableLabelProvider { + + private static final class AlternativeRepositoryComparator extends + ViewerComparator { + + public AlternativeRepositoryComparator() { + } + + private int getCategory(Object element) { + if (element instanceof RepositoryLocationItem) { + return 0; + } + return 2; + } + + public int compare(Viewer viewer, Object e1, Object e2) { + final int compare = getCategory(e1) - getCategory(e2); + if (compare != 0) + return compare; + return super.compare(viewer, ((Item) e1).location, + ((Item) e2).location); + } + } + + public abstract static class Item implements Comparable { + public final String location; + public List alternativeList; + public int selected; + + public Item(String name, List alternative) { + this.location = name; + this.alternativeList = alternative; + this.selected = 0; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(Object o) { + return location.compareTo(((Item) o).location); + } + } + + public static class RepositoryLocationItem extends Item { + public RepositoryLocationItem(CVSRepositoryLocation repo, + List repositoryLocation) { + super(repo.getLocation(), repositoryLocation); + } + } + + private final static int COLUMN_PADDING = 5; + + protected static final String ITEM = "item"; //$NON-NLS-1$ + protected static final String PROPERTY_ALTERNATIVE_LIST = "alternativeList"; //$NON-NLS-1$ + + private final TableViewer fTableViewer; + private final List fItems; + + private CellEditor[] cellEditors; + + private TextCellEditor dummyAlternativeRepositoryEditor; + + private final Table table; + + public AlternativeRepositoryTable(Composite composite, List items) { + + fItems = items; + + /** + * Create a table. + */ + table = new Table(composite, SWT.V_SCROLL | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION); + table.setLayoutData(SWTUtils.createHVFillGridData()); + table.setLinesVisible(true); + table.setHeaderVisible(true); + + final PixelConverter converter = SWTUtils.createDialogPixelConverter(composite); + + //TODO: columns width (@see Snippet77) + + /** + * The 'Project Set repository location' column + */ + final TableColumn projectSetRepositoryColumn = new TableColumn(table, SWT.NONE, 0); + projectSetRepositoryColumn.setWidth(converter.convertWidthInCharsToPixels(CVSUIMessages.AlternativeRepositoryWizard_column0.length() + COLUMN_PADDING)); + projectSetRepositoryColumn.setText(CVSUIMessages.AlternativeRepositoryWizard_column0); + + /** + * The 'Alternative repository locations' column + */ + final TableColumn alternativeRepositoryColums = new TableColumn(table, SWT.NONE, 1); + int length; + try { + length = CVSUIMessages.AlternativeRepositoryWizard_column1.length(); + } catch (RuntimeException e) { + // There may be an unbound message so just pick a reasonable length + length = 15; + } + alternativeRepositoryColums.setWidth(converter.convertWidthInCharsToPixels(length + COLUMN_PADDING)); + alternativeRepositoryColums.setText(CVSUIMessages.AlternativeRepositoryWizard_column1); + + /** + * Create a viewer for the table. + */ + fTableViewer = new TableViewer(table); + fTableViewer.setContentProvider(this); + fTableViewer.setLabelProvider(this); + fTableViewer.setComparator(new AlternativeRepositoryComparator()); + + /** + * Add a cell editor in the 'Alternative repository locations' column + */ + new TableEditor(table); + + cellEditors = new CellEditor[2]; + cellEditors[0] = null; + // to enable cell editing, create a dummy cell editor + cellEditors[1] = dummyAlternativeRepositoryEditor = new TextCellEditor(table, SWT.READ_ONLY); + + fTableViewer.setCellEditors(cellEditors); + fTableViewer.setColumnProperties(new String [] { ITEM, PROPERTY_ALTERNATIVE_LIST }); + fTableViewer.setCellModifier(this); + fTableViewer.setInput(fItems); + } + + + public Object getValue(Object element, String property) { + + final Item item = (Item)element; + + if (PROPERTY_ALTERNATIVE_LIST.equals(property)) { + return new Integer(item.selected); + } + return null; + } + + public boolean canModify(Object element, String property) { + // set the correct cell editor for this element + cellEditors[1] = getCellEditor(element); + // only allow modification for editable elements + return PROPERTY_ALTERNATIVE_LIST.equals(property); + } + + private CellEditor getCellEditor(Object element) { + + if (element instanceof RepositoryLocationItem) { + + // create combo-box list of alternative repositories + List alternativeList = ((RepositoryLocationItem) element).alternativeList; + String[] alternativeNames = new String[alternativeList.size()]; + int i = 0; + for (Iterator iterator = alternativeList.iterator(); iterator.hasNext();) { + CVSRepositoryLocation repo = (CVSRepositoryLocation) iterator.next(); + alternativeNames[i++] = repo.getLocation(); + } + return new ComboBoxCellEditor(table, alternativeNames, + SWT.READ_ONLY); + } + return dummyAlternativeRepositoryEditor; + } + + + public void modify(Object element, String property, Object value) { + + final IStructuredSelection selection = (IStructuredSelection)fTableViewer.getSelection(); + final Item item = (Item)selection.getFirstElement(); + if (item == null) + return; + + final int comboIndex = ((Integer)value).intValue(); + + if (PROPERTY_ALTERNATIVE_LIST.equals(property)) { + item.selected = comboIndex; + } + fTableViewer.refresh(item); + } + + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + public String getColumnText(Object element, int columnIndex) { + + final Item item = (Item) element; + + if (columnIndex == 0) { + return item.location; + } + + if (columnIndex == 1) { + return ((CVSRepositoryLocation) item.alternativeList + .get(item.selected)).getLocation(); + } + return null; + } + + public void addListener(ILabelProviderListener listener) {} + + public void dispose() {} + + public boolean isLabelProperty(Object element, String property) { + return false; + } + + public void removeListener(ILabelProviderListener listener) {} + + public Object[] getElements(Object inputElement) { + return ((Collection)inputElement).toArray(); + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} + + public IStructuredSelection getSelection() { + return (IStructuredSelection)fTableViewer.getSelection(); + } + + public TableViewer getViewer() { + return fTableViewer; + } + + public CVSRepositoryLocation getSelectedAlternativeRepository() { + RepositoryLocationItem firstElement = (RepositoryLocationItem) getSelection() + .getFirstElement(); + return (CVSRepositoryLocation) firstElement.alternativeList + .get(firstElement.selected); + } + + public void addAlternativeRepositoryToSelection( + ICVSRepositoryLocation location) { + RepositoryLocationItem firstElement = (RepositoryLocationItem) getSelection() + .getFirstElement(); + // put new alternative repository at first position + firstElement.alternativeList.add(0, location); + firstElement.selected = 0; + fTableViewer.refresh(firstElement); + } +} Index: src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryDialog.java =================================================================== RCS file: src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryDialog.java diff -N src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryDialog.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/team/internal/ccvs/ui/AlternativeRepositoryDialog.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2007 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.internal.ccvs.ui; + +import java.util.*; +import java.util.List; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.TrayDialog; +import org.eclipse.jface.viewers.*; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; +import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; +import org.eclipse.team.internal.ccvs.ui.wizards.AlternativeLocationWizard; +import org.eclipse.team.internal.ui.SWTUtils; + +public class AlternativeRepositoryDialog extends TrayDialog { + + private List fAlternatives; + private final static String title = CVSUIMessages.AlternativeRepositoryWizard_title; + private final static String message = CVSUIMessages.AlternativeRepositoryWizard_message; + + /** + * Creates a new AlternativeRepositoryDialog. + * + * @param parentShell the parent shell + * @param alternativesMap the default user name + * @param message a message to display to the user + */ + public AlternativeRepositoryDialog(Shell parentShell, Map alternativesMap/*, String message*/) { + super(parentShell); + setShellStyle(getShellStyle() | SWT.RESIZE); + fAlternatives = new ArrayList(); + for (Iterator iterator = alternativesMap.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + fAlternatives + .add(new AlternativeRepositoryTable.RepositoryLocationItem( + (CVSRepositoryLocation) entry.getKey(), + (List) entry.getValue())); + } + } + + /* + * (non-Javadoc) Method declared in Window. + */ + protected void configureShell(Shell shell) { + super.configureShell(shell); + if (title != null) { + shell.setText(title); + } + } + + /** + * @see Dialog#createDialogArea + */ + protected Control createDialogArea(Composite parent) { + initializeDialogUnits(parent); + + final Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(1, false)); + + // TODO: help + + GridData childData = new GridData(GridData.FILL_BOTH); + composite.setLayoutData(childData); + + final Label label= new Label(composite, SWT.WRAP); + label.setText(message); + label.setLayoutData(SWTUtils.createHFillGridData()); + Dialog.applyDialogFont(composite); + + final AlternativeRepositoryTable table = new AlternativeRepositoryTable(composite, fAlternatives); + + final Button createLocationButton = new Button(composite, SWT.PUSH); + createLocationButton.setText(CVSUIMessages.AlternativeRepositoryWizard_createLocation); + createLocationButton.setToolTipText(CVSUIMessages.AlternativeRepositoryWizard_createLocationTooltip); + createLocationButton.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + + CVSRepositoryLocation selectedAlternativeRepository = table.getSelectedAlternativeRepository(); + + Properties properties = new Properties(); + properties.put("connection", selectedAlternativeRepository.getMethod()); //$NON-NLS-1$ + properties.put("user", selectedAlternativeRepository.getUsername()); //$NON-NLS-1$ + //TODO: +// properties.put("password", ""); //$NON-NLS-1$ + properties.put("host", selectedAlternativeRepository.getHost()); //$NON-NLS-1$ + int port = selectedAlternativeRepository.getPort(); + if (port != ICVSRepositoryLocation.USE_DEFAULT_PORT) + properties.put("port", String.valueOf(port)); //$NON-NLS-1$ + properties.put("root", selectedAlternativeRepository.getRootDirectory()); //$NON-NLS-1$ + + AlternativeLocationWizard wizard = new AlternativeLocationWizard(properties); + wizard.setSwitchPerspectives(false); + WizardDialog dialog = new WizardDialog(getShell(), wizard); + dialog.open(); + + ICVSRepositoryLocation location = wizard.getLocation(); + if (location != null) + table.addAlternativeRepositoryToSelection(location); + } + }); + createLocationButton.setEnabled(table.getSelection().getFirstElement() != null); + + table.getViewer().addSelectionChangedListener( + new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection sel = (IStructuredSelection) event + .getSelection(); + Object firstElement = sel.getFirstElement(); + createLocationButton.setEnabled(firstElement != null); + } + }); + + return composite; + } + + protected Point getInitialSize() { + //TODO: read/write using memento + return new Point(500, 500); + } + + public Map getSelected() { + Map map = new HashMap(); + for (Iterator iterator = fAlternatives.iterator(); iterator.hasNext();) { + AlternativeRepositoryTable.RepositoryLocationItem rli = (AlternativeRepositoryTable.RepositoryLocationItem) iterator + .next(); + map.put(rli.location, rli.alternativeList.get(rli.selected)); + } + return map; + } +} Index: src/org/eclipse/team/internal/ccvs/ui/wizards/AlternativeLocationWizard.java =================================================================== RCS file: src/org/eclipse/team/internal/ccvs/ui/wizards/AlternativeLocationWizard.java diff -N src/org/eclipse/team/internal/ccvs/ui/wizards/AlternativeLocationWizard.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/team/internal/ccvs/ui/wizards/AlternativeLocationWizard.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2007 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.internal.ccvs.ui.wizards; + +import java.util.Properties; + +import org.eclipse.team.internal.ccvs.core.CVSException; +import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; +import org.eclipse.team.internal.ccvs.ui.*; + +public class AlternativeLocationWizard extends NewLocationWizard { + + private ICVSRepositoryLocation location; + + public boolean performFinish() { + // TODO: do validation (as in super) + try { + location = mainPage.getLocation(); + } catch (CVSException e) { + // TODO: ignore? + // e.printStackTrace(); + } + return true; + +// boolean performFinish = super.performFinish(); +// location = mainPage.getLocation(); +// return performFinish; + } + + public AlternativeLocationWizard(Properties initialProperties) { + super(initialProperties); + } + + /** + * Creates the wizard pages + */ + public void addPages() { + mainPage = new ConfigurationWizardMainPage("repositoryPage1", CVSUIMessages.AlternativeLocationWizard_heading, CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_WIZBAN_NEW_LOCATION)); //$NON-NLS-1$ + if (properties != null) { + mainPage.setProperties(properties); + } + mainPage.setShowValidate(true); + mainPage.setDescription(CVSUIMessages.AlternativeLocationWizard_description); + mainPage.setDialogSettings(getDialogSettings()); + addPage(mainPage); + } + + public ICVSRepositoryLocation getLocation() { + return location; + } + +}