blob: 45e1332a5fd681c3d993bc6c5cc3a9dab3a12cc0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 Shane Clarke.
* 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:
* Shane Clarke - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.ws.internal.jaxws.ui.views;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IMemberValuePair;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.ui.IJavaElementSearchConstants;
import org.eclipse.jdt.ui.ISharedImages;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.DialogCellEditor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
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.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.jst.ws.internal.jaxws.ui.JAXWSUIMessages;
import org.eclipse.jst.ws.internal.jaxws.ui.JAXWSUIPlugin;
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.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.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.SelectionDialog;
import org.eclipse.ui.dialogs.SelectionStatusDialog;
public class AnnotationArrayCellEditor extends DialogCellEditor {
private Method method;
private Object[] values;
private List<Object> originalValues;
private List<Object> updatedValues;
private AnnotationArrayDialog annotationArrayDialog;
boolean cancelled;
public AnnotationArrayCellEditor(Composite parent, Object[] values) {
super(parent, SWT.NONE);
this.values = values.clone();
}
@Override
protected Object openDialogBox(Control cellEditorWindow) {
annotationArrayDialog = new AnnotationArrayDialog(cellEditorWindow.getShell(), values);
int returnValue = annotationArrayDialog.open();
if (returnValue == Window.OK) {
cancelled = false;
return annotationArrayDialog.getResult();
} if (returnValue == Window.CANCEL) {
cancelled = true;
}
return values;
}
public void setMethod(Method method) {
this.method = method;
if (updatedValues != null) {
updatedValues.clear();
}
}
@Override
protected void updateContents(Object value) {
if (value instanceof Object[]) {
Object[] values = (Object[])value;
if (values.length > 0) {
getDefaultLabel().setText("[]{...}"); //$NON-NLS-1$
} else {
getDefaultLabel().setText("[]{}"); //$NON-NLS-1$
}
}
}
@Override
protected Object doGetValue() {
if (cancelled || updatedValues == null) {
return originalValues != null ? originalValues.toArray() : new Object[0];
}
return updatedValues.toArray();
}
@Override
protected void doSetValue(Object value) {
super.doSetValue(value);
this.values = (Object[])value;
}
private class AnnotationArrayDialog extends SelectionStatusDialog {
private Button addButton;
private Button removeButton;
private Button upButton;
private Button downButton;
private Table arrayValuesTable;
private TableViewer arrayValuesTableViewer;
private Map<String, Control> controls = new HashMap<String, Control>();
public AnnotationArrayDialog(Shell parent, Object[] values) {
super(parent);
setValues(values);
setTitle(JAXWSUIMessages.ANNOTATION_ARRAY_CELL_EDITOR_EDIT_ARRAY_VALUES_TITLE);
}
private void setValues(Object[] values) {
try {
originalValues = new ArrayList<Object>();
updatedValues = new ArrayList<Object>();
for (Object value : values) {
if (value instanceof IAnnotation) {
IAnnotation annotation = (IAnnotation) value;
IMemberValuePair[] memberValuePairs = annotation.getMemberValuePairs();
if (memberValuePairs.length > 0) {
List<Map<String, Object>> aList = new ArrayList<Map<String,Object>>();
for (IMemberValuePair memberValuePair : memberValuePairs) {
String memberName = memberValuePair.getMemberName();
Object memberValue = memberValuePair.getValue();
Map<String, Object> mvps = new HashMap<String, Object>();
if (memberValuePair.getValueKind() == IMemberValuePair.K_STRING) {
mvps.put(memberName, memberValue);
}
if (memberValuePair.getValueKind() == IMemberValuePair.K_CLASS) {
mvps.put(memberName, memberValuePair.getValue() + ".class"); //$NON-NLS-1$
}
aList.add(mvps);
}
originalValues.add(aList);
updatedValues.add(aList);
}
}
if (value.equals(Class.class)) {
originalValues.add(value);
updatedValues.add(value);
}
if (value instanceof String) {
String string = (String)value;
originalValues.add(string);
updatedValues.add(string);
}
}
} catch (JavaModelException jme) {
JAXWSUIPlugin.log(jme.getStatus());
}
}
@Override
protected Control createDialogArea(Composite parent) {
Composite mainComposite = (Composite) super.createDialogArea(parent);
GridLayout gridLayout = new GridLayout(3, false);
mainComposite.setLayout(gridLayout);
GridData gridData = new GridData(SWT.FILL, SWT.BEGINNING, false, false);
gridData.widthHint = 800;
mainComposite.setLayoutData(gridData);
Composite typeComposite = new Composite(mainComposite, SWT.NONE);
gridLayout = new GridLayout(3, false);
typeComposite.setLayout(gridLayout);
gridData = new GridData(SWT.FILL, SWT.BEGINNING, true, true);
typeComposite.setLayoutData(gridData);
final Class<?> componentType = method.getReturnType().getComponentType();
if (componentType.isAnnotation()) {
Label compontTypeLabel = new Label(typeComposite, SWT.NONE);
compontTypeLabel.setText("@" + componentType.getName()); //$NON-NLS-1$
gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
gridData.horizontalSpan = 3;
compontTypeLabel.setLayoutData(gridData);
Method[] methods = componentType.getDeclaredMethods();
for (Method method : methods) {
Label label = new Label(typeComposite, SWT.NONE);
label.setText(method.getName() + ":"); //$NON-NLS-1$
createEntryFields(method, typeComposite);
}
} else {
Label label = new Label(typeComposite, SWT.NONE);
label.setText(method.getReturnType().getSimpleName());
createEntryFields(method, typeComposite);
}
Composite buttonComposite = new Composite(mainComposite, SWT.NONE);
gridLayout = new GridLayout(1, false);
buttonComposite.setLayout(gridLayout);
addButton = new Button(buttonComposite, SWT.PUSH);
addButton.setText(JAXWSUIMessages.ANNOTATION_ARRAY_CELL_EDITOR_ADD_LABEL);
addButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
Set<Entry<String, Control>> entrySet = controls.entrySet();
Iterator<Map.Entry<String, Control>> iterator = entrySet.iterator();
List<Map<String, Object>> aList = new ArrayList<Map<String,Object>>();
while (iterator.hasNext()) {
Map.Entry<String, Control> entry = iterator.next();
if (entry.getValue() instanceof Text) {
Text textField = (Text) entry.getValue();
Method method = (Method) textField.getData();
if (textField.getText().trim().length() > 0) {
if (componentType.isAnnotation()) {
Map<String, Object> memberValuePairs = new HashMap<String, Object>();
memberValuePairs.put(method.getName(), textField.getText());
aList.add(memberValuePairs);
} else {
updatedValues.add(textField.getText());
}
}
}
if (entry.getValue() instanceof Button) {
Button button = (Button) entry.getValue();
Method method = (Method) button.getData();
if (componentType.isAnnotation()) {
Map<String, Object> memberValuePairs = new HashMap<String, Object>();
memberValuePairs.put(method.getName(), button.getSelection());
aList.add(memberValuePairs);
} else {
updatedValues.add(button.getSelection());
}
}
}
if (aList.size() > 0) {
updatedValues.add(aList);
}
arrayValuesTableViewer.refresh();
}
});
gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
addButton.setLayoutData(gridData);
removeButton = new Button(buttonComposite, SWT.PUSH);
removeButton.setText(JAXWSUIMessages.ANNOTATION_ARRAY_CELL_EDITOR_REMOVE_LABEL);
removeButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
ISelection selection = arrayValuesTableViewer.getSelection();
if (selection != null && !selection.isEmpty()) {
int index = arrayValuesTable.getSelectionIndex();
updatedValues.remove(index);
arrayValuesTableViewer.refresh();
}
}
});
gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
removeButton.setLayoutData(gridData);
upButton = new Button(buttonComposite, SWT.PUSH);
upButton.setText(JAXWSUIMessages.ANNOTATION_ARRAY_CELL_EDITOR_UP_LABEL);
upButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
moveSelectedElememtUp(getSelectedElement(), getTableViewer());
}
});
gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
upButton.setLayoutData(gridData);
downButton = new Button(buttonComposite, SWT.PUSH);
downButton.setText(JAXWSUIMessages.ANNOTATION_ARRAY_CELL_EDITOR_DOWN_LABEL);
downButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
moveSelectedElememtDown(getSelectedElement(), getTableViewer());
}
});
gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
downButton.setLayoutData(gridData);
Composite valuesComposite = new Composite(mainComposite, SWT.NONE);
gridLayout = new GridLayout(1, false);
valuesComposite.setLayout(gridLayout);
gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
gridData.widthHint = 200;
valuesComposite.setLayoutData(gridData);
Label valuesLabel = new Label(valuesComposite, SWT.NONE);
valuesLabel.setText(method.getName() + ":"); //$NON-NLS-1$
arrayValuesTableViewer = new TableViewer(valuesComposite, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL
| SWT.H_SCROLL);
arrayValuesTableViewer.setLabelProvider(new LabelProvider() {
@Override
public String getText(Object element) {
if (element instanceof List<?>) {
String annotationName = method.getReturnType().getComponentType().getSimpleName();
annotationName += "("; //$NON-NLS-1$
List<Map<String, Object>> valuesList = (List<Map<String, Object>>)element;
Iterator<Map<String, Object>> valuesIterator = valuesList.iterator();
while (valuesIterator.hasNext()) {
Map<String, Object> valuesMap = valuesIterator.next();
Set<Entry<String, Object>> entrySet = valuesMap.entrySet();
Iterator<Map.Entry<String, Object>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
Object value = entry.getValue();
boolean isString = value instanceof String && !value.toString().
endsWith(".class"); //$NON-NLS-1$
if (isString) {
annotationName += entry.getKey() + "=\"" + value + "\""; //$NON-NLS-1$ //$NON-NLS-2$
} else {
annotationName += entry.getKey() + "=" + value; //$NON-NLS-1$
}
}
if (valuesIterator.hasNext()) {
annotationName += ", "; //$NON-NLS-1$
}
}
return annotationName += ")"; //$NON-NLS-1$
}
return element.toString();
}
@Override
public Image getImage(Object element) {
Class<?> returnType = method.getReturnType();
if (returnType.getComponentType().isAnnotation()) {
return JavaUI.getSharedImages().getImage(ISharedImages.IMG_OBJS_ANNOTATION);
} if (returnType.equals(Class.class)) {
return JavaUI.getSharedImages().getImage(ISharedImages.IMG_OBJS_CLASS);
} else {
return PlatformUI.getWorkbench().getSharedImages().getImage(
org.eclipse.ui.ISharedImages.IMG_OBJ_FILE);
}
}
});
arrayValuesTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
int index = arrayValuesTable.getSelectionIndex();
int itemCount = arrayValuesTable.getItemCount();
if (index == 0 && itemCount <= 1) {
upButton.setEnabled(false);
downButton.setEnabled(false);
}
if (index == 0 && itemCount > 1) {
upButton.setEnabled(false);
downButton.setEnabled(true);
}
if (index > 0 && index < itemCount - 1) {
upButton.setEnabled(true);
downButton.setEnabled(true);
}
if (index > 0 && index == itemCount - 1) {
upButton.setEnabled(true);
downButton.setEnabled(false);
}
if (index != -1) {
removeButton.setEnabled(true);
} else {
removeButton.setEnabled(false);
}
}
});
arrayValuesTableViewer.setContentProvider(new ArrayValuesContentProvider());
arrayValuesTable = arrayValuesTableViewer.getTable();
gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
arrayValuesTable.setLayoutData(gridData);
arrayValuesTableViewer.setInput(values);
upButton.setEnabled(false);
downButton.setEnabled(false);
removeButton.setEnabled(false);
return mainComposite;
}
public void createEntryFields(Method method, Composite typeComposite) {
//TODO Handle ENUMS
Class<?> returnType = method.getReturnType();
Object defaultValue = method.getDefaultValue();
GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
//String or String[]
if (returnType.equals(String.class) || returnType.isArray() && returnType.getComponentType().equals(String.class)) {
Text text = new Text(typeComposite, SWT.BORDER);
text.setData(method);
gridData.horizontalSpan = 2;
text.setLayoutData(gridData);
if (defaultValue != null) {
if (defaultValue instanceof String[] && ((String[]) defaultValue).length == 1) {
String[] values = (String[]) defaultValue;
text.setText(values[0]);
} else {
text.setText(defaultValue.toString());
}
}
controls.put(method.getName(), text);
}
//Class or Class[]
if (returnType.equals(Class.class) || returnType.isArray() && returnType.getComponentType().equals(Class.class)) {
final Text text = new Text(typeComposite, SWT.BORDER);
text.setData(method);
gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
text.setLayoutData(gridData);
if (defaultValue != null) {
Class<?> classValue = (Class<?>)defaultValue;
text.setText(classValue.getCanonicalName() + ".class"); //$NON-NLS-1$
}
Button browseClassButton = new Button(typeComposite, SWT.PUSH);
browseClassButton.setText(JAXWSUIMessages.ANNOTATION_ARRAY_CELL_EDITOR_BROWSE_LABEL);
browseClassButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
SelectionDialog dialog = getClassSelectionDialog();
dialog.setTitle(JAXWSUIMessages.ANNOTATION_ARRAY_CELL_EDITOR_SELECT_CLASS_TITLE);
if (dialog.open() == IDialogConstants.OK_ID) {
Object[] types = dialog.getResult();
if (types != null && types.length > 0) {
IType type = (IType)types[0];
if (type.isBinary()) {
text.setText(type.getClassFile().getElementName());
}
}
}
}
});
controls.put(method.getName(), text);
}
//Boolean
if (returnType.equals(Boolean.TYPE)) {
Button checkbox = new Button(typeComposite, SWT.CHECK);
checkbox.setData(method);
gridData.horizontalSpan = 2;
checkbox.setLayoutData(gridData);
if (defaultValue != null) {
checkbox.setSelection((Boolean)defaultValue);
}
controls.put(method.getName(), checkbox);
}
}
public Object getSelectedElement() {
IStructuredSelection selection= (IStructuredSelection) arrayValuesTableViewer.getSelection();
return selection.getFirstElement();
}
private TableViewer getTableViewer() {
return arrayValuesTableViewer;
}
public void moveSelectedElememtUp(Object selected, TableViewer tableViewer) {
int selectionIndex = tableViewer.getTable().getSelectionIndex();
if (selectionIndex > 0) {
updatedValues.remove(selected);
updatedValues.add(selectionIndex - 1, selected);
tableViewer.refresh();
tableViewer.reveal(selected);
tableViewer.setSelection(new StructuredSelection(selected));
}
}
public void moveSelectedElememtDown(Object selected, TableViewer tableViewer) {
int selectionIndex = tableViewer.getTable().getSelectionIndex();
int itemCount = tableViewer.getTable().getItemCount();
if (selectionIndex < itemCount - 1) {
updatedValues.remove(selected);
updatedValues.add(selectionIndex + 1, selected);
tableViewer.refresh();
tableViewer.reveal(selected);
tableViewer.setSelection(new StructuredSelection(selected));
}
}
private class ArrayValuesContentProvider implements IStructuredContentProvider {
public ArrayValuesContentProvider() {
}
public Object[] getElements(Object inputElement) {
return updatedValues.toArray();
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
public SelectionDialog getClassSelectionDialog() {
try {
return JavaUI.createTypeDialog(getShell(), PlatformUI.getWorkbench().getProgressService(),
SearchEngine.createWorkspaceScope(), IJavaElementSearchConstants.CONSIDER_CLASSES,
false, "* "); //$NON-NLS-1$
} catch (JavaModelException jme) {
JAXWSUIPlugin.log(jme.getStatus());
}
return null;
}
@Override
public Object[] getResult() {
return updatedValues.toArray();
}
@Override
protected void computeResult() {
}
}
}