/*******************************************************************************
* Copyright (c) 2015 Pivotal, Inc.
* 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:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.cloudfoundry;
import java.util.List;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.springframework.ide.eclipse.boot.dash.BootDashActivator;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.client.CFEntity;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.client.CFOrganization;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.client.CFSpace;
import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression;
import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult;
import org.springsource.ide.eclipse.commons.livexp.core.ValueListener;
/**
* Wizard page to allow users to select a target cloud space when cloning an
* existing server.
*/
class OrgsAndSpacesWizardPage extends WizardPage implements ValueListener<ValidationResult> {
protected TreeViewer orgsSpacesViewer;
private final CloudFoundryTargetWizardModel targetProperties;
private final OrgsAndSpaces spaces;
private boolean canFinish = false;
OrgsAndSpacesWizardPage(CloudFoundryTargetWizardModel targetWizardModel) {
super("Select an Org and Space");
setTitle("Select an Org and Space");
setDescription("Select a space in " + targetWizardModel.getUrl());
this.setImageDescriptor(BootDashActivator.getImageDescriptor("icons/wizban_cloudfoundry.png"));
this.targetProperties = targetWizardModel;
this.spaces = targetWizardModel.getSpaces();
targetWizardModel.addAllPropertiesListener(this);
}
@Override
public void dispose() {
this.targetProperties.removeAllPropertiesListeners(this);
super.dispose();
}
@Override
public boolean isPageComplete() {
return canFinish && targetProperties.getSpaceName() != null && targetProperties.getOrganizationName() != null;
}
@Override
public void createControl(Composite parent) {
Composite mainComposite = new Composite(parent, SWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(mainComposite);
GridDataFactory.fillDefaults().grab(true, true).applyTo(mainComposite);
Label orgLabel = new Label(mainComposite, SWT.NONE);
GridDataFactory.fillDefaults().grab(false, false).applyTo(orgLabel);
orgLabel.setText("Orgs:");
Tree orgTable = new Tree(mainComposite, SWT.BORDER | SWT.SINGLE);
GridDataFactory.fillDefaults().grab(true, true).applyTo(orgTable);
orgsSpacesViewer = new TreeViewer(orgTable);
orgsSpacesViewer.setContentProvider(new TableContentProvider());
orgsSpacesViewer.setLabelProvider(new SpacesLabelProvider());
orgsSpacesViewer.setSorter(new SpacesSorter());
orgsSpacesViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
refresh();
}
});
setControl(mainComposite);
setInput();
}
public void setInput() {
List<CFOrganization> orgInput = spaces.getOrgs();
CFOrganization[] organizationInput = orgInput.toArray(new CFOrganization[orgInput.size()]);
orgsSpacesViewer.setInput(organizationInput);
// Expand all first, so that child elements can be selected
orgsSpacesViewer.setExpandedElements(organizationInput);
setInitialSelectionInViewer();
}
protected void setInitialSelectionInViewer() {
CFSpace selectedSpace = spaces.getAllSpaces().get(0);
if (selectedSpace != null) {
setSpaceInProperties(selectedSpace);
setSelectionInViewer(selectedSpace);
}
}
protected void setSelectionInViewer(CFSpace selectedSpace) {
// Now set the cloud space in the tree
Tree tree = orgsSpacesViewer.getTree();
TreeItem[] orgItems = tree.getItems();
if (orgItems != null) {
TreeItem orgItem = null;
// Find the tree item corresponding to the cloud space's
// org
for (TreeItem item : orgItems) {
Object treeObj = item.getData();
if (treeObj instanceof CFOrganization
&& ((CFOrganization) treeObj).getName().equals(selectedSpace.getOrganization().getName())) {
orgItem = item;
break;
}
}
if (orgItem != null) {
TreeItem[] children = orgItem.getItems();
if (children != null) {
for (TreeItem childItem : children) {
Object treeObj = childItem.getData();
if (treeObj instanceof CFSpace
&& ((CFSpace) treeObj).getName().equals(selectedSpace.getName())) {
tree.select(childItem);
break;
}
}
}
}
}
}
protected void refresh() {
if (orgsSpacesViewer != null) {
Tree tree = orgsSpacesViewer.getTree();
TreeItem[] selectedItems = tree.getSelection();
if (selectedItems != null && selectedItems.length > 0) {
// It's a single selection tree, so only get the first selection
Object selectedObj = selectedItems[0].getData();
setSpaceInProperties(selectedObj instanceof CFSpace ? (CFSpace) selectedObj : null);
}
}
refreshWizardUI();
}
protected void setSpaceInProperties(CFSpace selectedSpace) {
targetProperties.setSpace(selectedSpace);
}
private void refreshWizardUI() {
if (getWizard() != null && getWizard().getContainer() != null) {
setPageComplete(targetProperties.getSpaceName() != null && targetProperties.getOrganizationName() != null);
getWizard().getContainer().updateButtons();
}
}
static class SpacesSorter extends ViewerSorter {
public SpacesSorter() {
}
public int compare(Viewer viewer, Object e1, Object e2) {
if (e1 instanceof CFEntity && e2 instanceof CFEntity) {
String name1 = ((CFEntity) e1).getName();
String name2 = ((CFEntity) e2).getName();
return name1.compareTo(name2);
}
return super.compare(viewer, e1, e2);
}
}
class TableContentProvider implements ITreeContentProvider {
private Object[] elements;
public TableContentProvider() {
}
public void dispose() {
}
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof CFOrganization) {
List<CFSpace> children = spaces.getOrgSpaces(((CFOrganization) parentElement).getName());
if (children != null) {
return children.toArray(new CFSpace[children.size()]);
}
}
return null;
}
public Object[] getElements(Object inputElement) {
return elements;
}
public Object getParent(Object element) {
return null;
}
public boolean hasChildren(Object element) {
return false;
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (newInput instanceof Object[]) {
elements = (Object[]) newInput;
}
}
}
static class SpacesLabelProvider extends LabelProvider {
public SpacesLabelProvider() {
}
public String getText(Object element) {
if (element instanceof CFEntity) {
CFEntity cloudEntity = (CFEntity) element;
return cloudEntity.getName();
}
return super.getText(element);
}
}
@Override
public void gotValue(LiveExpression<ValidationResult> exp, ValidationResult value) {
setErrorMessage(null);
canFinish = true;
if (value.status == IStatus.ERROR) {
setErrorMessage(value.msg);
canFinish = false;
} else {
setMessage(value.msg, value.status);
}
refreshWizardUI();
}
}