package net.sourceforge.c4jplugin.internal.wizards;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Vector;
import net.sourceforge.c4jplugin.C4JActivator;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Item;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;
public class NewContractWizardPageTwo extends WizardPage {
private final static String PAGE_NAME= "NewContractWizardPage2"; //$NON-NLS-1$
private final static String STORE_USE_TASKMARKER= PAGE_NAME + ".USE_TASKMARKER"; //$NON-NLS-1$
private final static String STORE_CREATE_FINAL_METHOD_STUBS= PAGE_NAME + ".CREATE_FINAL_METHOD_STUBS"; //$NON-NLS-1$
private final String PROP_METHOD_COL = "methods"; //$NON-NLS-1$
private final String PROP_PRE_COL = "pre"; //$NON-NLS-1$
private final String PROP_POST_COL = "post"; //$NON-NLS-1$
private IType fClassToContract;
private Button fCreateFinalMethodStubsButton;
private Button fCreateTasksButton;
private ContainerCheckedTreeViewer fMethodsTree;
private Button fSelectAllButton;
private Button fDeselectAllButton;
private Label fSelectedMethodsLabel;
private Object[] fCheckedObjects = new Object[] {};
private boolean fCreateFinalStubs;
private boolean fCreateTasks;
/**
* Creates a new <code>NewContractWizardPageTwo</code>.
*/
public NewContractWizardPageTwo() {
super(PAGE_NAME);
setTitle(WizardMessages.NewContractWizardPageTwo_title);
setDescription(WizardMessages.NewContractWizardPageTwo_description);
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
*/
public void createControl(Composite parent) {
Composite container= new Composite(parent, SWT.NONE);
GridLayout layout= new GridLayout();
layout.numColumns= 2;
container.setLayout(layout);
createMethodsTreeControls(container);
createSpacer(container);
createButtonChoices(container);
setControl(container);
restoreWidgetValues();
Dialog.applyDialogFont(container);
//PlatformUI.getWorkbench().getHelpSystem().setHelp(container, IJUnitHelpContextIds.NEW_TESTCASE_WIZARD_PAGE2);
}
private void createButtonChoices(Composite container) {
GridLayout layout;
GridData gd;
Composite prefixContainer= new Composite(container, SWT.NONE);
gd= new GridData();
gd.horizontalAlignment = GridData.FILL;
gd.horizontalSpan = 1;
prefixContainer.setLayoutData(gd);
layout = new GridLayout();
layout.numColumns = 1;
layout.marginWidth = 0;
layout.marginHeight = 0;
prefixContainer.setLayout(layout);
SelectionListener listener= new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
doCheckBoxSelected(e.widget);
}
};
fCreateFinalMethodStubsButton= createCheckBox(prefixContainer, WizardMessages.NewContractWizardPageTwo_create_final_method_stubs_text, listener);
fCreateTasksButton= createCheckBox(prefixContainer, WizardMessages.NewContractWizardPageTwo_create_tasks_text, listener);
}
private Button createCheckBox(Composite parent, String name, SelectionListener listener) {
Button button= new Button(parent, SWT.CHECK | SWT.LEFT);
button.setText(name);
button.setEnabled(true);
button.setSelection(true);
button.addSelectionListener(listener);
GridData gd= new GridData(GridData.FILL, GridData.CENTER, false, false);
button.setLayoutData(gd);
return button;
}
private void doCheckBoxSelected(Widget widget) {
if (widget == fCreateFinalMethodStubsButton) {
fCreateFinalStubs= fCreateFinalMethodStubsButton.getSelection();
} else if (widget == fCreateTasksButton) {
fCreateTasks= fCreateTasksButton.getSelection();
}
saveWidgetValues();
}
private void createMethodsTreeControls(Composite container) {
Label label= new Label(container, SWT.LEFT | SWT.WRAP);
label.setFont(container.getFont());
label.setText(WizardMessages.NewContractWizardPageTwo_methods_tree_label);
GridData gd = new GridData();
gd.horizontalSpan = 2;
label.setLayoutData(gd);
fMethodsTree= new ContainerCheckedTreeViewer(container, SWT.BORDER);
gd= new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
gd.heightHint= 180;
fMethodsTree.getTree().setLayoutData(gd);
fMethodsTree.getTree().setHeaderVisible(true);
TreeColumn colMember = new TreeColumn(fMethodsTree.getTree(), SWT.NONE);
colMember.setText(WizardMessages.NewContractWizardPageTwo_columnheader_methods);
TreeColumn colPre = new TreeColumn(fMethodsTree.getTree(), SWT.NONE);
colPre.setText(WizardMessages.NewContractWizardPageTwo_columnheader_pre);
TreeColumn colPost = new TreeColumn(fMethodsTree.getTree(), SWT.NONE);
colPost.setText(WizardMessages.NewContractWizardPageTwo_columnheader_post);
colMember.setWidth(250);
colPre.setWidth(150);
colPost.setWidth(150);
ComboBoxCellEditor cellEditorPre = new ComboBoxCellEditor(fMethodsTree.getTree(), NewContractLabelProvider.preCondLabels);
ComboBoxCellEditor cellEditorPost = new ComboBoxCellEditor(fMethodsTree.getTree(), NewContractLabelProvider.postCondLabels);
fMethodsTree.setColumnProperties(new String[] {PROP_METHOD_COL, PROP_PRE_COL, PROP_POST_COL});
fMethodsTree.setCellEditors(new CellEditor[] {null, cellEditorPre, cellEditorPost});
fMethodsTree.setCellModifier(new MethodCellModifier());
fMethodsTree.setLabelProvider(new NewContractLabelProvider());
fMethodsTree.setAutoExpandLevel(2);
fMethodsTree.addCheckStateListener(new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent event) {
doCheckedStateChanged();
}
});
fMethodsTree.addFilter(new ViewerFilter() {
public boolean select(Viewer viewer, Object parentElement, Object element) {
NewContractMethodElement item = (NewContractMethodElement)element;
if (item.getMember() instanceof IMethod) {
IMethod method = (IMethod) item.getMember();
return !method.getElementName().equals("<clinit>"); //$NON-NLS-1$
}
return true;
}
});
Composite buttonContainer= new Composite(container, SWT.NONE);
gd= new GridData(GridData.FILL_VERTICAL);
buttonContainer.setLayoutData(gd);
GridLayout buttonLayout= new GridLayout();
buttonLayout.marginWidth= 0;
buttonLayout.marginHeight= 0;
buttonContainer.setLayout(buttonLayout);
fSelectAllButton= new Button(buttonContainer, SWT.PUSH);
fSelectAllButton.setText(WizardMessages.NewContractWizardPageTwo_selectAll);
gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
fSelectAllButton.setLayoutData(gd);
fSelectAllButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
fMethodsTree.setCheckedElements((Object[]) fMethodsTree.getInput());
doCheckedStateChanged();
}
});
//LayoutUtil.setButtonDimensionHint(fSelectAllButton);
fDeselectAllButton= new Button(buttonContainer, SWT.PUSH);
fDeselectAllButton.setText(WizardMessages.NewContractWizardPageTwo_deselectAll);
gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
fDeselectAllButton.setLayoutData(gd);
fDeselectAllButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
fMethodsTree.setCheckedElements(new Object[0]);
doCheckedStateChanged();
}
});
//LayoutUtil.setButtonDimensionHint(fDeselectAllButton);
/* No of selected methods label */
fSelectedMethodsLabel= new Label(container, SWT.LEFT);
fSelectedMethodsLabel.setFont(container.getFont());
doCheckedStateChanged();
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan= 1;
fSelectedMethodsLabel.setLayoutData(gd);
Label emptyLabel= new Label(container, SWT.LEFT);
gd= new GridData();
gd.horizontalSpan= 1;
emptyLabel.setLayoutData(gd);
}
private void createSpacer(Composite container) {
Label spacer= new Label(container, SWT.NONE);
GridData data= new GridData();
data.horizontalSpan= 2;
data.horizontalAlignment= GridData.FILL;
data.verticalAlignment= GridData.BEGINNING;
data.heightHint= 4;
spacer.setLayoutData(data);
}
/**
* Sets the class under test.
*
* @param classUnderTest the class under test
*/
public void setClassUnderTest(IType classUnderTest) {
fClassToContract= classUnderTest;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
*/
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
if (fClassToContract == null) {
return;
}
ArrayList<IType> types= null;
try {
ITypeHierarchy hierarchy= fClassToContract.newSupertypeHierarchy(null);
IType[] superTypes;
if (fClassToContract.isClass())
superTypes= hierarchy.getAllSuperclasses(fClassToContract);
else if (fClassToContract.isInterface())
superTypes= hierarchy.getAllSuperInterfaces(fClassToContract);
else
superTypes= new IType[0];
types= new ArrayList<IType>(superTypes.length+1);
types.add(fClassToContract);
types.addAll(Arrays.asList(superTypes));
} catch(JavaModelException e) {
C4JActivator.log(e);
}
if (types == null)
types= new ArrayList<IType>();
MethodsTreeContentProvider contentProvider = new MethodsTreeContentProvider(types.toArray(new IType[] {}));
fMethodsTree.setContentProvider(contentProvider);
fMethodsTree.setInput(types.toArray());
NewContractMethodElement selElement = contentProvider.getElementFromType(fClassToContract);
if (selElement != null)
fMethodsTree.setSelection(new StructuredSelection(selElement), true);
doCheckedStateChanged();
fMethodsTree.getControl().setFocus();
}
}
/**
* Returns all checked methods in the methods tree.
*
* @return the checked methods
*/
public NewContractMethodElement[] getCheckedElements() {
int methodCount= 0;
for (Object object : fCheckedObjects) {
if (((NewContractMethodElement)object).getMember() instanceof IMethod)
methodCount++;
}
NewContractMethodElement[] checkedElements= new NewContractMethodElement[methodCount];
int j= 0;
for (Object object : fCheckedObjects) {
if (((NewContractMethodElement)object).getMember() instanceof IMethod) {
checkedElements[j]= (NewContractMethodElement)object;
j++;
}
}
return checkedElements;
}
private static class MethodsTreeContentProvider implements ITreeContentProvider {
private IType[] fTypes;
private NewContractMethodElement[] fElements;
private IMethod[] fMethods;
private final Object[] fEmpty= new Object[0];
public MethodsTreeContentProvider(IType[] types) {
fTypes= types;
fElements = new NewContractMethodElement[fTypes.length];
for (int i = 0; i < fTypes.length; i++) {
fElements[i] = new NewContractMethodElement(fTypes[i]);
}
Vector<IMethod> methods= new Vector<IMethod>();
for (int i = types.length-1; i > -1; i--) {
Object object = types[i];
if (object instanceof IType) {
IType type = (IType) object;
try {
IMethod[] currMethods= type.getMethods();
for_currMethods:
for (int j = 0; j < currMethods.length; j++) {
IMethod currMethod = currMethods[j];
int flags= currMethod.getFlags();
if (!Flags.isPrivate(flags) && !Flags.isSynthetic(flags)) {
for (int k = 0; k < methods.size(); k++) {
IMethod m= ((IMethod)methods.get(k));
if (m.getElementName().equals(currMethod.getElementName())
&& m.getSignature().equals(currMethod.getSignature())) {
methods.set(k,currMethod);
continue for_currMethods;
}
}
methods.add(currMethod);
}
}
} catch (JavaModelException e) {
C4JActivator.log(e);
}
}
}
fMethods= new IMethod[methods.size()];
methods.copyInto(fMethods);
}
public NewContractMethodElement getElementFromType(IType type) {
for (NewContractMethodElement element : fElements) {
if (element.getMember().equals(type)) return element;
}
return null;
}
/*
* @see ITreeContentProvider#getChildren(Object)
*/
public Object[] getChildren(Object parentElement) {
NewContractMethodElement parent = (NewContractMethodElement)parentElement;
if (parent.getMember() instanceof IType) {
IType parentType= (IType)parent.getMember();
ArrayList<NewContractMethodElement> result= new ArrayList<NewContractMethodElement>(fMethods.length);
for (IMethod curMethod : fMethods) {
if (curMethod.getDeclaringType().equals(parentType)) {
result.add(new NewContractMethodElement(curMethod));
}
}
return result.toArray();
}
return fEmpty;
}
/*
* @see ITreeContentProvider#getParent(Object)
*/
public Object getParent(Object element) {
NewContractMethodElement item = (NewContractMethodElement)element;
if (item.getMember() instanceof IMethod) {
IType parentType = ((IMethod)item.getMember()).getDeclaringType();
for (NewContractMethodElement curElement : fElements) {
if (curElement.getMember().equals(parentType))
return curElement;
}
}
return null;
}
/*
* @see ITreeContentProvider#hasChildren(Object)
*/
public boolean hasChildren(Object element) {
return getChildren(element).length > 0;
}
/*
* @see IStructuredContentProvider#getElements(Object)
*/
public Object[] getElements(Object inputElement) {
return fElements;
}
/*
* @see IContentProvider#dispose()
*/
public void dispose() {
}
/*
* @see IContentProvider#inputChanged(Viewer, Object, Object)
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
public IMethod[] getAllMethods() {
return fMethods;
}
}
private class MethodCellModifier implements ICellModifier {
public boolean canModify(Object element, String property) {
if (((NewContractMethodElement)element).getMember() instanceof IType)
return false;
if (property.equals(PROP_METHOD_COL))
return false;
return true;
}
public Object getValue(Object element, String property) {
if (property.equals(PROP_PRE_COL)) {
return ((NewContractMethodElement)element).getPreCondition();
}
else if(property.equals(PROP_POST_COL)) {
return ((NewContractMethodElement)element).getPostCondition();
}
return null;
}
public void modify(Object element, String property, Object value) {
if (element instanceof Item) {
element = ((Item) element).getData();
}
if (property.equals(PROP_PRE_COL)) {
((NewContractMethodElement)element).setPreCondition((Integer)value);
}
else if (property.equals(PROP_POST_COL)) {
((NewContractMethodElement)element).setPostCondition((Integer)value);
}
fMethodsTree.update(element, null);
}
}
/**
* Returns true if the checkbox for creating tasks is checked.
*
* @return <code>true</code> is returned if tasks should be created
*/
public boolean isCreateTasks() {
return fCreateTasks;
}
/**
* Returns true if the checkbox for final method stubs is checked.
* @return <code>true</code> is returned if methods should be created final
*/
public boolean getCreateFinalMethodStubsButtonSelection() {
return fCreateFinalStubs;
}
private void doCheckedStateChanged() {
Object[] checked= fMethodsTree.getCheckedElements();
fCheckedObjects= checked;
int checkedMethodCount= 0;
for (int i= 0; i < checked.length; i++) {
NewContractMethodElement element = (NewContractMethodElement)checked[i];
if (element.getMember() instanceof IMethod)
checkedMethodCount++;
}
String label= ""; //$NON-NLS-1$
if (checkedMethodCount == 1)
label= NLS.bind(WizardMessages.NewContractWizardPageTwo_selected_methods_label_one, new Integer(checkedMethodCount));
else
label= NLS.bind(WizardMessages.NewContractWizardPageTwo_selected_methods_label_many, new Integer(checkedMethodCount));
fSelectedMethodsLabel.setText(label);
}
/**
* Use the dialog store to restore widget values to the values that they held
* last time this wizard was used to completion
*/
private void restoreWidgetValues() {
IDialogSettings settings= getDialogSettings();
if (settings != null) {
fCreateTasks= settings.getBoolean(STORE_USE_TASKMARKER);
fCreateTasksButton.setSelection(fCreateTasks);
fCreateFinalStubs= settings.getBoolean(STORE_CREATE_FINAL_METHOD_STUBS);
fCreateFinalMethodStubsButton.setSelection(fCreateFinalStubs);
}
}
private void saveWidgetValues() {
IDialogSettings settings= getDialogSettings();
if (settings != null) {
settings.put(STORE_USE_TASKMARKER, fCreateTasks);
settings.put(STORE_CREATE_FINAL_METHOD_STUBS, fCreateFinalStubs);
}
}
}