/*******************************************************************************
* Copyright (c) 2011 GEBIT Solutions.
* 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:
* Carsten Pfeiffer(GEBIT Solutions) - initial implementation
*******************************************************************************/
package com.amazonaws.eclipse.core.egit;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.CredentialItem.CharArrayType;
import org.eclipse.jgit.transport.CredentialItem.StringType;
import org.eclipse.jgit.transport.CredentialItem.YesNoType;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
/**
* This dialog is used in order to display information about
* authentication problems, and/or request authentication input
* from the user.
*
* The {@link CredentialItem CredentialItems} passed in the constructor
* are updated to reflect the user-specified values as soon as the dialog
* is confirmed.
*/
public class CustomPromptDialog extends TrayDialog {
private CredentialItem[] credentialItems;
private List<Control> editingControls;
private URIish uri;
private String title;
private static final String KEY_ITEM = "item"; //$NON-NLS-1$
/**
* Creates an instance of the dialog that will present the given
* CredentialItems and let the user supply values for them
* @param shell the shell for this dialog
* @param uri the uri for which the information shall be displayed
* @param title an optional title for this dialog
* @param items the items to display and edit
*/
public CustomPromptDialog(Shell shell, URIish uri, String title, CredentialItem... items) {
super(shell);
this.uri = uri;
this.title = title;
setShellStyle(getShellStyle() | SWT.SHELL_TRIM);
credentialItems = items;
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
if (title != null) {
newShell.setText(title);
}
}
/**
* Returns the credential items that were passed into the constructor.
* @return the credential items
*/
public CredentialItem[] getCredentialItems() {
return credentialItems;
}
@Override
protected Control createDialogArea(Composite parent) {
editingControls = new ArrayList<Control>(credentialItems.length);
Composite main = (Composite) super.createDialogArea(parent);
GridLayout mainLayout = (GridLayout) main.getLayout();
mainLayout.numColumns = 2;
Label infoLabel = new Label(main, SWT.NONE);
GridDataFactory.defaultsFor(infoLabel).span(2, 1).applyTo(infoLabel);
String tempInfoText = hasEditingItems()
? UIText.CustomPromptDialog_provide_information_for
: UIText.CustomPromptDialog_information_about;
infoLabel.setText(NLS.bind(tempInfoText, uri.toString()));
for (CredentialItem item : credentialItems) {
Label label = new Label(main, SWT.NONE);
label.setText(item.getPromptText());
GridDataFactory.defaultsFor(label).applyTo(label);
if (item instanceof CharArrayType || item instanceof StringType) {
Text text = new Text(main, SWT.BORDER | (item.isValueSecure() ? SWT.PASSWORD : SWT.NONE));
GridDataFactory.defaultsFor(text).applyTo(text);
text.setData(KEY_ITEM, item);
editingControls.add(text);
} else if (item instanceof YesNoType) {
Button checkBox = new Button(main, SWT.CHECK);
GridDataFactory.defaultsFor(checkBox).applyTo(checkBox);
editingControls.add(checkBox);
} else {
// unknown type, not editable
Label dummy = new Label(main, SWT.NONE);
GridDataFactory.fillDefaults().applyTo(dummy);
}
}
return main;
}
/**
* Returns <code>true</code> if there's anything to edit for the user
* @return <code>true</code> if the user needs to supply some data
*/
private boolean hasEditingItems() {
for (CredentialItem item : credentialItems) {
if (item instanceof StringType) {
return true;
}
if (item instanceof CharArrayType) {
return true;
}
if (item instanceof YesNoType) {
return true;
}
}
return false;
}
@Override
protected void okPressed() {
updateValues();
super.okPressed();
}
/**
* Updates all {@link CredentialItem CredentialItems} with the
* user-supplied values.
*/
private void updateValues() {
for (Control control : editingControls) {
if (control instanceof Text) {
Text textControl = (Text) control;
CredentialItem itemToUpdate = (CredentialItem) textControl.getData(KEY_ITEM);
String value = textControl.getText();
updateValue(itemToUpdate, value);
} else if (control instanceof Button) {
Button checkBoxControl = (Button) control;
CredentialItem itemToUpdate = (CredentialItem) checkBoxControl.getData(KEY_ITEM);
boolean value = checkBoxControl.getSelection();
updateValue(itemToUpdate, value);
}
}
}
/**
* Updates the value of the given {@link CredentialItem}.
* @param itemToUpdate the item to update
* @param value the new value
*/
protected void updateValue(CredentialItem itemToUpdate, String value) {
if (itemToUpdate instanceof CharArrayType) {
((CharArrayType) itemToUpdate).setValueNoCopy(value.toCharArray());
} else if (itemToUpdate instanceof StringType) {
((StringType) itemToUpdate).setValue(value);
} else {
throw new IllegalArgumentException("Cannot handle item of type " + itemToUpdate.getClass()); //$NON-NLS-1$
}
}
/**
* Updates the value of the given {@link CredentialItem}.
* @param itemToUpdate the item to update
* @param value the new value
*/
protected void updateValue(CredentialItem itemToUpdate, boolean value) {
if (itemToUpdate instanceof YesNoType) {
((YesNoType) itemToUpdate).setValue(value);
} else {
throw new IllegalArgumentException("Cannot handle item of type " + itemToUpdate.getClass()); //$NON-NLS-1$
}
}
}