/*******************************************************************************
* Copyright (c) 2012 - 2014 Red Hat, Inc. and others.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.ws.ui.dialogs;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
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.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.jboss.tools.ws.ui.messages.JBossWSUIMessages;
import org.jboss.tools.ws.ui.utils.JAXRSPathTemplateParser;
/**
* Dialog that pops up if the URL has parameters that need values.
* This should only appear if it's a JAX-RS endpoint being tested from the
* JAX-RS tooling.
* @author bfitzpat
*
*/
public class WSTesterURLInputsDialog extends TitleAreaDialog {
private TreeViewer treeRequestBody;
private static final String NAME_COLUMN = "name";//$NON-NLS-1$
private static final String VALUE_COLUMN = "value";//$NON-NLS-1$
private static final String TYPE_COLUMN = "datatype";//$NON-NLS-1$
private static final String[] TREE_COLUMNS = new String[] { NAME_COLUMN, VALUE_COLUMN, TYPE_COLUMN };
private String stashedURL;
private URLTemplateParameter[] parms;
private Button mOKButton = null;
/**
* Constructor
* @param parentShell
* @param url
*/
public WSTesterURLInputsDialog(Shell parentShell, String url) {
super(parentShell);
stashedURL = url;
parms = JAXRSPathTemplateParser.parse(stashedURL);
}
/**
* Return the modified URL with values
* @return
*/
public String getURL() {
return replaceParmsWithValues();
}
/*
* See http://munkymorgy.blogspot.com/2010/01/java-string-search-and-replace.html
*/
private String replaceString(String input, String find, String replace, boolean casesensitive){
String input_case_adjusted = input;
if (casesensitive == false) {
//For Case Insensitive searches
//Lowercase everything (but replace in the original string)
input_case_adjusted = input.toLowerCase() ;
find = find.toLowerCase() ;
}
int startPosition = input_case_adjusted.indexOf(find);
String start = ""; //$NON-NLS-1$
String end = ""; //$NON-NLS-1$
if (startPosition >= 0) {
if (startPosition > 0) {
start = input.substring(0, startPosition);
}
end = input.substring(startPosition + find.length());
return start + replace + end;
} else {
return input;
}
}
/*
* If we have values for parms, send them back
* @return
*/
private String replaceParmsWithValues () {
if (parms.length > 0 && stashedURL != null && stashedURL.trim().length() > 0) {
String modified = stashedURL;
for (URLTemplateParameter parm : parms) {
if (parm.getValue() != null) {
modified = replaceString(modified, parm.getOriginalContent(), parm.getReplacementContent(), true);
}
}
modified = modified.replace("//", "/"); //$NON-NLS-1$ //$NON-NLS-2$
// fix JBIDE-11728
if (modified.startsWith("http:/") && !modified.startsWith("http://")) { //$NON-NLS-1$ //$NON-NLS-2$
modified = modified.replace("http:/", "http://"); //$NON-NLS-1$ //$NON-NLS-2$
} else if (modified.startsWith("https:/") && !modified.startsWith("https://")) { //$NON-NLS-1$ //$NON-NLS-2$
modified = modified.replace("https:/", "https://"); //$NON-NLS-1$ //$NON-NLS-2$
}
return modified;
}
return stashedURL;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createDialogArea(Composite parent) {
setTitle(JBossWSUIMessages.WSTesterURLInputsDialog_DialogTitle);
setMessage(JBossWSUIMessages.WSTesterURLInputsDialog_DialogMessage);
Composite area = (Composite) super.createDialogArea(parent);
Font font = parent.getFont();
Composite content = new Composite(area, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
content.setLayout(layout);
layout.marginLeft=5;
layout.marginRight=5;
GridData data = new GridData(GridData.FILL_BOTH);
content.setLayoutData(data);
content.setFont(font);
Label label = new Label(content, SWT.NONE);
label.setText(JBossWSUIMessages.WSTesterURLInputsDialog_URLParms_Label);
GridData gridData = new GridData();
gridData.horizontalSpan = 2;
label.setLayoutData(gridData);
treeRequestBody = new TreeViewer(content, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL | SWT.FULL_SELECTION );
this.treeRequestBody.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
GridData gd11 = new GridData(SWT.FILL, SWT.FILL, true, true);
gd11.heightHint = 100;
treeRequestBody.getTree().setLayoutData(gd11);
treeRequestBody.getTree().setHeaderVisible(true);
TreeColumn nameColumn = new TreeColumn(treeRequestBody.getTree(), SWT.LEFT);
nameColumn.setText(JBossWSUIMessages.JAXRSWSTestView2_Name_column);
nameColumn.setWidth(200);
TreeColumn valueColumn = new TreeColumn(treeRequestBody.getTree(), SWT.LEFT);
valueColumn.setText(JBossWSUIMessages.JAXRSWSTestView2_Value_column);
valueColumn.setWidth(200);
TreeColumn typeColumn = new TreeColumn(treeRequestBody.getTree(), SWT.LEFT);
typeColumn.setText(JBossWSUIMessages.WSTesterURLInputsDialog_Type_Column);
typeColumn.setWidth(200);
treeRequestBody.setColumnProperties(TREE_COLUMNS);
treeRequestBody.setLabelProvider(new ITableLabelProvider() {
@Override
public void addListener(ILabelProviderListener listener) {
}
@Override
public void dispose() {
}
@Override
public boolean isLabelProperty(Object element, String property) {
if (element instanceof URLTemplateParameter && property.equalsIgnoreCase(NAME_COLUMN)) {
return true;
} else if (element instanceof URLTemplateParameter && property.equalsIgnoreCase(VALUE_COLUMN)) {
return true;
} else if (element instanceof URLTemplateParameter && property.equalsIgnoreCase(TYPE_COLUMN)) {
return true;
}
return false;
}
@Override
public void removeListener(ILabelProviderListener listener) {
}
@Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
@Override
public String getColumnText(Object element, int columnIndex) {
if (element instanceof URLTemplateParameter) {
URLTemplateParameter parameter = (URLTemplateParameter) element;
if (columnIndex == 0) {
final StringBuilder nameBuilder = new StringBuilder();
nameBuilder.append(parameter.getName());
// suffix the parameter name with an asterix to indicate
// it is mandatory.
if (parameter.isMandatory()) {
nameBuilder.append("* "); //$NON-NLS-1$
}
return nameBuilder.toString();
} else if (columnIndex == 1) {
return parameter.getValue();
} else if (columnIndex == 2) {
return parameter.getDatatype();
}
}
return null;
}
});
treeRequestBody.setContentProvider(new ITreeContentProvider(){
URLTemplateParameter[] parms;
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput,
Object newInput) {
if (newInput instanceof URLTemplateParameter[]) {
parms = (URLTemplateParameter[]) newInput;
}
}
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof URLTemplateParameter[]) {
return this.parms;
}
return null;
}
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof URLTemplateParameter[]) {
return new Object[] {this.parms};
}
return null;
}
@Override
public Object getParent(Object element) {
if (element instanceof URLTemplateParameter) {
return parms;
}
return null;
}
@Override
public boolean hasChildren(Object element) {
if (element instanceof URLTemplateParameter[]) {
return ((URLTemplateParameter[])element).length > 0;
}
return false;
}
});
treeRequestBody.setCellModifier(new ICellModifier() {
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, java.lang.String)
*/
public boolean canModify(Object element, String property) {
if (element instanceof URLTemplateParameter && property.equalsIgnoreCase(VALUE_COLUMN)) {
return true;
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, java.lang.String)
*/
public Object getValue(Object element, String property) {
if (element instanceof URLTemplateParameter && property.equalsIgnoreCase(VALUE_COLUMN)) {
return ((URLTemplateParameter) element).getValue();
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object, java.lang.String, java.lang.Object)
*/
public void modify(Object element, String property, Object value) {
if (element instanceof TreeItem && property.equalsIgnoreCase(VALUE_COLUMN)) {
TreeItem ti = (TreeItem) element;
URLTemplateParameter parm = (URLTemplateParameter) ti.getData();
parm.setValue((String) value);
treeRequestBody.refresh(true);
validate();
}
}
});
treeRequestBody.setCellEditors(new CellEditor[] { null, new TextCellEditor(treeRequestBody.getTree()), null });
treeRequestBody.setInput(parms);
// mention at the bottom of the grid to indicate that some values are mandatory
Label mandatoryValuesLabel = new Label(content, SWT.NONE);
mandatoryValuesLabel.setText(JBossWSUIMessages.WSTesterURLInputsDialog_URLParms_Mandatory);
gridData = new GridData();
gridData.horizontalSpan = 2;
mandatoryValuesLabel.setLayoutData(gridData);
return area;
}
/*
* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
*/
protected void createButtonsForButtonBar(Composite parent) {
this.mOKButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
true);
createButton(parent, IDialogConstants.CANCEL_ID,
IDialogConstants.CANCEL_LABEL, false);
this.mOKButton.setEnabled(true);
validate();
setErrorMessage(null);
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
*/
@Override
protected void configureShell(Shell newShell) {
newShell.setText(JBossWSUIMessages.WSTesterURLInputsDialog_Window_Title);
super.configureShell(newShell);
}
/**
*
* Validate all parameters and return an error message as soon as one param
* is invalid
*
* @return an error message for the first error detected, null otherwise.
*/
private String validateParmValues() {
for (URLTemplateParameter parameter : parms) {
final String errorMessage = parameter.validate();
if (errorMessage != null) {
return errorMessage;
}
}
return null;
}
/**
* Validate the parameter values and pop up a message for the first invalid value.
* Updated for JBIDE-15593 to just show warning, no error, and allow user to submit
* request with bad parms if desired.
*/
private void validate() {
// validates two different types of parameters in the url
// parms with regex: {id:[0-9][0-9]*}
// parms without regex: {id} (always valid, no way to test)
final String errorMessage = validateParmValues();
boolean hasError = errorMessage != null;
if (hasError) {
setMessage(errorMessage, IMessageProvider.WARNING);
}
else
setMessage(JBossWSUIMessages.WSTesterURLInputsDialog_DialogMessage);
}
}