package com.amazonaws.eclipse.codedeploy.deploy.wizard.page;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.databinding.AggregateValidationStatus;
import org.eclipse.core.databinding.observable.ChangeEvent;
import org.eclipse.core.databinding.observable.IChangeListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import com.amazonaws.eclipse.codedeploy.appspec.AppspecTemplateRegistry;
import com.amazonaws.eclipse.codedeploy.appspec.model.AppspecTemplateMetadataModel;
import com.amazonaws.eclipse.codedeploy.deploy.wizard.model.DeployProjectToCodeDeployWizardDataModel;
public class AppspecTemplateSelectionPage extends WizardPage {
/* Data model */
private final DeployProjectToCodeDeployWizardDataModel dataModel;
/**
* For fast look-up when switching the top control
*/
private final Map<AppspecTemplateMetadataModel, AppspecTemplateConfigComposite> templateConfigCompositeMap =
new HashMap<AppspecTemplateMetadataModel, AppspecTemplateConfigComposite>();
/* UI widgets */
private ComboViewer appspecTemplateSelectionCombo;
private Composite stackArea;
private AppspecTemplateConfigComposite selectedTemplateComposite;
/**
* The validation status listener to be registered to the template config UI
* composite that is currently shown in the page.
*/
private final IChangeListener selectedTemplateConfigValidationStatusListener = new IChangeListener() {
public void handleChange(ChangeEvent event) {
Object observable = event.getObservable();
if (observable instanceof AggregateValidationStatus == false) return;
AggregateValidationStatus statusObservable = (AggregateValidationStatus)observable;
Object statusObservableValue = statusObservable.getValue();
if (statusObservableValue instanceof IStatus == false) return;
IStatus status = (IStatus)statusObservableValue;
boolean success = (status.getSeverity() == IStatus.OK);
setPageComplete(success);
if (success) {
setMessage("", IStatus.OK);
} else {
setMessage(status.getMessage(), IStatus.ERROR);
}
}
};
public AppspecTemplateSelectionPage(DeployProjectToCodeDeployWizardDataModel dataModel) {
super("Appspec Template Configuration");
setTitle("Appspec Template Configuration");
setDescription("");
this.dataModel = dataModel;
}
public Map<String, String> getParamValuesForSelectedTemplate() {
if (selectedTemplateComposite != null) {
return selectedTemplateComposite.getAllParameterValues();
}
return Collections.emptyMap();
}
public void createControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(3, false));
List<AppspecTemplateMetadataModel> allModels =
AppspecTemplateRegistry.getInstance().getDefaultTemplates();
allModels.addAll(AppspecTemplateRegistry.getInstance().getCustomTemplates());
createAppspecTemplateSelection(composite, allModels);
stackArea = new Composite(composite, SWT.NONE);
GridData stackAreaLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
stackAreaLayoutData.horizontalSpan = 3;
stackArea.setLayoutData(stackAreaLayoutData);
stackArea.setLayout(new StackLayout());
createStackedTemplateConfigComposites(stackArea, allModels);
AppspecTemplateMetadataModel initSelection = allModels.get(0);
appspecTemplateSelectionCombo.setSelection(
new StructuredSelection(initSelection), true);
setControl(composite);
setPageComplete(true);
}
private void createAppspecTemplateSelection(
Composite parent, List<AppspecTemplateMetadataModel> allModels) {
new Label(parent, SWT.READ_ONLY).setText("Appspec template: ");
appspecTemplateSelectionCombo = new ComboViewer(parent, SWT.DROP_DOWN
| SWT.READ_ONLY);
appspecTemplateSelectionCombo.getCombo().setLayoutData(
new GridData(SWT.FILL, SWT.CENTER, true, false));
appspecTemplateSelectionCombo.setContentProvider(ArrayContentProvider.getInstance());
appspecTemplateSelectionCombo.setLabelProvider(new LabelProvider() {
@Override
public String getText(Object element) {
if (element instanceof AppspecTemplateMetadataModel) {
AppspecTemplateMetadataModel model = (AppspecTemplateMetadataModel) element;
return model.getTemplateName();
}
return super.getText(element);
}
});
appspecTemplateSelectionCombo.setInput(allModels);
appspecTemplateSelectionCombo
.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection) event
.getSelection();
Object selectedObject = selection.getFirstElement();
if (selectedObject instanceof AppspecTemplateMetadataModel) {
AppspecTemplateMetadataModel model = (AppspecTemplateMetadataModel) selectedObject;
onTemplateSelectionChanged(model);
}
}
});
Button importTemplateBtn = new Button(parent, SWT.PUSH);
importTemplateBtn.setText("Import new template");
importTemplateBtn.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
importTemplateBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent arg0) {
ImportAppspecTemplateMetadataDialog importDialog = new ImportAppspecTemplateMetadataDialog(
Display.getCurrent().getActiveShell());
int returnCode = importDialog.open();
if (returnCode != IDialogConstants.CANCEL_ID) {
selectImportedTemplate();
}
}
});
}
@SuppressWarnings("unchecked")
private void selectImportedTemplate() {
Set<String> existingTemplateNames = new HashSet<String>();
for (AppspecTemplateMetadataModel template : templateConfigCompositeMap.keySet()) {
existingTemplateNames.add(template.getTemplateName());
}
// Now re-load from the registry and find the new template model
for (AppspecTemplateMetadataModel template : AppspecTemplateRegistry
.getInstance().getCustomTemplates()) {
if ( !existingTemplateNames.contains(template.getTemplateName()) ) {
AppspecTemplateMetadataModel newTemplate = template;
((List<AppspecTemplateMetadataModel>) appspecTemplateSelectionCombo
.getInput()).add(newTemplate);
AppspecTemplateConfigComposite newTemplateComposite = new AppspecTemplateConfigComposite(
stackArea, SWT.NONE, newTemplate);
templateConfigCompositeMap.put(newTemplate, newTemplateComposite);
appspecTemplateSelectionCombo.refresh();
appspecTemplateSelectionCombo.setSelection(
new StructuredSelection(newTemplate), true);
return;
}
}
}
private void createStackedTemplateConfigComposites(
Composite parent, List<AppspecTemplateMetadataModel> allModels) {
for (AppspecTemplateMetadataModel templateModel : allModels) {
AppspecTemplateConfigComposite templateConfigComposite = new AppspecTemplateConfigComposite(
parent, SWT.NONE, templateModel);
// put it into the look-up hashmap
templateConfigCompositeMap.put(templateModel, templateConfigComposite);
}
}
private void onTemplateSelectionChanged(AppspecTemplateMetadataModel model) {
if (selectedTemplateComposite != null) {
selectedTemplateComposite.removeValidationStatusChangeListener();
}
AppspecTemplateConfigComposite compositeToShow = templateConfigCompositeMap.get(model);
if (compositeToShow != null) {
StackLayout stackLayout = (StackLayout) stackArea.getLayout();
stackLayout.topControl = compositeToShow;
compositeToShow.setValidationStatusChangeListener(selectedTemplateConfigValidationStatusListener);
compositeToShow.updateValidationStatus();
stackArea.layout();
selectedTemplateComposite = compositeToShow;
dataModel.setTemplateModel(compositeToShow.getTemplateModel());
}
}
}