Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 237500 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/mylyn/internal/sandbox/ui/wizards/AbstractRepositorySettingsPage.java (+1550 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2007 Mylyn project committers and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *******************************************************************************/
8
9
package org.eclipse.mylyn.internal.sandbox.ui.wizards;
10
11
import java.lang.reflect.InvocationTargetException;
12
import java.nio.charset.Charset;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Set;
16
import java.util.SortedSet;
17
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.IStatus;
21
import org.eclipse.core.runtime.OperationCanceledException;
22
import org.eclipse.core.runtime.Status;
23
import org.eclipse.jface.dialogs.IMessageProvider;
24
import org.eclipse.jface.layout.GridDataFactory;
25
import org.eclipse.jface.operation.IRunnableWithProgress;
26
import org.eclipse.jface.preference.PreferenceDialog;
27
import org.eclipse.jface.preference.StringFieldEditor;
28
import org.eclipse.jface.wizard.WizardPage;
29
import org.eclipse.mylyn.commons.core.StatusHandler;
30
import org.eclipse.mylyn.commons.net.AuthenticationCredentials;
31
import org.eclipse.mylyn.commons.net.AuthenticationType;
32
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
33
import org.eclipse.mylyn.internal.sandbox.ui.editors.TaskEditorExtensions;
34
import org.eclipse.mylyn.internal.sandbox.ui.editors.TaskEditorExtensions.RegisteredTaskEditorExtension;
35
import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants;
36
import org.eclipse.mylyn.internal.tasks.core.RepositoryTemplateManager;
37
import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryManager;
38
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
39
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
40
import org.eclipse.mylyn.tasks.core.RepositoryTemplate;
41
import org.eclipse.mylyn.tasks.core.TaskRepository;
42
import org.eclipse.mylyn.tasks.ui.TasksUi;
43
import org.eclipse.mylyn.tasks.ui.TasksUiImages;
44
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
45
import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPage;
46
import org.eclipse.swt.SWT;
47
import org.eclipse.swt.events.FocusAdapter;
48
import org.eclipse.swt.events.FocusEvent;
49
import org.eclipse.swt.events.ModifyEvent;
50
import org.eclipse.swt.events.ModifyListener;
51
import org.eclipse.swt.events.SelectionAdapter;
52
import org.eclipse.swt.events.SelectionEvent;
53
import org.eclipse.swt.events.SelectionListener;
54
import org.eclipse.swt.layout.FillLayout;
55
import org.eclipse.swt.layout.GridData;
56
import org.eclipse.swt.layout.GridLayout;
57
import org.eclipse.swt.widgets.Button;
58
import org.eclipse.swt.widgets.Combo;
59
import org.eclipse.swt.widgets.Composite;
60
import org.eclipse.swt.widgets.Display;
61
import org.eclipse.swt.widgets.Label;
62
import org.eclipse.swt.widgets.Text;
63
import org.eclipse.ui.IWorkbench;
64
import org.eclipse.ui.dialogs.PreferencesUtil;
65
import org.eclipse.ui.forms.events.ExpansionAdapter;
66
import org.eclipse.ui.forms.events.ExpansionEvent;
67
import org.eclipse.ui.forms.events.HyperlinkAdapter;
68
import org.eclipse.ui.forms.events.HyperlinkEvent;
69
import org.eclipse.ui.forms.events.IHyperlinkListener;
70
import org.eclipse.ui.forms.widgets.ExpandableComposite;
71
import org.eclipse.ui.forms.widgets.FormToolkit;
72
import org.eclipse.ui.forms.widgets.Hyperlink;
73
74
/**
75
 * Extend to provide custom repository settings. This page is typically invoked by the user requesting properties via
76
 * the Task Repositories view.
77
 * 
78
 * @author Mik Kersten
79
 * @author Rob Elves
80
 * @author Steffen Pingel
81
 * @author Frank Becker
82
 */
83
public abstract class AbstractRepositorySettingsPage extends WizardPage implements ITaskRepositoryPage {
84
85
	protected static final String PREFS_PAGE_ID_NET_PROXY = "org.eclipse.ui.net.NetPreferences";
86
87
	protected static final String LABEL_REPOSITORY_LABEL = "Label: ";
88
89
	protected static final String LABEL_SERVER = "Server: ";
90
91
	protected static final String LABEL_USER = "User ID: ";
92
93
	protected static final String LABEL_PASSWORD = "Password: ";
94
95
	protected static final String URL_PREFIX_HTTPS = "https://";
96
97
	protected static final String URL_PREFIX_HTTP = "http://";
98
99
	protected static final String INVALID_REPOSITORY_URL = "Repository url is invalid.";
100
101
	protected static final String INVALID_LOGIN = "Unable to authenticate with repository. Login credentials invalid.";
102
103
	protected AbstractRepositoryConnector connector;
104
105
	protected StringFieldEditor repositoryLabelEditor;
106
107
	protected Combo serverUrlCombo;
108
109
	private String serverVersion = TaskRepository.NO_VERSION_SPECIFIED;
110
111
	protected StringFieldEditor repositoryUserNameEditor;
112
113
	protected StringFieldEditor repositoryPasswordEditor;
114
115
	protected StringFieldEditor httpAuthUserNameEditor;
116
117
	protected StringFieldEditor httpAuthPasswordEditor;
118
119
	protected StringFieldEditor proxyHostnameEditor;
120
121
	protected StringFieldEditor proxyPortEditor;
122
123
	protected StringFieldEditor proxyUserNameEditor;
124
125
	protected StringFieldEditor proxyPasswordEditor;
126
127
	protected TaskRepository repository;
128
129
	private Button validateServerButton;
130
131
	private Combo otherEncodingCombo;
132
133
	private Button defaultEncoding;
134
135
	// private Combo timeZonesCombo;
136
137
	protected Button anonymousButton;
138
139
	private String oldUsername;
140
141
	private String oldPassword;
142
143
	private String oldHttpAuthUserId;
144
145
	private String oldHttpAuthPassword;
146
147
	private boolean needsAnonymousLogin;
148
149
	private boolean needsTimeZone;
150
151
	private boolean needsEncoding;
152
153
	private boolean needsHttpAuth;
154
155
	private boolean needsValidation;
156
157
	private boolean needsAdvanced;
158
159
	private boolean needsEditorExtensionSelector;
160
161
	protected Composite compositeContainer;
162
163
	private Composite advancedComp;
164
165
	private Composite httpAuthComp;
166
167
	private Composite proxyAuthComp;
168
169
	private ExpandableComposite advancedExpComposite;
170
171
	private ExpandableComposite httpAuthExpComposite;
172
173
	private ExpandableComposite proxyExpComposite;
174
175
	private Set<String> repositoryUrls;
176
177
	private String originalUrl;
178
179
	private Button otherEncoding;
180
181
	private Button httpAuthButton;
182
183
	private boolean needsProxy;
184
185
	private Button systemProxyButton;
186
187
	private String oldProxyUsername = "";
188
189
	private String oldProxyPassword = "";
190
191
	// private Button proxyAuthButton;
192
193
	private String oldProxyHostname = "";
194
195
	private String oldProxyPort = "";
196
197
	private Button proxyAuthButton;
198
199
	private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
200
201
	private Hyperlink createAccountHyperlink;
202
203
	private Hyperlink manageAccountHyperlink;
204
205
	private Button savePasswordButton;
206
207
	private Button saveHttpPasswordButton;
208
209
	private Button saveProxyPasswordButton;
210
211
	private Button disconnectedButton;
212
213
	private RegisteredTaskEditorExtension[] editorExtensions;
214
215
	/**
216
	 * @since 3.0
217
	 */
218
	public AbstractRepositorySettingsPage(String title, String description, TaskRepository taskRepository) {
219
		super(title);
220
		this.repository = taskRepository;
221
		this.connector = TasksUi.getRepositoryManager().getRepositoryConnector(getConnectorKind());
222
		setTitle(title);
223
		setDescription(description);
224
		setNeedsAnonymousLogin(false);
225
		setNeedsEncoding(true);
226
		setNeedsTimeZone(true);
227
		setNeedsProxy(true);
228
		setNeedsValidation(true);
229
		setNeedsAdvanced(true);
230
		setNeedsEditorExtensionSelector(true);
231
	}
232
233
	/**
234
	 * @since 3.0
235
	 */
236
	public abstract String getConnectorKind();
237
238
	@Override
239
	public void dispose() {
240
		super.dispose();
241
		if (toolkit != null) {
242
			if (toolkit.getColors() != null) {
243
				toolkit.dispose();
244
			}
245
		}
246
	}
247
248
	public void createControl(Composite parent) {
249
		if (repository != null) {
250
			originalUrl = repository.getRepositoryUrl();
251
			AuthenticationCredentials oldCredentials = repository.getCredentials(AuthenticationType.REPOSITORY);
252
			if (oldCredentials != null) {
253
				oldUsername = oldCredentials.getUserName();
254
				oldPassword = oldCredentials.getPassword();
255
			} else {
256
				oldUsername = "";
257
				oldPassword = "";
258
			}
259
260
			AuthenticationCredentials oldHttpCredentials = repository.getCredentials(AuthenticationType.HTTP);
261
			if (oldHttpCredentials != null) {
262
				oldHttpAuthUserId = oldHttpCredentials.getUserName();
263
				oldHttpAuthPassword = oldHttpCredentials.getPassword();
264
			} else {
265
				oldHttpAuthPassword = null;
266
				oldHttpAuthUserId = null;
267
			}
268
269
			oldProxyHostname = repository.getProperty(TaskRepository.PROXY_HOSTNAME);
270
			oldProxyPort = repository.getProperty(TaskRepository.PROXY_PORT);
271
			if (oldProxyHostname == null) {
272
				oldProxyHostname = "";
273
			}
274
			if (oldProxyPort == null) {
275
				oldProxyPort = "";
276
			}
277
278
			AuthenticationCredentials oldProxyCredentials = repository.getCredentials(AuthenticationType.PROXY);
279
			if (oldProxyCredentials != null) {
280
				oldProxyUsername = oldProxyCredentials.getUserName();
281
				oldProxyPassword = oldProxyCredentials.getPassword();
282
			} else {
283
				oldProxyUsername = null;
284
				oldProxyPassword = null;
285
			}
286
287
		} else {
288
			oldUsername = "";
289
			oldPassword = "";
290
			oldHttpAuthPassword = null;
291
			oldHttpAuthUserId = null;
292
		}
293
294
		compositeContainer = new Composite(parent, SWT.NULL);
295
		FillLayout layout = new FillLayout();
296
		compositeContainer.setLayout(layout);
297
298
		new Label(compositeContainer, SWT.NONE).setText(LABEL_SERVER);
299
		serverUrlCombo = new Combo(compositeContainer, SWT.DROP_DOWN);
300
		serverUrlCombo.addModifyListener(new ModifyListener() {
301
			public void modifyText(ModifyEvent e) {
302
				if (getWizard() != null) {
303
					getWizard().getContainer().updateButtons();
304
				}
305
			}
306
		});
307
		serverUrlCombo.addFocusListener(new FocusAdapter() {
308
309
			@Override
310
			public void focusLost(FocusEvent e) {
311
				updateHyperlinks();
312
			}
313
		});
314
		serverUrlCombo.addSelectionListener(new SelectionAdapter() {
315
			@Override
316
			public void widgetSelected(SelectionEvent e) {
317
				if (getWizard() != null) {
318
					getWizard().getContainer().updateButtons();
319
				}
320
			}
321
		});
322
323
		GridDataFactory.fillDefaults().hint(300, SWT.DEFAULT).grab(true, false).applyTo(serverUrlCombo);
324
325
		repositoryLabelEditor = new StringFieldEditor("", LABEL_REPOSITORY_LABEL, StringFieldEditor.UNLIMITED,
326
				compositeContainer) {
327
328
			@Override
329
			protected boolean doCheckState() {
330
				return true;
331
				// return isValidUrl(getStringValue());
332
			}
333
334
			@Override
335
			protected void valueChanged() {
336
				super.valueChanged();
337
				if (getWizard() != null) {
338
					getWizard().getContainer().updateButtons();
339
				}
340
			}
341
		};
342
		// repositoryLabelEditor.setErrorMessage("error");
343
344
		if (needsAnonymousLogin()) {
345
			anonymousButton = new Button(compositeContainer, SWT.CHECK);
346
			GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(anonymousButton);
347
348
			anonymousButton.setText("Anonymous Access");
349
			anonymousButton.addSelectionListener(new SelectionAdapter() {
350
				@Override
351
				public void widgetSelected(SelectionEvent e) {
352
					setAnonymous(anonymousButton.getSelection());
353
					isPageComplete();
354
				}
355
			});
356
		}
357
358
		repositoryUserNameEditor = new StringFieldEditor("", LABEL_USER, StringFieldEditor.UNLIMITED,
359
				compositeContainer) {
360
361
			@Override
362
			protected boolean doCheckState() {
363
				return true;
364
			}
365
366
			@Override
367
			protected void valueChanged() {
368
				super.valueChanged();
369
				isPageComplete();
370
				if (getWizard() != null) {
371
					getWizard().getContainer().updateButtons();
372
				}
373
			}
374
		};
375
376
		repositoryPasswordEditor = new RepositoryStringFieldEditor("", LABEL_PASSWORD, StringFieldEditor.UNLIMITED,
377
				compositeContainer) {
378
379
			@Override
380
			protected boolean doCheckState() {
381
				return true;
382
			}
383
384
			@Override
385
			protected void valueChanged() {
386
				super.valueChanged();
387
				isPageComplete();
388
				if (getWizard() != null) {
389
					getWizard().getContainer().updateButtons();
390
				}
391
			}
392
		};
393
394
		savePasswordButton = new Button(compositeContainer, SWT.CHECK);
395
		GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(savePasswordButton);
396
		savePasswordButton.setText("Save Password");
397
398
		if (repository != null) {
399
			try {
400
				String repositoryLabel = repository.getProperty(IRepositoryConstants.PROPERTY_LABEL);
401
				if (repositoryLabel != null && repositoryLabel.length() > 0) {
402
					// repositoryLabelCombo.add(repositoryLabel);
403
					// repositoryLabelCombo.select(0);
404
					repositoryLabelEditor.setStringValue(repositoryLabel);
405
				}
406
				serverUrlCombo.setText(repository.getRepositoryUrl());
407
				AuthenticationCredentials credentials = repository.getCredentials(AuthenticationType.REPOSITORY);
408
				if (credentials != null) {
409
					repositoryUserNameEditor.setStringValue(credentials.getUserName());
410
					repositoryPasswordEditor.setStringValue(credentials.getPassword());
411
				} else {
412
					repositoryUserNameEditor.setStringValue("");
413
					repositoryPasswordEditor.setStringValue("");
414
				}
415
			} catch (Throwable t) {
416
				StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not set field value", t));
417
			}
418
		}
419
420
		if (needsAnonymousLogin()) {
421
			if (repository != null) {
422
				setAnonymous(repository.getCredentials(AuthenticationType.REPOSITORY) == null);
423
			} else {
424
				setAnonymous(true);
425
			}
426
		}
427
428
		if (repository != null) {
429
			savePasswordButton.setSelection(repository.getSavePassword(AuthenticationType.REPOSITORY));
430
		} else {
431
			savePasswordButton.setSelection(false);
432
		}
433
434
		// TODO: put this back if we can't get the info from all connectors
435
		// if (needsTimeZone()) {
436
		// Label timeZoneLabel = new Label(container, SWT.NONE);
437
		// timeZoneLabel.setText("Repository time zone: ");
438
		// timeZonesCombo = new Combo(container, SWT.READ_ONLY);
439
		// String[] timeZoneIds = TimeZone.getAvailableIDs();
440
		// Arrays.sort(timeZoneIds);
441
		// for (String zone : timeZoneIds) {
442
		// timeZonesCombo.add(zone);
443
		// }
444
		// boolean setZone = false;
445
		// if (repository != null) {
446
		// if (timeZonesCombo.indexOf(repository.getTimeZoneId()) > -1) {
447
		// timeZonesCombo.select(timeZonesCombo.indexOf(repository.getTimeZoneId()));
448
		// setZone = true;
449
		// }
450
		// }
451
		// if (!setZone) {
452
		// timeZonesCombo.select(timeZonesCombo.indexOf(TimeZone.getDefault().getID()));
453
		// }
454
		// }
455
456
		if (needsAdvanced() || needsEncoding() || needsEditorExtensionSelector()) {
457
458
			advancedExpComposite = toolkit.createExpandableComposite(compositeContainer, ExpandableComposite.COMPACT
459
					| ExpandableComposite.TWISTIE | ExpandableComposite.TITLE_BAR);
460
			advancedExpComposite.clientVerticalSpacing = 0;
461
			GridData gridData_2 = new GridData(SWT.FILL, SWT.FILL, true, false);
462
			gridData_2.horizontalIndent = -5;
463
			advancedExpComposite.setLayoutData(gridData_2);
464
			advancedExpComposite.setFont(compositeContainer.getFont());
465
			advancedExpComposite.setBackground(compositeContainer.getBackground());
466
			advancedExpComposite.setText("Additional Settings");
467
			advancedExpComposite.addExpansionListener(new ExpansionAdapter() {
468
				@Override
469
				public void expansionStateChanged(ExpansionEvent e) {
470
					getControl().getShell().pack();
471
				}
472
			});
473
474
			GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(advancedExpComposite);
475
476
			advancedComp = toolkit.createComposite(advancedExpComposite, SWT.NONE);
477
			GridLayout gridLayout2 = new GridLayout();
478
			gridLayout2.numColumns = 2;
479
			gridLayout2.verticalSpacing = 5;
480
			advancedComp.setLayout(gridLayout2);
481
			advancedComp.setBackground(compositeContainer.getBackground());
482
			advancedExpComposite.setClient(advancedComp);
483
484
			createAdditionalControls(advancedComp);
485
486
			if (needsEditorExtensionSelector()) {
487
				Label editorExtensionLabel = new Label(advancedComp, SWT.HORIZONTAL);
488
				editorExtensionLabel.setText("Editor Style:");
489
				GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(editorExtensionLabel);
490
491
				final Combo editorExtensionSelector = new Combo(advancedComp, SWT.READ_ONLY);
492
493
				SortedSet<RegisteredTaskEditorExtension> allEditorExtensions = TaskEditorExtensions.getTaskEditorExtensions();
494
				editorExtensions = allEditorExtensions.toArray(new RegisteredTaskEditorExtension[allEditorExtensions.size()]);
495
496
				String selectedExtensionId = TaskEditorExtensions.getTaskEditorExtensionId(repository);
497
498
				int index = 0;
499
				editorExtensionSelector.add(""); // for empty selection
500
				for (RegisteredTaskEditorExtension extension : editorExtensions) {
501
					++index;
502
					editorExtensionSelector.add(extension.getName());
503
					if (extension.getId().equals(selectedExtensionId)) {
504
						editorExtensionSelector.select(index);
505
					}
506
				}
507
508
				editorExtensionSelector.addSelectionListener(new SelectionAdapter() {
509
					@Override
510
					public void widgetSelected(SelectionEvent e) {
511
						int index = editorExtensionSelector.getSelectionIndex();
512
						String editorExtensionId = index == 0 ? "" : editorExtensions[index - 1].getId();
513
						TaskEditorExtensions.setTaskEditorExtensionId(repository, editorExtensionId);
514
					}
515
				});
516
			}
517
518
			if (needsEncoding()) {
519
				Label encodingLabel = new Label(advancedComp, SWT.HORIZONTAL);
520
				encodingLabel.setText("Character encoding:");
521
				GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.TOP).applyTo(encodingLabel);
522
523
				Composite encodingContainer = new Composite(advancedComp, SWT.NONE);
524
				GridLayout gridLayout = new GridLayout(2, false);
525
				gridLayout.marginWidth = 0;
526
				gridLayout.marginHeight = 0;
527
				encodingContainer.setLayout(gridLayout);
528
529
				defaultEncoding = new Button(encodingContainer, SWT.RADIO);
530
				defaultEncoding.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
531
				defaultEncoding.setText("Default (" + TaskRepository.DEFAULT_CHARACTER_ENCODING + ")");
532
				defaultEncoding.setSelection(true);
533
534
				otherEncoding = new Button(encodingContainer, SWT.RADIO);
535
				otherEncoding.setText("Other:");
536
				otherEncodingCombo = new Combo(encodingContainer, SWT.READ_ONLY);
537
				for (String encoding : Charset.availableCharsets().keySet()) {
538
					if (!encoding.equals(TaskRepository.DEFAULT_CHARACTER_ENCODING)) {
539
						otherEncodingCombo.add(encoding);
540
					}
541
				}
542
543
				setDefaultEncoding();
544
545
				otherEncoding.addSelectionListener(new SelectionAdapter() {
546
547
					@Override
548
					public void widgetSelected(SelectionEvent e) {
549
						if (otherEncoding.getSelection()) {
550
							defaultEncoding.setSelection(false);
551
							otherEncodingCombo.setEnabled(true);
552
						} else {
553
							defaultEncoding.setSelection(true);
554
							otherEncodingCombo.setEnabled(false);
555
						}
556
					}
557
				});
558
559
				if (repository != null) {
560
					try {
561
						String repositoryEncoding = repository.getCharacterEncoding();
562
						if (repositoryEncoding != null) {// &&
563
							// !repositoryEncoding.equals(defaultEncoding))
564
							// {
565
							if (otherEncodingCombo.getItemCount() > 0
566
									&& otherEncodingCombo.indexOf(repositoryEncoding) > -1) {
567
								otherEncodingCombo.setEnabled(true);
568
								otherEncoding.setSelection(true);
569
								defaultEncoding.setSelection(false);
570
								otherEncodingCombo.select(otherEncodingCombo.indexOf(repositoryEncoding));
571
							} else {
572
								setDefaultEncoding();
573
							}
574
						}
575
					} catch (Throwable t) {
576
						StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
577
								"Could not set field value", t));
578
					}
579
				}
580
			}
581
582
		}
583
584
		if (needsHttpAuth()) {
585
			httpAuthExpComposite = toolkit.createExpandableComposite(compositeContainer, ExpandableComposite.COMPACT
586
					| ExpandableComposite.TWISTIE | ExpandableComposite.TITLE_BAR);
587
			httpAuthExpComposite.clientVerticalSpacing = 0;
588
			GridData gridData_2 = new GridData(SWT.FILL, SWT.FILL, true, false);
589
			gridData_2.horizontalIndent = -5;
590
			httpAuthExpComposite.setLayoutData(gridData_2);
591
			httpAuthExpComposite.setFont(compositeContainer.getFont());
592
			httpAuthExpComposite.setBackground(compositeContainer.getBackground());
593
			httpAuthExpComposite.setText("Http Authentication");
594
			httpAuthExpComposite.addExpansionListener(new ExpansionAdapter() {
595
				@Override
596
				public void expansionStateChanged(ExpansionEvent e) {
597
					getControl().getShell().pack();
598
				}
599
			});
600
601
			GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(httpAuthExpComposite);
602
603
			httpAuthComp = toolkit.createComposite(httpAuthExpComposite, SWT.NONE);
604
			GridLayout gridLayout2 = new GridLayout();
605
			gridLayout2.numColumns = 2;
606
			gridLayout2.verticalSpacing = 0;
607
			httpAuthComp.setLayout(gridLayout2);
608
			httpAuthComp.setBackground(compositeContainer.getBackground());
609
			httpAuthExpComposite.setClient(httpAuthComp);
610
611
			httpAuthButton = new Button(httpAuthComp, SWT.CHECK);
612
			GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.TOP).span(2, SWT.DEFAULT).applyTo(httpAuthButton);
613
614
			httpAuthButton.setText("Enabled");
615
616
			httpAuthButton.addSelectionListener(new SelectionListener() {
617
				public void widgetSelected(SelectionEvent e) {
618
					setHttpAuth(httpAuthButton.getSelection());
619
				}
620
621
				public void widgetDefaultSelected(SelectionEvent e) {
622
					// ignore
623
				}
624
			});
625
626
			httpAuthUserNameEditor = new StringFieldEditor("", "User ID: ", StringFieldEditor.UNLIMITED, httpAuthComp) {
627
628
				@Override
629
				protected boolean doCheckState() {
630
					return true;
631
				}
632
633
				@Override
634
				protected void valueChanged() {
635
					super.valueChanged();
636
					if (getWizard() != null) {
637
						getWizard().getContainer().updateButtons();
638
					}
639
				}
640
			};
641
			httpAuthPasswordEditor = new RepositoryStringFieldEditor("", "Password: ", StringFieldEditor.UNLIMITED,
642
					httpAuthComp);
643
			((RepositoryStringFieldEditor) httpAuthPasswordEditor).getTextControl().setEchoChar('*');
644
645
			saveHttpPasswordButton = new Button(httpAuthComp, SWT.CHECK);
646
			GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(saveHttpPasswordButton);
647
			saveHttpPasswordButton.setText("Save Http Password");
648
649
			httpAuthUserNameEditor.setEnabled(httpAuthButton.getSelection(), httpAuthComp);
650
			httpAuthPasswordEditor.setEnabled(httpAuthButton.getSelection(), httpAuthComp);
651
			saveHttpPasswordButton.setEnabled(httpAuthButton.getSelection());
652
653
			if (repository != null) {
654
				saveHttpPasswordButton.setSelection(repository.getSavePassword(AuthenticationType.HTTP));
655
			} else {
656
				saveHttpPasswordButton.setSelection(false);
657
			}
658
			setHttpAuth(oldHttpAuthPassword != null || oldHttpAuthUserId != null);
659
			httpAuthExpComposite.setExpanded(httpAuthButton.getSelection());
660
		}
661
662
		if (needsProxy()) {
663
			addProxySection();
664
		}
665
666
		addStatusSection();
667
668
		Composite managementComposite = new Composite(compositeContainer, SWT.NULL);
669
		GridLayout managementLayout = new GridLayout(4, false);
670
		managementLayout.marginHeight = 0;
671
		managementLayout.marginWidth = 0;
672
		managementLayout.horizontalSpacing = 10;
673
		managementComposite.setLayout(managementLayout);
674
		managementComposite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 2, 1));
675
676
		if (needsValidation()) {
677
			validateServerButton = new Button(managementComposite, SWT.PUSH);
678
			GridDataFactory.swtDefaults().span(2, SWT.DEFAULT).grab(false, false).applyTo(validateServerButton);
679
			validateServerButton.setText("Validate Settings");
680
			validateServerButton.setImage(CommonImages.getImage(TasksUiImages.REPOSITORY_SYNCHRONIZE_SMALL));
681
			validateServerButton.addSelectionListener(new SelectionAdapter() {
682
683
				@Override
684
				public void widgetSelected(SelectionEvent e) {
685
					validateSettings();
686
				}
687
			});
688
		}
689
690
		createAccountHyperlink = toolkit.createHyperlink(managementComposite, "Create new account", SWT.NONE);
691
		createAccountHyperlink.setBackground(managementComposite.getBackground());
692
		createAccountHyperlink.addHyperlinkListener(new HyperlinkAdapter() {
693
			@Override
694
			public void linkActivated(HyperlinkEvent e) {
695
//				TaskRepository repository = getRepository();
696
				TaskRepository repository = createTaskRepository();
697
//				if (repository == null && getServerUrl() != null && getServerUrl().length() > 0) {
698
//					repository = createTaskRepository();
699
//				}
700
				if (repository != null) {
701
					String accountCreationUrl = TasksUiPlugin.getConnectorUi(connector.getConnectorKind())
702
							.getAccountCreationUrl(repository);
703
					if (accountCreationUrl != null) {
704
						TasksUiUtil.openUrl(accountCreationUrl);
705
					}
706
				}
707
			}
708
		});
709
710
		manageAccountHyperlink = toolkit.createHyperlink(managementComposite, "Change account settings", SWT.NONE);
711
		manageAccountHyperlink.setBackground(managementComposite.getBackground());
712
		manageAccountHyperlink.addHyperlinkListener(new HyperlinkAdapter() {
713
			@Override
714
			public void linkActivated(HyperlinkEvent e) {
715
				TaskRepository repository = getRepository();
716
				if (repository == null && getRepositoryUrl() != null && getRepositoryUrl().length() > 0) {
717
					repository = createTaskRepository();
718
				}
719
				if (repository != null) {
720
					String accountManagementUrl = TasksUiPlugin.getConnectorUi(connector.getConnectorKind())
721
							.getAccountManagementUrl(repository);
722
					if (accountManagementUrl != null) {
723
						TasksUiUtil.openUrl(accountManagementUrl);
724
					}
725
				}
726
			}
727
		});
728
729
		// bug 131656: must set echo char after setting value on Mac
730
		((RepositoryStringFieldEditor) repositoryPasswordEditor).getTextControl().setEchoChar('*');
731
732
		if (needsAnonymousLogin()) {
733
			// do this after username and password widgets have been intialized
734
			if (repository != null) {
735
				setAnonymous(isAnonymousAccess());
736
			}
737
		}
738
739
		updateHyperlinks();
740
741
		setControl(compositeContainer);
742
	}
743
744
	private void addProxySection() {
745
746
		proxyExpComposite = toolkit.createExpandableComposite(compositeContainer, ExpandableComposite.COMPACT
747
				| ExpandableComposite.TWISTIE | ExpandableComposite.TITLE_BAR);
748
		proxyExpComposite.clientVerticalSpacing = 0;
749
		GridData gridData_2 = new GridData(SWT.FILL, SWT.FILL, true, false);
750
		gridData_2.horizontalIndent = -5;
751
		proxyExpComposite.setLayoutData(gridData_2);
752
		proxyExpComposite.setFont(compositeContainer.getFont());
753
		proxyExpComposite.setBackground(compositeContainer.getBackground());
754
		proxyExpComposite.setText("Proxy Server Configuration");
755
		proxyExpComposite.addExpansionListener(new ExpansionAdapter() {
756
			@Override
757
			public void expansionStateChanged(ExpansionEvent e) {
758
				getControl().getShell().pack();
759
			}
760
		});
761
762
		GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(proxyExpComposite);
763
764
		proxyAuthComp = toolkit.createComposite(proxyExpComposite, SWT.NONE);
765
		GridLayout gridLayout2 = new GridLayout();
766
		gridLayout2.numColumns = 2;
767
		gridLayout2.verticalSpacing = 0;
768
		proxyAuthComp.setLayout(gridLayout2);
769
		proxyAuthComp.setBackground(compositeContainer.getBackground());
770
		proxyExpComposite.setClient(proxyAuthComp);
771
772
		Composite settingsComposite = new Composite(proxyAuthComp, SWT.NULL);
773
		GridLayout gridLayout3 = new GridLayout();
774
		gridLayout3.numColumns = 2;
775
		gridLayout3.verticalSpacing = 0;
776
		settingsComposite.setLayout(gridLayout3);
777
778
		systemProxyButton = new Button(settingsComposite, SWT.CHECK);
779
		GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.TOP).span(2, SWT.DEFAULT).applyTo(settingsComposite);
780
781
		systemProxyButton.setText("Use global Network Connections preferences");
782
		Hyperlink changeProxySettingsLink = toolkit.createHyperlink(settingsComposite, "Change Settings", SWT.NULL);
783
		changeProxySettingsLink.setBackground(compositeContainer.getBackground());
784
		changeProxySettingsLink.addHyperlinkListener(new IHyperlinkListener() {
785
786
			public void linkActivated(HyperlinkEvent e) {
787
				PreferenceDialog dlg = PreferencesUtil.createPreferenceDialogOn(getShell(), PREFS_PAGE_ID_NET_PROXY,
788
						new String[] { PREFS_PAGE_ID_NET_PROXY }, null);
789
				dlg.open();
790
			}
791
792
			public void linkEntered(HyperlinkEvent e) {
793
				// ignore
794
			}
795
796
			public void linkExited(HyperlinkEvent e) {
797
				// ignore
798
			}
799
		});
800
801
		systemProxyButton.addSelectionListener(new SelectionListener() {
802
			public void widgetSelected(SelectionEvent e) {
803
				setUseDefaultProxy(systemProxyButton.getSelection());
804
			}
805
806
			public void widgetDefaultSelected(SelectionEvent e) {
807
				// ignore
808
			}
809
		});
810
811
		proxyHostnameEditor = new StringFieldEditor("", "Proxy host address: ", StringFieldEditor.UNLIMITED,
812
				proxyAuthComp) {
813
814
			@Override
815
			protected boolean doCheckState() {
816
				return true;
817
			}
818
819
			@Override
820
			protected void valueChanged() {
821
				super.valueChanged();
822
				if (getWizard() != null) {
823
					getWizard().getContainer().updateButtons();
824
				}
825
			}
826
		};
827
		proxyHostnameEditor.setStringValue(oldProxyHostname);
828
829
		proxyPortEditor = new RepositoryStringFieldEditor("", "Proxy host port: ", StringFieldEditor.UNLIMITED,
830
				proxyAuthComp);
831
832
		proxyPortEditor.setStringValue(oldProxyPort);
833
834
		proxyHostnameEditor.setEnabled(systemProxyButton.getSelection(), proxyAuthComp);
835
		proxyPortEditor.setEnabled(systemProxyButton.getSelection(), proxyAuthComp);
836
837
		// ************* PROXY AUTHENTICATION **************
838
839
		proxyAuthButton = new Button(proxyAuthComp, SWT.CHECK);
840
		GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.TOP).span(2, SWT.DEFAULT).applyTo(proxyAuthButton);
841
842
		proxyAuthButton.setText("Enable proxy authentication");
843
		proxyAuthButton.addSelectionListener(new SelectionListener() {
844
			public void widgetSelected(SelectionEvent e) {
845
				setProxyAuth(proxyAuthButton.getSelection());
846
			}
847
848
			public void widgetDefaultSelected(SelectionEvent e) {
849
				// ignore
850
			}
851
		});
852
853
		proxyUserNameEditor = new StringFieldEditor("", "User ID: ", StringFieldEditor.UNLIMITED, proxyAuthComp) {
854
855
			@Override
856
			protected boolean doCheckState() {
857
				return true;
858
			}
859
860
			@Override
861
			protected void valueChanged() {
862
				super.valueChanged();
863
				if (getWizard() != null) {
864
					getWizard().getContainer().updateButtons();
865
				}
866
			}
867
		};
868
		proxyPasswordEditor = new RepositoryStringFieldEditor("", "Password: ", StringFieldEditor.UNLIMITED,
869
				proxyAuthComp);
870
		((RepositoryStringFieldEditor) proxyPasswordEditor).getTextControl().setEchoChar('*');
871
872
		// proxyPasswordEditor.setEnabled(httpAuthButton.getSelection(),
873
		// advancedComp);
874
		// ((StringFieldEditor)
875
		// httpAuthPasswordEditor).setEnabled(httpAuthButton.getSelection(),
876
		// advancedComp);
877
878
		saveProxyPasswordButton = new Button(proxyAuthComp, SWT.CHECK);
879
		GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(saveProxyPasswordButton);
880
		saveProxyPasswordButton.setText("Save Proxy Password");
881
		saveProxyPasswordButton.setEnabled(proxyAuthButton.getSelection());
882
883
		if (repository != null) {
884
			saveProxyPasswordButton.setSelection(repository.getSavePassword(AuthenticationType.PROXY));
885
		} else {
886
			saveProxyPasswordButton.setSelection(false);
887
		}
888
889
		setProxyAuth(oldProxyUsername != null || oldProxyPassword != null);
890
891
		setUseDefaultProxy(repository != null ? repository.isDefaultProxyEnabled() : true);
892
		proxyExpComposite.setExpanded(!systemProxyButton.getSelection());
893
	}
894
895
	private void addStatusSection() {
896
		ExpandableComposite statusComposite = toolkit.createExpandableComposite(compositeContainer,
897
				ExpandableComposite.COMPACT | ExpandableComposite.TWISTIE | ExpandableComposite.TITLE_BAR);
898
		statusComposite.clientVerticalSpacing = 0;
899
		GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false);
900
		gd.horizontalIndent = -5;
901
		statusComposite.setLayoutData(gd);
902
		statusComposite.setFont(compositeContainer.getFont());
903
		statusComposite.setBackground(compositeContainer.getBackground());
904
		statusComposite.setText("Status");
905
		statusComposite.addExpansionListener(new ExpansionAdapter() {
906
			@Override
907
			public void expansionStateChanged(ExpansionEvent e) {
908
				getControl().getShell().pack();
909
			}
910
		});
911
		GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(statusComposite);
912
913
		Composite composite = toolkit.createComposite(statusComposite, SWT.NONE);
914
		GridLayout layout = new GridLayout();
915
		layout.numColumns = 2;
916
		layout.verticalSpacing = 0;
917
		composite.setLayout(layout);
918
		composite.setBackground(compositeContainer.getBackground());
919
		statusComposite.setClient(composite);
920
921
		disconnectedButton = new Button(composite, SWT.CHECK);
922
		disconnectedButton.setText("Disconnected");
923
		GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.TOP).span(2, SWT.DEFAULT).applyTo(disconnectedButton);
924
		disconnectedButton.setSelection(repository != null ? repository.isOffline() : false);
925
		statusComposite.setExpanded(disconnectedButton.getSelection());
926
	}
927
928
	protected void setEncoding(String encoding) {
929
		if (encoding.equals(TaskRepository.DEFAULT_CHARACTER_ENCODING)) {
930
			setDefaultEncoding();
931
		} else {
932
			if (otherEncodingCombo.indexOf(encoding) != -1) {
933
				defaultEncoding.setSelection(false);
934
				otherEncodingCombo.setEnabled(true);
935
				otherEncoding.setSelection(true);
936
				otherEncodingCombo.select(otherEncodingCombo.indexOf(encoding));
937
			} else {
938
				setDefaultEncoding();
939
			}
940
		}
941
	}
942
943
	private void setDefaultEncoding() {
944
		defaultEncoding.setSelection(true);
945
		otherEncoding.setSelection(false);
946
		otherEncodingCombo.setEnabled(false);
947
		if (otherEncodingCombo.getItemCount() > 0) {
948
			otherEncodingCombo.select(0);
949
		}
950
	}
951
952
	public void setAnonymous(boolean selected) {
953
		if (!needsAnonymousLogin) {
954
			return;
955
		}
956
957
		anonymousButton.setSelection(selected);
958
959
		if (selected) {
960
			oldUsername = repositoryUserNameEditor.getStringValue();
961
			oldPassword = (repositoryPasswordEditor).getStringValue();
962
			repositoryUserNameEditor.setStringValue("");
963
			repositoryPasswordEditor.setStringValue("");
964
		} else {
965
			repositoryUserNameEditor.setStringValue(oldUsername);
966
			repositoryPasswordEditor.setStringValue(oldPassword);
967
		}
968
969
		repositoryUserNameEditor.setEnabled(!selected, compositeContainer);
970
		repositoryPasswordEditor.setEnabled(!selected, compositeContainer);
971
		savePasswordButton.setEnabled(!selected);
972
		if (getWizard() != null) {
973
			getWizard().getContainer().updateButtons();
974
		}
975
	}
976
977
	public void setHttpAuth(boolean selected) {
978
		if (!needsHttpAuth) {
979
			return;
980
		}
981
		httpAuthButton.setSelection(selected);
982
		if (!selected) {
983
			oldHttpAuthUserId = httpAuthUserNameEditor.getStringValue();
984
			oldHttpAuthPassword = httpAuthPasswordEditor.getStringValue();
985
			httpAuthUserNameEditor.setStringValue(null);
986
			httpAuthPasswordEditor.setStringValue(null);
987
		} else {
988
			httpAuthUserNameEditor.setStringValue(oldHttpAuthUserId);
989
			httpAuthPasswordEditor.setStringValue(oldHttpAuthPassword);
990
		}
991
		httpAuthUserNameEditor.setEnabled(selected, httpAuthComp);
992
		httpAuthPasswordEditor.setEnabled(selected, httpAuthComp);
993
		saveHttpPasswordButton.setEnabled(selected);
994
	}
995
996
	/**
997
	 * @since 2.2
998
	 */
999
	public boolean getHttpAuth() {
1000
		return httpAuthButton.getSelection();
1001
	}
1002
1003
	public void setUseDefaultProxy(boolean selected) {
1004
		if (!needsProxy) {
1005
			return;
1006
		}
1007
1008
		systemProxyButton.setSelection(selected);
1009
1010
		if (selected) {
1011
			oldProxyHostname = proxyHostnameEditor.getStringValue();
1012
			oldProxyPort = proxyPortEditor.getStringValue();
1013
			// proxyHostnameEditor.setStringValue(null);
1014
			// proxyPortEditor.setStringValue(null);
1015
		} else {
1016
			proxyHostnameEditor.setStringValue(oldProxyHostname);
1017
			proxyPortEditor.setStringValue(oldProxyPort);
1018
		}
1019
		proxyHostnameEditor.setEnabled(!selected, proxyAuthComp);
1020
		proxyPortEditor.setEnabled(!selected, proxyAuthComp);
1021
		proxyAuthButton.setEnabled(!selected);
1022
		setProxyAuth(proxyAuthButton.getSelection());
1023
	}
1024
1025
	public void setProxyAuth(boolean selected) {
1026
1027
		proxyAuthButton.setSelection(selected);
1028
		proxyAuthButton.setEnabled(!systemProxyButton.getSelection());
1029
		if (!selected) {
1030
			oldProxyUsername = proxyUserNameEditor.getStringValue();
1031
			oldProxyPassword = proxyPasswordEditor.getStringValue();
1032
			proxyUserNameEditor.setStringValue(null);
1033
			proxyPasswordEditor.setStringValue(null);
1034
		} else {
1035
			proxyUserNameEditor.setStringValue(oldProxyUsername);
1036
			proxyPasswordEditor.setStringValue(oldProxyPassword);
1037
		}
1038
1039
		proxyUserNameEditor.setEnabled(selected && !systemProxyButton.getSelection(), proxyAuthComp);
1040
		proxyPasswordEditor.setEnabled(selected && !systemProxyButton.getSelection(), proxyAuthComp);
1041
		saveProxyPasswordButton.setEnabled(selected && !systemProxyButton.getSelection());
1042
	}
1043
1044
	/**
1045
	 * @since 2.2
1046
	 */
1047
	public boolean getProxyAuth() {
1048
		return proxyAuthButton.getSelection();
1049
	}
1050
1051
	/**
1052
	 * @since 3.0
1053
	 */
1054
	protected void addRepositoryTemplatesToServerUrlCombo() {
1055
		final RepositoryTemplateManager templateManager = TasksUiPlugin.getRepositoryTemplateManager();
1056
		for (RepositoryTemplate template : templateManager.getTemplates(connector.getConnectorKind())) {
1057
			serverUrlCombo.add(template.label);
1058
		}
1059
		serverUrlCombo.addSelectionListener(new SelectionAdapter() {
1060
			@Override
1061
			public void widgetSelected(SelectionEvent e) {
1062
				String text = serverUrlCombo.getText();
1063
				RepositoryTemplate template = templateManager.getTemplate(connector.getConnectorKind(), text);
1064
				if (template != null) {
1065
					repositoryTemplateSelected(template);
1066
					return;
1067
				}
1068
			}
1069
1070
		});
1071
	}
1072
1073
	/**
1074
	 * @since 3.0
1075
	 */
1076
	protected void repositoryTemplateSelected(RepositoryTemplate template) {
1077
	}
1078
1079
	protected abstract void createAdditionalControls(Composite parent);
1080
1081
	protected abstract boolean isValidUrl(String name);
1082
1083
	private void updateHyperlinks() {
1084
		if (getRepositoryUrl() != null && getRepositoryUrl().length() > 0) {
1085
			TaskRepository repository = new TaskRepository(connector.getConnectorKind(), getRepositoryUrl());
1086
1087
			String accountCreationUrl = TasksUiPlugin.getConnectorUi(connector.getConnectorKind())
1088
					.getAccountCreationUrl(repository);
1089
			createAccountHyperlink.setEnabled(accountCreationUrl != null);
1090
			createAccountHyperlink.setVisible(accountCreationUrl != null);
1091
1092
			String accountManagementUrl = TasksUiPlugin.getConnectorUi(connector.getConnectorKind())
1093
					.getAccountManagementUrl(repository);
1094
			manageAccountHyperlink.setEnabled(accountManagementUrl != null);
1095
			manageAccountHyperlink.setVisible(accountManagementUrl != null);
1096
		} else {
1097
			createAccountHyperlink.setEnabled(false);
1098
			createAccountHyperlink.setVisible(false);
1099
			manageAccountHyperlink.setEnabled(false);
1100
			manageAccountHyperlink.setVisible(false);
1101
		}
1102
	}
1103
1104
	public String getRepositoryLabel() {
1105
		return repositoryLabelEditor.getStringValue();
1106
	}
1107
1108
	/**
1109
	 * @since 3.0
1110
	 */
1111
	public String getRepositoryUrl() {
1112
		return TaskRepositoryManager.stripSlashes(serverUrlCombo.getText());
1113
	}
1114
1115
	public String getUserName() {
1116
		return repositoryUserNameEditor.getStringValue();
1117
	}
1118
1119
	public String getPassword() {
1120
		return repositoryPasswordEditor.getStringValue();
1121
	}
1122
1123
	public String getHttpAuthUserId() {
1124
		if (needsHttpAuth()) {
1125
			return httpAuthUserNameEditor.getStringValue();
1126
		} else {
1127
			return "";
1128
		}
1129
	}
1130
1131
	public String getHttpAuthPassword() {
1132
		if (needsHttpAuth()) {
1133
			return httpAuthPasswordEditor.getStringValue();
1134
		} else {
1135
			return "";
1136
		}
1137
	}
1138
1139
	public String getProxyHostname() {
1140
		if (needsProxy()) {
1141
			return proxyHostnameEditor.getStringValue();
1142
		} else {
1143
			return "";
1144
		}
1145
	}
1146
1147
	public String getProxyPort() {
1148
		if (needsProxy()) {
1149
			return proxyPortEditor.getStringValue();
1150
		} else {
1151
			return "";
1152
		}
1153
	}
1154
1155
	public Boolean getUseDefaultProxy() {
1156
		if (needsProxy()) {
1157
			return systemProxyButton.getSelection();
1158
		} else {
1159
			return true;
1160
		}
1161
	}
1162
1163
	public String getProxyUserName() {
1164
		if (needsProxy()) {
1165
			return proxyUserNameEditor.getStringValue();
1166
		} else {
1167
			return "";
1168
		}
1169
	}
1170
1171
	public String getProxyPassword() {
1172
		if (needsProxy()) {
1173
			return proxyPasswordEditor.getStringValue();
1174
		} else {
1175
			return "";
1176
		}
1177
	}
1178
1179
	public void init(IWorkbench workbench) {
1180
		// ignore
1181
	}
1182
1183
	public boolean isAnonymousAccess() {
1184
		if (anonymousButton != null) {
1185
			return anonymousButton.getSelection();
1186
		} else {
1187
			return false;
1188
		}
1189
	}
1190
1191
	/**
1192
	 * Exposes StringFieldEditor.refreshValidState()
1193
	 * 
1194
	 * TODO: is there a better way?
1195
	 */
1196
	private static class RepositoryStringFieldEditor extends StringFieldEditor {
1197
		public RepositoryStringFieldEditor(String name, String labelText, int style, Composite parent) {
1198
			super(name, labelText, style, parent);
1199
		}
1200
1201
		@Override
1202
		public void refreshValidState() {
1203
			try {
1204
				super.refreshValidState();
1205
			} catch (Exception e) {
1206
				StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
1207
						"Problem refreshing password field", e));
1208
			}
1209
		}
1210
1211
		@Override
1212
		public Text getTextControl() {
1213
			return super.getTextControl();
1214
		}
1215
1216
	}
1217
1218
	@Override
1219
	public boolean isPageComplete() {
1220
		String errorMessage = null;
1221
		String url = getRepositoryUrl();
1222
		errorMessage = isUniqueUrl(url);
1223
		if (errorMessage == null && !isValidUrl(url)) {
1224
			errorMessage = "Enter a valid server url";
1225
		}
1226
		if (errorMessage == null) {
1227
			errorMessage = credentialsComplete();
1228
		}
1229
1230
		setErrorMessage(errorMessage);
1231
		return errorMessage == null;
1232
	}
1233
1234
	private String credentialsComplete() {
1235
		if ((!needsAnonymousLogin() || !anonymousButton.getSelection()) && isMissingCredentials()) {
1236
			return "Repository user name and password must not be blank";
1237
		}
1238
		return null;
1239
	}
1240
1241
	private boolean isMissingCredentials() {
1242
		return repositoryUserNameEditor.getStringValue().trim().equals("")
1243
				|| repositoryPasswordEditor.getStringValue().trim().equals("");
1244
	}
1245
1246
	protected String isUniqueUrl(String urlString) {
1247
		if (!urlString.equals(originalUrl)) {
1248
			if (repositoryUrls == null) {
1249
				List<TaskRepository> repositories = TasksUi.getRepositoryManager().getAllRepositories();
1250
				repositoryUrls = new HashSet<String>(repositories.size());
1251
				for (TaskRepository repository : repositories) {
1252
					repositoryUrls.add(repository.getRepositoryUrl());
1253
				}
1254
			}
1255
1256
			if (repositoryUrls.contains(urlString)) {
1257
				return "Repository already exists.";
1258
			}
1259
		}
1260
		return null;
1261
	}
1262
1263
	@Deprecated
1264
	public void setRepository(TaskRepository repository) {
1265
		this.repository = repository;
1266
	}
1267
1268
	public void setVersion(String previousVersion) {
1269
		if (previousVersion == null) {
1270
			serverVersion = TaskRepository.NO_VERSION_SPECIFIED;
1271
		} else {
1272
			serverVersion = previousVersion;
1273
		}
1274
	}
1275
1276
	public String getVersion() {
1277
		return serverVersion;
1278
	}
1279
1280
	public TaskRepository getRepository() {
1281
		return repository;
1282
	}
1283
1284
	public String getCharacterEncoding() {
1285
		if (defaultEncoding == null) {
1286
			return null;
1287
		}
1288
1289
		if (defaultEncoding.getSelection()) {
1290
			return TaskRepository.DEFAULT_CHARACTER_ENCODING;
1291
		} else {
1292
			if (otherEncodingCombo.getSelectionIndex() > -1) {
1293
				return otherEncodingCombo.getItem(otherEncodingCombo.getSelectionIndex());
1294
			} else {
1295
				return TaskRepository.DEFAULT_CHARACTER_ENCODING;
1296
			}
1297
		}
1298
	}
1299
1300
	public TaskRepository createTaskRepository() {
1301
		TaskRepository repository = new TaskRepository(connector.getConnectorKind(), getRepositoryUrl());
1302
		applyTo(repository);
1303
		return repository;
1304
	}
1305
1306
	/**
1307
	 * @since 2.2
1308
	 */
1309
	public void applyTo(TaskRepository repository) {
1310
		repository.setVersion(getVersion());
1311
		if (needsEncoding()) {
1312
			repository.setCharacterEncoding(getCharacterEncoding());
1313
		}
1314
1315
		if (isAnonymousAccess()) {
1316
			repository.setCredentials(AuthenticationType.REPOSITORY, null, getSavePassword());
1317
		} else {
1318
			AuthenticationCredentials credentials = new AuthenticationCredentials(getUserName(), getPassword());
1319
			repository.setCredentials(AuthenticationType.REPOSITORY, credentials, getSavePassword());
1320
		}
1321
		repository.setRepositoryLabel(getRepositoryLabel());
1322
1323
		if (needsHttpAuth()) {
1324
			if (getHttpAuth()) {
1325
				AuthenticationCredentials webCredentials = new AuthenticationCredentials(getHttpAuthUserId(),
1326
						getHttpAuthPassword());
1327
				repository.setCredentials(AuthenticationType.HTTP, webCredentials, getSaveHttpPassword());
1328
			} else {
1329
				repository.setCredentials(AuthenticationType.HTTP, null, getSaveHttpPassword());
1330
			}
1331
		}
1332
1333
		if (needsProxy()) {
1334
			repository.setProperty(TaskRepository.PROXY_USEDEFAULT, String.valueOf(getUseDefaultProxy()));
1335
			repository.setProperty(TaskRepository.PROXY_HOSTNAME, getProxyHostname());
1336
			repository.setProperty(TaskRepository.PROXY_PORT, getProxyPort());
1337
			if (getProxyAuth()) {
1338
				AuthenticationCredentials webCredentials = new AuthenticationCredentials(getProxyUserName(),
1339
						getProxyPassword());
1340
				repository.setCredentials(AuthenticationType.PROXY, webCredentials, getSaveProxyPassword());
1341
			} else {
1342
				repository.setCredentials(AuthenticationType.PROXY, null, getSaveProxyPassword());
1343
			}
1344
		}
1345
1346
		repository.setOffline(disconnectedButton.getSelection());
1347
	}
1348
1349
	public AbstractRepositoryConnector getConnector() {
1350
		return connector;
1351
	}
1352
1353
	public boolean needsEncoding() {
1354
		return needsEncoding;
1355
	}
1356
1357
	public boolean needsTimeZone() {
1358
		return needsTimeZone;
1359
	}
1360
1361
	public boolean needsAnonymousLogin() {
1362
		return needsAnonymousLogin;
1363
	}
1364
1365
	public boolean needsAdvanced() {
1366
		return needsAdvanced;
1367
	}
1368
1369
	public void setNeedsEncoding(boolean needsEncoding) {
1370
		this.needsEncoding = needsEncoding;
1371
	}
1372
1373
	public void setNeedsTimeZone(boolean needsTimeZone) {
1374
		this.needsTimeZone = needsTimeZone;
1375
	}
1376
1377
	public void setNeedsAdvanced(boolean needsAdvanced) {
1378
		this.needsAdvanced = needsAdvanced;
1379
	}
1380
1381
	public boolean needsHttpAuth() {
1382
		return this.needsHttpAuth;
1383
	}
1384
1385
	public void setNeedsHttpAuth(boolean needsHttpAuth) {
1386
		this.needsHttpAuth = needsHttpAuth;
1387
	}
1388
1389
	public void setNeedsProxy(boolean needsProxy) {
1390
		this.needsProxy = needsProxy;
1391
	}
1392
1393
	public boolean needsProxy() {
1394
		return this.needsProxy;
1395
	}
1396
1397
	public void setNeedsAnonymousLogin(boolean needsAnonymousLogin) {
1398
		this.needsAnonymousLogin = needsAnonymousLogin;
1399
	}
1400
1401
	public void setNeedsValidation(boolean needsValidation) {
1402
		this.needsValidation = needsValidation;
1403
	}
1404
1405
	public boolean needsValidation() {
1406
		return needsValidation;
1407
	}
1408
1409
	public boolean needsEditorExtensionSelector() {
1410
		return needsEditorExtensionSelector;
1411
	}
1412
1413
	public void setNeedsEditorExtensionSelector(boolean needsEditorExtensionSelector) {
1414
		this.needsEditorExtensionSelector = needsEditorExtensionSelector;
1415
	}
1416
1417
	/** for testing */
1418
	public void setUrl(String url) {
1419
		serverUrlCombo.setText(url);
1420
	}
1421
1422
	/** for testing */
1423
	public void setUserId(String id) {
1424
		repositoryUserNameEditor.setStringValue(id);
1425
	}
1426
1427
	/** for testing */
1428
	public void setPassword(String pass) {
1429
		repositoryPasswordEditor.setStringValue(pass);
1430
	}
1431
1432
	/**
1433
	 * @since 2.2
1434
	 */
1435
	public Boolean getSavePassword() {
1436
		return savePasswordButton.getSelection();
1437
	}
1438
1439
	/**
1440
	 * @since 2.2
1441
	 */
1442
	public Boolean getSaveProxyPassword() {
1443
		if (needsProxy()) {
1444
			return saveProxyPasswordButton.getSelection();
1445
		} else {
1446
			return false;
1447
		}
1448
	}
1449
1450
	/**
1451
	 * @since 2.2
1452
	 */
1453
	public Boolean getSaveHttpPassword() {
1454
		if (needsHttpAuth()) {
1455
			return saveHttpPasswordButton.getSelection();
1456
		} else {
1457
			return false;
1458
		}
1459
	}
1460
1461
	protected void validateSettings() {
1462
		final Validator validator = getValidator(createTaskRepository());
1463
		if (validator == null) {
1464
			return;
1465
		}
1466
1467
		try {
1468
			getWizard().getContainer().run(true, true, new IRunnableWithProgress() {
1469
				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
1470
					monitor.beginTask("Validating server settings", IProgressMonitor.UNKNOWN);
1471
					try {
1472
						validator.run(monitor);
1473
						if (validator.getStatus() == null) {
1474
							validator.setStatus(Status.OK_STATUS);
1475
						}
1476
					} catch (CoreException e) {
1477
						validator.setStatus(e.getStatus());
1478
					} catch (OperationCanceledException e) {
1479
						validator.setStatus(Status.CANCEL_STATUS);
1480
						throw new InterruptedException();
1481
					} catch (Exception e) {
1482
						throw new InvocationTargetException(e);
1483
					} finally {
1484
						monitor.done();
1485
					}
1486
				}
1487
			});
1488
		} catch (InvocationTargetException e) {
1489
			StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
1490
					"Internal error validating repository", e.getCause()));
1491
			return;
1492
		} catch (InterruptedException e) {
1493
			// canceled
1494
			return;
1495
		}
1496
1497
		applyValidatorResult(validator);
1498
		getWizard().getContainer().updateButtons();
1499
	}
1500
1501
	protected void applyValidatorResult(Validator validator) {
1502
		IStatus status = validator.getStatus();
1503
		String message = status.getMessage();
1504
		if (message == null || message.length() == 0) {
1505
			message = null;
1506
		}
1507
		switch (status.getSeverity()) {
1508
		case IStatus.OK:
1509
			if (status == Status.OK_STATUS) {
1510
				if (getUserName().length() > 0) {
1511
					message = "Authentication credentials are valid.";
1512
				} else {
1513
					message = "Repository is valid.";
1514
				}
1515
			}
1516
			setMessage(message, IMessageProvider.INFORMATION);
1517
			break;
1518
		case IStatus.INFO:
1519
			setMessage(message, IMessageProvider.INFORMATION);
1520
			break;
1521
		case IStatus.WARNING:
1522
			setMessage(message, IMessageProvider.WARNING);
1523
			break;
1524
		default:
1525
			setMessage(message, IMessageProvider.ERROR);
1526
			break;
1527
		}
1528
		setErrorMessage(null);
1529
	}
1530
1531
	protected abstract Validator getValidator(TaskRepository repository);
1532
1533
	// public for testing
1534
	public abstract class Validator {
1535
1536
		private IStatus status;
1537
1538
		public abstract void run(IProgressMonitor monitor) throws CoreException;
1539
1540
		public IStatus getStatus() {
1541
			return status;
1542
		}
1543
1544
		public void setStatus(IStatus status) {
1545
			this.status = status;
1546
		}
1547
1548
	}
1549
1550
}

Return to bug 237500