blob: 693e8ccc18d533b6fb1bed5edfab85b1a5621b91 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 IONA Technologies PLC
* 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:
* IONA Technologies PLC - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.ws.internal.cxf.creation.ui.widgets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
import org.eclipse.jdt.internal.ui.text.SimpleJavaSourceViewerConfiguration;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
import org.eclipse.jdt.ui.text.IColorManager;
import org.eclipse.jdt.ui.text.IJavaPartitions;
import org.eclipse.jdt.ui.text.JavaTextTools;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.FindReplaceDocumentAdapter;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jst.ws.internal.cxf.core.model.Java2WSDataModel;
import org.eclipse.jst.ws.annotations.core.utils.AnnotationUtils;
import org.eclipse.jst.ws.internal.cxf.core.utils.CXFModelUtils;
import org.eclipse.jst.ws.internal.cxf.creation.ui.CXFCreationUIMessages;
import org.eclipse.jst.ws.internal.cxf.creation.ui.CXFCreationUIPlugin;
import org.eclipse.jst.ws.internal.cxf.creation.ui.viewers.AnnotationColumnLabelProvider;
import org.eclipse.jst.ws.jaxws.core.utils.JDTUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
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.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;
@SuppressWarnings("restriction")
public class JAXWSAnnotateJavaWidget extends SimpleWidgetDataContributor {
IStatus status = Status.OK_STATUS;
private IType type;
private Java2WSDataModel model;
private TreeViewer javaTreeViewer;
private SourceViewer annotationPreviewViewer;
private TreeViewerColumn webMethodViewerColumn;
private TreeViewerColumn webParamViewerColumn;
private TreeViewerColumn requestWrapperViewerColumn;
private TreeViewerColumn responceWrapperViewerColumn;
public JAXWSAnnotateJavaWidget() {
}
public void setJava2WSDataModel(Java2WSDataModel model) {
this.model = model;
}
@Override
public WidgetDataEvents addControls(Composite parent, Listener statusListener) {
SashForm sashForm = new SashForm(parent, SWT.VERTICAL | SWT.SMOOTH);
GridLayout gridLayout = new GridLayout(1, true);
sashForm.setLayout(gridLayout);
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
sashForm.setLayoutData(gridData);
Composite javaTreecomposite = new Composite(sashForm, SWT.NONE);
gridLayout = new GridLayout(1, true);
javaTreecomposite.setLayout(gridLayout);
gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
javaTreecomposite.setLayoutData(gridData);
Label outlineLabel = new Label(javaTreecomposite, SWT.NONE);
outlineLabel.setText(CXFCreationUIMessages.JAXWS_ANNOTATE_JJAVA_WIDGET_SELECT_METHOD_TO_ANNOTATE);
Tree javaTree = new Tree(javaTreecomposite, SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL
| SWT.H_SCROLL);
javaTreeViewer = new TreeViewer(javaTree);
javaTree.setHeaderVisible(true);
gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
gridData.heightHint = 10;
gridData.widthHint = 200;
javaTree.setLayoutData(gridData);
TreeViewerColumn classViewerColumn = new TreeViewerColumn(javaTreeViewer, SWT.NONE);
TreeColumn classColumn = classViewerColumn.getColumn();
classColumn.setWidth(200);
classColumn.setMoveable(false);
final JavaElementLabelProvider javaElementLabelProvider = new JavaElementLabelProvider();
classViewerColumn.setLabelProvider(new ColumnLabelProvider() {
@Override
public Image getImage(Object element) {
return javaElementLabelProvider.getImage(element);
}
@Override
public String getText(Object element) {
return javaElementLabelProvider.getText(element);
}
});
javaTreeViewer.setContentProvider(new StandardJavaElementContentProvider(true) {
@Override
public Object[] getChildren(Object element) {
if (element instanceof ICompilationUnit) {
try {
ICompilationUnit compilationUnit = (ICompilationUnit) element;
IType[] types = compilationUnit.getTypes();
for (IType type : types) {
if (type instanceof IType) {
return new Object[] {type};
}
}
} catch (JavaModelException jme) {
CXFCreationUIPlugin.log(jme.getStatus());
}
}
if (element instanceof IType) {
try {
IType sourceType = (IType) element;
List<IMethod> publicMethods = new ArrayList<IMethod>();
IMethod[] methods = sourceType.getMethods();
if (sourceType.isInterface()) {
return methods;
} else if (sourceType.isClass()) {
for (IMethod method : methods) {
if (JDTUtils.isPublicMethod(method)) {
publicMethods.add(method);
}
}
}
return publicMethods.toArray(new Object[publicMethods.size()]);
} catch (JavaModelException jme) {
CXFCreationUIPlugin.log(jme.getStatus());
}
}
return NO_CHILDREN;
}
@Override
public boolean hasChildren(Object element) {
return getChildren(element).length > 0;
}
});
javaTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
if (event.getSelection() instanceof ITreeSelection) {
ITreeSelection treeSelection = (TreeSelection) event.getSelection();
Object firstElement = treeSelection.getFirstElement();
IDocument document = annotationPreviewViewer.getDocument();
FindReplaceDocumentAdapter findReplaceDocumentAdapter =
new FindReplaceDocumentAdapter(document);
try {
if (firstElement instanceof IType) {
IType sourceType = (IType) firstElement;
String elementName = sourceType.getElementName();
StringBuilder regex = new StringBuilder("\\bpublic\\W+(?:\\w+\\W+){1,3}?");
regex.append(elementName);
regex.append("\\b");
IRegion region = findReplaceDocumentAdapter.find(0, regex.toString(), true, true,
false, true);
annotationPreviewViewer.setSelectedRange(region.getOffset(), region.getLength());
annotationPreviewViewer.revealRange(region.getOffset(), region.getLength());
} else if (firstElement instanceof IMethod) {
IMethod sourceMethod = (IMethod) firstElement;
IType sourceType = (IType) sourceMethod.getParent();
String elementName = sourceMethod.getElementName();
StringBuilder regex = new StringBuilder();
if (sourceType.isClass()) {
regex.append("\\bpublic");
}
regex.append("\\W+(?:\\w+\\W+){1,3}?");
regex.append(elementName);
regex.append("\\s*?\\(\\s*?.*?");
String[] parameterTypes = sourceMethod.getParameterTypes();
String[] paramterNames = sourceMethod.getParameterNames();
for (int i = 0; i < parameterTypes.length; i++) {
regex.append("\\s*?");
String typeName = Signature.toString(parameterTypes[i]);
regex.append(typeName);
regex.append("\\s*?");
regex.append(paramterNames[i]);
if (i < parameterTypes.length - 1) {
regex.append("\\s*?,\\s*?.*?");
}
}
regex.append("\\s*?\\)");
IRegion region = findReplaceDocumentAdapter.find(0, regex.toString(), true, true,
false, true);
if (region != null) {
IRegion elementNameRegion = findReplaceDocumentAdapter.find(
region.getOffset(), elementName, true, true, true, false);
if (elementNameRegion != null) {
annotationPreviewViewer.setSelectedRange(elementNameRegion.getOffset(),
elementNameRegion.getLength());
annotationPreviewViewer.revealRange(elementNameRegion.getOffset(),
elementNameRegion.getLength());
}
}
}
} catch (BadLocationException ble) {
CXFCreationUIPlugin.log(ble);
} catch (JavaModelException jme) {
CXFCreationUIPlugin.log(jme);
}
}
}
});
createWebMethodViewerColumn(javaTreeViewer);
createWebParamViewerColumn(javaTreeViewer);
createRequestWrapperViewerColumn(javaTreeViewer);
createResponseWrapperViewerColumn(javaTreeViewer);
javaTreeViewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
javaTreeViewer.expandAll();
Composite previewComposite = new Composite(sashForm, SWT.NONE);
gridLayout = new GridLayout(1, true);
previewComposite.setLayout(gridLayout);
gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
javaTreecomposite.setLayoutData(gridData);
Label previewLabel = new Label(previewComposite, SWT.NONE);
previewLabel.setText(CXFCreationUIMessages.JAXWS_ANNOTATE_JJAVA_WIDGET_PREVIEW);
annotationPreviewViewer = createAnnotationPreviewer(previewComposite, SWT.READ_ONLY | SWT.V_SCROLL
| SWT.H_SCROLL | SWT.BORDER);
gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
gridData.heightHint = 10;
gridData.widthHint = 200;
annotationPreviewViewer.getControl().setLayoutData(gridData);
sashForm.setWeights(new int[]{50, 50});
return this;
}
@Override
public void internalize() {
type = null;
updateLabelProviders();
javaTreeViewer.setInput(getType().getTypeRoot());
javaTreeViewer.refresh();
handleAnnotation(getType());
}
private IType getType() {
if (type != null) {
return type;
}
if (model.getFullyQualifiedJavaInterfaceName() != null) {
type = JDTUtils.getType(JDTUtils.getJavaProject(model.getProjectName()), model
.getFullyQualifiedJavaInterfaceName());
} else if (model.getFullyQualifiedJavaClassName() != null) {
type =JDTUtils.getType(JDTUtils.getJavaProject(model.getProjectName()), model
.getFullyQualifiedJavaClassName());
}
if (type == null) {
type = JDTUtils.getType(JDTUtils.getJavaProject(model.getProjectName()), model
.getJavaStartingPoint());
}
model.setMethodMap(CXFModelUtils.getMethodMap(type, model));
return type;
}
private TreeViewerColumn createWebMethodViewerColumn(TreeViewer treeViewer) {
webMethodViewerColumn = new TreeViewerColumn(treeViewer, SWT.CENTER);
TreeColumn webMethodColumn = webMethodViewerColumn.getColumn();
webMethodColumn.setText("@" + CXFModelUtils.WEB_METHOD); //$NON-NLS-1$
webMethodColumn.setWidth(100);
webMethodColumn.setAlignment(SWT.CENTER);
webMethodColumn.setMoveable(false);
webMethodViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
CXFModelUtils.WEB_METHOD, getType()));
webMethodViewerColumn.setEditingSupport(new AnnotationEditingSupport(treeViewer,
CXFModelUtils.WEB_METHOD));
return webMethodViewerColumn;
}
private TreeViewerColumn createWebParamViewerColumn(TreeViewer treeViewer) {
webParamViewerColumn = new TreeViewerColumn(treeViewer, SWT.CENTER);
TreeColumn webParamColumn = webParamViewerColumn.getColumn();
webParamColumn.setText("@" + CXFModelUtils.WEB_PARAM); //$NON-NLS-1$
webParamColumn.setWidth(100);
webParamColumn.setAlignment(SWT.CENTER);
webParamColumn.setMoveable(false);
webParamViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
CXFModelUtils.WEB_PARAM, getType()));
webParamViewerColumn.setEditingSupport(new AnnotationEditingSupport(treeViewer,
CXFModelUtils.WEB_PARAM));
return webParamViewerColumn;
}
private TreeViewerColumn createRequestWrapperViewerColumn(TreeViewer treeViewer) {
requestWrapperViewerColumn = new TreeViewerColumn(treeViewer, SWT.CENTER);
TreeColumn createRequestWrapperColumn = requestWrapperViewerColumn.getColumn();
createRequestWrapperColumn.setText("@" + CXFModelUtils.REQUEST_WRAPPER); //$NON-NLS-1$
createRequestWrapperColumn.setWidth(100);
createRequestWrapperColumn.setMoveable(false);
requestWrapperViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
CXFModelUtils.REQUEST_WRAPPER, getType()));
requestWrapperViewerColumn.setEditingSupport(new AnnotationEditingSupport(treeViewer,
CXFModelUtils.REQUEST_WRAPPER));
return requestWrapperViewerColumn;
}
private TreeViewerColumn createResponseWrapperViewerColumn(TreeViewer treeViewer) {
responceWrapperViewerColumn = new TreeViewerColumn(treeViewer, SWT.CENTER);
TreeColumn responceWrapperColumn = responceWrapperViewerColumn.getColumn();
responceWrapperColumn.setText("@" + CXFModelUtils.RESPONSE_WRAPPER); //$NON-NLS-1$
responceWrapperColumn.setWidth(100);
responceWrapperColumn.setMoveable(false);
responceWrapperViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
CXFModelUtils.RESPONSE_WRAPPER, getType()));
responceWrapperViewerColumn.setEditingSupport(new AnnotationEditingSupport(treeViewer,
CXFModelUtils.RESPONSE_WRAPPER));
return responceWrapperViewerColumn;
}
private void updateLabelProviders() {
webMethodViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
CXFModelUtils.WEB_METHOD, getType()));
webParamViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
CXFModelUtils.WEB_PARAM, getType()));
requestWrapperViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
CXFModelUtils.REQUEST_WRAPPER, getType()));
responceWrapperViewerColumn.setLabelProvider(new AnnotationColumnLabelProvider(model,
CXFModelUtils.RESPONSE_WRAPPER, getType()));
}
private void handleAnnotation(IType type) {
try {
annotationPreviewViewer.setRedraw(false);
ICompilationUnit compilationUnit = type.getCompilationUnit();
IProgressMonitor monitor = new NullProgressMonitor();
TextFileChange textFileChange = new TextFileChange("Annotation Changes",
(IFile)compilationUnit.getResource());
MultiTextEdit multiTextEdit = new MultiTextEdit();
textFileChange.setEdit(multiTextEdit);
textFileChange.setKeepPreviewEdits(true);
// compositeChange.setSaveMode(TextFileChange.FORCE_SAVE);
CXFModelUtils.getWebServiceAnnotationChange(type, model, textFileChange);
IMethod[] typeMethods = JDTUtils.getPublicMethods(type);
for (int i = 0; i < typeMethods.length; i++) {
IMethod method = typeMethods[i];
Map<String, Boolean> methodAnnotationMap = model.getMethodMap().get(method);
if (methodAnnotationMap.get(CXFModelUtils.WEB_METHOD)) {
CXFModelUtils.getWebMethodAnnotationChange(type, method, textFileChange);
}
if (methodAnnotationMap.get(CXFModelUtils.REQUEST_WRAPPER)) {
CXFModelUtils.getRequestWrapperAnnotationChange(type, method, textFileChange);
}
if (methodAnnotationMap.get(CXFModelUtils.RESPONSE_WRAPPER)) {
CXFModelUtils.getResponseWrapperAnnotationChange(type, method, textFileChange);
}
if (methodAnnotationMap.get(CXFModelUtils.WEB_PARAM)) {
List<SingleVariableDeclaration> parameters = AnnotationUtils.getMethodParameters(
type, method);
for (SingleVariableDeclaration parameter : parameters) {
CXFModelUtils.getWebParamAnnotationChange(type, method, parameter, textFileChange);
}
}
}
CXFModelUtils.getImportsChange(compilationUnit, model, textFileChange, false);
annotationPreviewViewer.getDocument().set(textFileChange.getPreviewContent(monitor));
annotationPreviewViewer.setRedraw(true);
} catch (CoreException ce) {
CXFCreationUIPlugin.log(ce.getStatus());
} catch (MalformedTreeException mte) {
CXFCreationUIPlugin.log(mte);
}
}
private SourceViewer createAnnotationPreviewer(Composite parent, int styles) {
JavaPlugin javaPlugin = JavaPlugin.getDefault();
IPreferenceStore store = javaPlugin.getCombinedPreferenceStore();
JavaTextTools javaTextTools = javaPlugin.getJavaTextTools();
annotationPreviewViewer = new JavaSourceViewer(parent, null, null, true, styles, store);
IColorManager colorManager = javaTextTools.getColorManager();
SimpleJavaSourceViewerConfiguration configuration = new SimpleJavaSourceViewerConfiguration(
colorManager, store, null, IJavaPartitions.JAVA_PARTITIONING, true);
annotationPreviewViewer.configure(configuration);
Font font = JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT);
annotationPreviewViewer.getTextWidget().setFont(font);
annotationPreviewViewer.setEditable(false);
String source = JDTUtils.getSourceFromType(getType());
IDocument document = new Document(source);
JavaPlugin.getDefault().getJavaTextTools().setupJavaDocumentPartitioner(document,
IJavaPartitions.JAVA_PARTITIONING);
annotationPreviewViewer.setDocument(document);
return annotationPreviewViewer;
}
@Override
public IStatus getStatus() {
return status;
}
private class AnnotationEditingSupport extends EditingSupport {
private CheckboxCellEditor checkboxCellEditor;
private String annotationKey;
public AnnotationEditingSupport(TreeViewer viewer, String annotationKey) {
super(viewer);
this.annotationKey = annotationKey;
checkboxCellEditor = new CheckboxCellEditor(viewer.getTree());
}
@Override
protected boolean canEdit(Object element) {
if (element instanceof IMethod) {
IMethod method = (IMethod) element;
return !AnnotationUtils.isAnnotationPresent(type.findMethods(method)[0],
annotationKey);
}
return false;
}
@Override
protected CellEditor getCellEditor(Object element) {
return checkboxCellEditor;
}
@Override
protected Object getValue(Object element) {
Boolean annotate = model.getMethodMap().get(element).get(annotationKey);
return annotate;
}
@Override
protected void setValue(Object element, Object value) {
if (element instanceof IMethod) {
IMethod method = (IMethod) element;
Boolean annotate = (Boolean) value;
Map<String, Boolean> annotationMap = model.getMethodMap().get(element);
annotationMap.put(annotationKey, annotate);
handleAnnotation(method.getDeclaringType());
getViewer().refresh(true);
}
}
}
}