/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*******************************************************************************/
/**
*
*/
package org.ebayopensource.turmeric.eclipse.services.ui.wizards.pages;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.ebayopensource.turmeric.eclipse.core.logging.SOALogger;
import org.ebayopensource.turmeric.eclipse.core.model.IParameterElement;
import org.ebayopensource.turmeric.eclipse.core.model.services.ServiceFromTemplateWsdlParamModel;
import org.ebayopensource.turmeric.eclipse.core.model.services.ServiceFromTemplateWsdlParamModel.Operation;
import org.ebayopensource.turmeric.eclipse.core.model.services.ServiceFromTemplateWsdlParamModel.Parameter;
import org.ebayopensource.turmeric.eclipse.core.model.services.ServiceFromTemplateWsdlParamModel.TemplateWSDLModel;
import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOAProjectConstants;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.GlobalRepositorySystem;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.ISOAHelpProvider;
import org.ebayopensource.turmeric.eclipse.ui.SOABasePage;
import org.ebayopensource.turmeric.eclipse.ui.SOABaseWizard;
import org.ebayopensource.turmeric.eclipse.utils.collections.ListUtil;
import org.ebayopensource.turmeric.eclipse.utils.plugin.JDTUtil;
import org.ebayopensource.turmeric.eclipse.utils.ui.UIUtil;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DialogCellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
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.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
/**
* The Class ServiceFromNewWSDLAddOperationWizardPage.
*
* @author yayu
*/
public class ServiceFromNewWSDLAddOperationWizardPage extends SOABasePage {
/** The Constant COLUMN_NAME. */
public static final String COLUMN_NAME = "name";
/** The Constant COLUMN_INPUT_PARAM. */
public static final String COLUMN_INPUT_PARAM = "input_param";
/** The Constant COLUMN_OUTPUT_PARAM. */
public static final String COLUMN_OUTPUT_PARAM = "output_param";
/** The Constant OPERATION_COLUMN_PROPERTIES. */
public static final String[] OPERATION_COLUMN_PROPERTIES =
{COLUMN_NAME, COLUMN_INPUT_PARAM, COLUMN_OUTPUT_PARAM};
private List<Operation> operations = new ArrayList<Operation>();
private List<Operation> newOperations = new ArrayList<Operation>();
private boolean needControlButtons = true;
//UI controls
private TreeViewer operationViewer;
private Button addOpBtn;
private Button removeOpBtn;
private Button upOpBtn;
private Button downOpBtn;
/**
* Instantiates a new service from new wsdl add operation wizard page.
*
*/
public ServiceFromNewWSDLAddOperationWizardPage() {
super("newSOAServiceProjectFromBlankWSDLAddOperationWizardPage", "Service from Template WSDL - Add Operation",
"Add operations to the template WSDL");
}
/**
* Instantiates a new service from new wsdl add operation wizard page.
* @param operations the operations
* @param needControlButtons whether need control buttons
*/
public ServiceFromNewWSDLAddOperationWizardPage(List<Operation> operations,
boolean needControlButtons) {
this();
this.needControlButtons = needControlButtons;
if (operations != null) {
this.operations = operations;
}
}
/**
* {@inheritDoc}
*/
@Override
public String getDefaultValue(Text text) {
return SOAProjectConstants.EMPTY_STRING;
}
/**
* {@inheritDoc}
*/
@Override
public void createControl(Composite parent) {
try {
final Composite container = super.createParentControl(parent, 3);
createOperationViewer(container);
createControlButtons(container);
setControl(container);
dialogChanged();
} catch (Exception e) {
UIUtil.showErrorDialog(e);
SOALogger.getLogger().error(e);
}
}
private TreeViewer createOperationViewer(Composite parent) {
operationViewer = new TreeViewer(parent, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL
| SWT.FULL_SELECTION | SWT.SINGLE);
GridData data = new GridData(GridData.FILL_BOTH);
data.horizontalSpan = 2;
final Tree tree = operationViewer.getTree();
tree.setLayoutData(data);
tree.setHeaderVisible(true);
tree.setLinesVisible(true);
{
final TableLayout layout = new TableLayout();
layout.addColumnData(new ColumnWeightData(26, 120, true));
layout.addColumnData(new ColumnWeightData(37, 130, true));
layout.addColumnData(new ColumnWeightData(37, 130, true));
tree.setLayout(layout);
TreeColumn column = new TreeColumn(tree, SWT.LEFT);
column.setText("Operation Name");
// column.setImage(Activator.getImageFromRegistry("operation.gif"));
column = new TreeColumn(tree, SWT.LEFT);
column.setText("Input Parameter");
// column.setImage(Activator.getImageFromRegistry("parameter_input.gif"));
column = new TreeColumn(tree, SWT.LEFT);
column.setText("Output Parameter");
// column.setImage(Activator.getImageFromRegistry("parameter_output.gif"));
}
operationViewer.setContentProvider(new ITreeContentProvider() {
@Override
public Object[] getChildren(Object parentElement) {
return getElements(parentElement);
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
return element instanceof Collection<?>;
}
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof Collection<?>) {
return ((Collection<?>)inputElement).toArray();
}
return Collections.EMPTY_LIST.toArray();
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput,
Object newInput) {
}
});
operationViewer.setLabelProvider(new ITableLabelProvider() {
@Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
@Override
public String getColumnText(Object element, int columnIndex) {
if (element instanceof Operation) {
final Operation op = (Operation) element;
switch(columnIndex) {
case 0:
return op.getName();
case 1:
if (op.getInputParameter() != null)
return op.getInputParameter().getName();
break;
case 2:
return op.getOutputParameter().getName();
}
}
return SOAProjectConstants.EMPTY_STRING;
}
@Override
public void addListener(ILabelProviderListener listener) {
}
@Override
public void dispose() {
}
@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
@Override
public void removeListener(ILabelProviderListener listener) {
}
});
operationViewer.setColumnProperties(OPERATION_COLUMN_PROPERTIES);
operationViewer.setCellModifier(new ICellModifier() {
@Override
public boolean canModify(Object element, String property) {
return needControlButtons ? (element instanceof Operation) : newOperations.contains(element);
}
@Override
public Object getValue(Object element, String property) {
if (element instanceof Operation) {
final Operation op = (Operation) element;
if (COLUMN_INPUT_PARAM.equals(property)) {
if (op.getInputParameter() != null) {
return op.getInputParameter().getName();
}
}if (COLUMN_OUTPUT_PARAM.equals(property)) {
if (op.getOutputParameter() != null) {
return op.getOutputParameter().getName();
}
}
else if (COLUMN_NAME.equals(property)) {
return op.getName();
}
}
return SOAProjectConstants.EMPTY_STRING;
}
@Override
public void modify(Object element, String property, Object value) {
Object obj = null;
if (element instanceof TreeItem) {
final TreeItem item = (TreeItem)element;
if (item.getData() instanceof Operation) {
final Operation op = (Operation) item.getData();
if (COLUMN_NAME.equals(property)) {
if (op.getName().equals(value) == false) {
op.setName(String.valueOf(value));
if (op.getInputParameter() != null) {
op.getInputParameter().setName(
op.getName() + SOAProjectConstants.PARAMETER_INPUT_SUFFIX);
}
if (op.getOutputParameter() != null) {
op.getOutputParameter().setName(
op.getName() + SOAProjectConstants.PARAMETER_OUTPUT_SUFFIX);
}
obj = op;
}
}
}
}
if (obj != null) {
operationViewer.refresh(obj);
dialogChanged();
}
}
});
operationViewer.setCellEditors(new CellEditor[]{
new TextCellEditor(tree),
new SOADialogCellEditor(tree), new SOADialogCellEditor(tree, false)
});
operationViewer.setInput(getInputObject());
operationViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
if (event.getSelection().isEmpty() == false) {
final TemplateWSDLModel model = getSelectedModel(event.getSelection());
resetButtons(model);
}
}
});
operationViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
return operationViewer;
}
private void resetButtons(TemplateWSDLModel model) {
if (needControlButtons == true) {
final boolean isOperation = model instanceof Operation;
removeOpBtn.setEnabled(isOperation);
upOpBtn.setEnabled(false);
downOpBtn.setEnabled(false);
final int index = operations.indexOf(model);
if( index >= 0) {
upOpBtn.setEnabled(index > 0);
downOpBtn.setEnabled(index + 1 < operations.size());
}
}
}
private TemplateWSDLModel getSelectedModel(ISelection sel) {
IStructuredSelection selection = null;
if (sel == null && this.operationViewer != null) {
if (operationViewer.getSelection().isEmpty() == false
&& operationViewer.getSelection() instanceof IStructuredSelection) {
selection = (IStructuredSelection) operationViewer.getSelection();
}
} else if (sel instanceof IStructuredSelection) {
selection = (IStructuredSelection)sel;
}
if (selection != null && selection.getFirstElement() instanceof TemplateWSDLModel) {
return (TemplateWSDLModel)selection.getFirstElement();
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public String getHelpContextID() {
return GlobalRepositorySystem.instanceOf().getActiveRepositorySystem()
.getHelpProvider().getHelpContextID(
ISOAHelpProvider.PAGE_CREATE_SERVICE_FROM_TEMPLATE_WSDL);
}
/**
* {@inheritDoc}
*/
@Override
protected boolean dialogChanged() {
if(super.dialogChanged() == false)
return false;
if (getOperations().isEmpty()) {
updateStatus(operationViewer.getControl(),
"At least one operation must be added");
return false;
}
final Set<String> opNames = new HashSet<String>();
for (final Operation op : getOperations()) {
final String opName = op.getName();
if (StringUtils.isBlank(String.valueOf(opName).trim())) {
updateStatus(operationViewer.getControl(),
"Operation name must not be empty");
return false;
}
else if (opNames.contains(opName) == true) {
updateStatus(operationViewer.getControl(),
"Duplicate operation name: " + opName);
return false;
}
final IStatus status = JDTUtil.validateMethodName(opName);
if (status.isOK() == false) {
updateStatus(operationViewer.getControl(),
"'" + opName + "' is not a valid operation name");
return false;
}
if(validateWSDLOperationName(opName) == false){
updateStatus(operationViewer.getControl(),
"'" + opName + "' is not a valid WSDL operation name");
return false;
}
opNames.add(opName);
}
return true;
}
private boolean validateWSDLOperationName(String optName) {
// no validation if it is an existing operation.
if (newOperations == null) {
return true;
}
boolean isNewOperation = false;
for (Operation oprt : newOperations) {
if (oprt.getName().equals(optName)) {
isNewOperation = true;
break;
}
}
if(isNewOperation == false){
return true;
}
// check name is empty
if (optName.length() == 0) {
return false;
}
// check name is lower case started
char start = optName.charAt(0);
if (Character.isLowerCase(start) == false) {
return false;
}
// more validations may coming here...
return true;
}
private void createControlButtons(Composite parent) {
final Composite container = new Composite(parent, SWT.NONE);
container.setLayoutData(new GridData(GridData.FILL_VERTICAL));
container.setLayout(new GridLayout(1, true));
final GridData data = new GridData(GridData.FILL_HORIZONTAL);
data.widthHint = 100;
{
addOpBtn = new Button(container, SWT.PUSH);
addOpBtn.setText("Add &Operation");
addOpBtn.setLayoutData(data);
addOpBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
Operation op = ServiceFromTemplateWsdlParamModel.createOperation("newOperation");
operations.add(op);
newOperations.add(op);
operationViewer.refresh();
resetButtons(null);
dialogChanged();
if (needControlButtons == false) {
addOpBtn.setEnabled(false);
}
}
});
if (needControlButtons == true) {
removeOpBtn = new Button(container, SWT.PUSH);
removeOpBtn.setText("&Remove Operation");
removeOpBtn.setLayoutData(data);
removeOpBtn.setEnabled(false);
removeOpBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
final TemplateWSDLModel model = getSelectedModel(null);
if (model instanceof Operation && operations.remove(model)) {
operationViewer.refresh();
resetButtons(null);
dialogChanged();
}
}
});
new Label(container, SWT.LEFT);
upOpBtn = new Button(container, SWT.PUSH);
upOpBtn.setText("&Up");
upOpBtn.setLayoutData(data);
upOpBtn.setEnabled(false);
upOpBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
final TemplateWSDLModel model = getSelectedModel(null);
if (model instanceof Operation) {
ListUtil.moveOnePositionUp(operations, (Operation)model);
operationViewer.refresh();
resetButtons(model);
}
}
});
downOpBtn = new Button(container, SWT.PUSH);
downOpBtn.setText("&Down");
downOpBtn.setLayoutData(data);
downOpBtn.setEnabled(false);
downOpBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
final TemplateWSDLModel model = getSelectedModel(null);
if (model instanceof Operation) {
ListUtil.moveOnePositionDown(operations, (Operation)model);
operationViewer.refresh();
resetButtons(model);
}
}
});
}
}
}
/**
* Gets the operations.
*
* @return the operations
*/
public List<Operation> getOperations() {
return operations;
}
private Object getInputObject() {
if (this.operations.isEmpty() == true) {
final Operation op = ServiceFromTemplateWsdlParamModel.createOperation("getVersion");
op.getOutputParameter().getElements().clear();
operations.add(op);
}
return operations;
}
private class SOADialogCellEditor extends DialogCellEditor{
private boolean input;
public SOADialogCellEditor(Composite composite) {
this(composite, true);
}
public SOADialogCellEditor(Composite composite, boolean input) {
super(composite);
this.input = input;
}
@Override
protected Object openDialogBox(Control cellEditorWindow) {
final TemplateWSDLModel model = getSelectedModel(null);
if (model instanceof Operation) {
final Operation op = (Operation) model;
final IWizard soaWizard = new SOABaseWizard() {
private DataTypeManagementWizardPage datatypePage;
@Override
public IWizardPage[] getContentPages() {
final List<? extends IParameterElement> elements;
final String paramName;
if (input) {
if (op.getInputParameter() != null) {
paramName = op.getInputParameter().getName();
elements = op.getInputParameter().getElements();
} else {
paramName = op.getName() + SOAProjectConstants.PARAMETER_INPUT_SUFFIX;
elements = null;
}
} else {
paramName = op.getOutputParameter().getName();
elements = op.getOutputParameter().getElements();
}
int minimumElems = input ? 0 : 1;
datatypePage = new DataTypeManagementWizardPage(
"Add Elements to " + paramName,
elements, minimumElems);
final List<IWizardPage> pages = new ArrayList<IWizardPage>();
pages.add(datatypePage);
return pages.toArray(new IWizardPage[0]);
}
@Override
public boolean performFinish() {
if (datatypePage.getElements() != null) {
if (input) {
//has param elements
if (op.getInputParameter() == null) {
op.setInputParameter(new Parameter(
op.getName() + SOAProjectConstants.PARAMETER_INPUT_SUFFIX));
}
op.getInputParameter().setElements(datatypePage.getElements());
} else {
op.getOutputParameter().setElements(datatypePage.getElements());
}
}
return true;
}
@Override
public void setShellAtCenter(Shell activeShell) {
Rectangle rect = activeShell.getDisplay().getPrimaryMonitor().getBounds();
int width = 450, height = 400;
// Calculate the left and top
int left = (rect.width - width)/2;
int top = (rect.height - height)/2;
// Set shell bounds,
activeShell.setBounds(left, top, width, height);
}
};
final WizardDialog dialog = new WizardDialog(UIUtil.getActiveShell(), soaWizard);
if (dialog.open() == Window.OK) {
operationViewer.refresh(op);
}
}
return "";
}
}
public List<Operation> getNewOperations() {
return newOperations;
}
}