001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.refactoring;
011:
012: import java.util.ArrayList;
013: import java.util.Iterator;
014: import java.util.List;
015:
016: import org.eclipse.core.runtime.Assert;
017: import org.eclipse.core.runtime.IStatus;
018: import org.eclipse.core.runtime.NullProgressMonitor;
019:
020: import org.eclipse.swt.SWT;
021: import org.eclipse.swt.events.SelectionAdapter;
022: import org.eclipse.swt.events.SelectionEvent;
023: import org.eclipse.swt.graphics.Image;
024: import org.eclipse.swt.layout.GridData;
025: import org.eclipse.swt.layout.GridLayout;
026: import org.eclipse.swt.widgets.Button;
027: import org.eclipse.swt.widgets.Composite;
028: import org.eclipse.swt.widgets.Table;
029:
030: import org.eclipse.jface.viewers.ISelection;
031: import org.eclipse.jface.viewers.ISelectionChangedListener;
032: import org.eclipse.jface.viewers.IStructuredContentProvider;
033: import org.eclipse.jface.viewers.IStructuredSelection;
034: import org.eclipse.jface.viewers.ITableLabelProvider;
035: import org.eclipse.jface.viewers.LabelProvider;
036: import org.eclipse.jface.viewers.SelectionChangedEvent;
037: import org.eclipse.jface.viewers.StructuredSelection;
038: import org.eclipse.jface.viewers.TableViewer;
039: import org.eclipse.jface.viewers.Viewer;
040: import org.eclipse.jface.window.Window;
041:
042: import org.eclipse.ui.PlatformUI;
043: import org.eclipse.ui.dialogs.ISelectionStatusValidator;
044:
045: import org.eclipse.jdt.core.IJavaElement;
046: import org.eclipse.jdt.core.IJavaProject;
047: import org.eclipse.jdt.core.IType;
048: import org.eclipse.jdt.core.ITypeHierarchy;
049: import org.eclipse.jdt.core.JavaModelException;
050: import org.eclipse.jdt.core.search.IJavaSearchConstants;
051: import org.eclipse.jdt.core.search.IJavaSearchScope;
052: import org.eclipse.jdt.core.search.SearchEngine;
053:
054: import org.eclipse.jdt.internal.corext.refactoring.ExceptionInfo;
055:
056: import org.eclipse.jdt.internal.ui.JavaPlugin;
057: import org.eclipse.jdt.internal.ui.JavaPluginImages;
058: import org.eclipse.jdt.internal.ui.JavaUIStatus;
059: import org.eclipse.jdt.internal.ui.dialogs.FilteredTypesSelectionDialog;
060: import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
061: import org.eclipse.jdt.internal.ui.util.SWTUtil;
062:
063: /**
064: * A special control to add and remove thrown exceptions.
065: */
066: public class ChangeExceptionsControl extends Composite {
067: //TODO: cleanup, adapt NLS strings
068:
069: private static class ExceptionInfoContentProvider implements
070: IStructuredContentProvider {
071: public Object[] getElements(Object inputElement) {
072: return removeMarkedAsDeleted((List) inputElement);
073: }
074:
075: private ExceptionInfo[] removeMarkedAsDeleted(
076: List exceptionInfos) {
077: List result = new ArrayList(exceptionInfos.size());
078: for (Iterator iter = exceptionInfos.iterator(); iter
079: .hasNext();) {
080: ExceptionInfo info = (ExceptionInfo) iter.next();
081: if (!info.isDeleted())
082: result.add(info);
083: }
084: return (ExceptionInfo[]) result
085: .toArray(new ExceptionInfo[result.size()]);
086: }
087:
088: public void dispose() {
089: // do nothing
090: }
091:
092: public void inputChanged(Viewer viewer, Object oldInput,
093: Object newInput) {
094: // do nothing
095: }
096: }
097:
098: private static class ExceptionInfoLabelProvider extends
099: LabelProvider implements ITableLabelProvider {
100: private Image fInterfaceImage;
101:
102: public ExceptionInfoLabelProvider() {
103: super ();
104: fInterfaceImage = JavaPluginImages
105: .get(JavaPluginImages.IMG_OBJS_CLASS);
106: }
107:
108: public Image getColumnImage(Object element, int columnIndex) {
109: return fInterfaceImage;
110: }
111:
112: public String getColumnText(Object element, int columnIndex) {
113: ExceptionInfo info = (ExceptionInfo) element;
114: return info.getType().getFullyQualifiedName();
115: }
116: }
117:
118: private final IExceptionListChangeListener fListener;
119: private final IJavaProject fProject;
120:
121: private TableViewer fTableViewer;
122: private Button fRemoveButton;
123: private List fExceptionInfos;
124:
125: public ChangeExceptionsControl(Composite parent, int style,
126: IExceptionListChangeListener listener, IJavaProject project) {
127: super (parent, style);
128: Assert.isNotNull(listener);
129: fListener = listener;
130: Assert.isNotNull(project);
131: fProject = project;
132: GridLayout layout = new GridLayout();
133: layout.numColumns = 2;
134: layout.marginWidth = 0;
135: layout.marginHeight = 0;
136: setLayout(layout);
137:
138: createExceptionList(this );
139: createButtonComposite(this );
140: }
141:
142: public void setInput(List exceptionInfos) {
143: Assert.isNotNull(exceptionInfos);
144: fExceptionInfos = exceptionInfos;
145: fTableViewer.setInput(fExceptionInfos);
146: if (fExceptionInfos.size() > 0)
147: fTableViewer.setSelection(new StructuredSelection(
148: fExceptionInfos.get(0)));
149: }
150:
151: private void createExceptionList(Composite parent) {
152: final Table table = new Table(parent, SWT.MULTI | SWT.BORDER
153: | SWT.H_SCROLL | SWT.V_SCROLL);
154: table.setLayoutData(new GridData(GridData.FILL_BOTH));
155:
156: fTableViewer = new TableViewer(table);
157: fTableViewer.setUseHashlookup(true);
158: fTableViewer
159: .setContentProvider(new ExceptionInfoContentProvider());
160: fTableViewer.setLabelProvider(new ExceptionInfoLabelProvider());
161: fTableViewer
162: .addSelectionChangedListener(new ISelectionChangedListener() {
163: public void selectionChanged(
164: SelectionChangedEvent event) {
165: updateButtonsEnabledState();
166: }
167: });
168: }
169:
170: private ExceptionInfo[] getSelectedItems() {
171: ISelection selection = fTableViewer.getSelection();
172: if (selection == null)
173: return new ExceptionInfo[0];
174:
175: if (!(selection instanceof IStructuredSelection))
176: return new ExceptionInfo[0];
177:
178: List selected = ((IStructuredSelection) selection).toList();
179: return (ExceptionInfo[]) selected
180: .toArray(new ExceptionInfo[selected.size()]);
181: }
182:
183: // ---- Button bar --------------------------------------------------------------------------------------
184:
185: private void createButtonComposite(Composite parent) {
186: Composite buttonComposite = new Composite(parent, SWT.NONE);
187: buttonComposite.setLayoutData(new GridData(
188: GridData.FILL_VERTICAL));
189: GridLayout gl = new GridLayout();
190: gl.marginHeight = 0;
191: gl.marginWidth = 0;
192: buttonComposite.setLayout(gl);
193:
194: createAddButton(buttonComposite);
195: fRemoveButton = createRemoveButton(buttonComposite);
196: updateButtonsEnabledState();
197: }
198:
199: private void updateButtonsEnabledState() {
200: if (fRemoveButton != null)
201: fRemoveButton.setEnabled(getTableSelectionCount() != 0);
202: }
203:
204: private int getTableSelectionCount() {
205: return getTable().getSelectionCount();
206: }
207:
208: private int getTableItemCount() {
209: return getTable().getItemCount();
210: }
211:
212: private Table getTable() {
213: return fTableViewer.getTable();
214: }
215:
216: private Button createAddButton(Composite buttonComposite) {
217: Button button = new Button(buttonComposite, SWT.PUSH);
218: button
219: .setText(RefactoringMessages.ChangeExceptionsControl_buttons_add);
220: button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
221: SWTUtil.setButtonDimensionHint(button);
222: button.setEnabled(true);
223: button.addSelectionListener(new SelectionAdapter() {
224: public void widgetSelected(SelectionEvent e) {
225: doAddException();
226: }
227: });
228: return button;
229: }
230:
231: private void doAddException() {
232: IType newException = chooseException();
233: if (newException == null)
234: return;
235:
236: ExceptionInfo info = findExceptionInfo(newException);
237: if (info != null) {
238: if (info.isDeleted()) {
239: info.markAsOld();
240: fTableViewer.refresh();
241: }
242: fListener.exceptionListChanged();
243: fTableViewer.getControl().setFocus();
244: fTableViewer.setSelection(new StructuredSelection(info),
245: true);
246: return;
247: }
248:
249: info = ExceptionInfo.createInfoForAddedException(newException);
250: fExceptionInfos.add(info);
251: fListener.exceptionListChanged();
252: fTableViewer.refresh();
253: fTableViewer.getControl().setFocus();
254: int row = getTableItemCount() - 1;
255: getTable().setSelection(row);
256: updateButtonsEnabledState();
257:
258: }
259:
260: private IType chooseException() {
261: IJavaElement[] elements = new IJavaElement[] { fProject
262: .getJavaProject() };
263: final IJavaSearchScope scope = SearchEngine
264: .createJavaSearchScope(elements);
265:
266: FilteredTypesSelectionDialog dialog = new FilteredTypesSelectionDialog(
267: getShell(), false, PlatformUI.getWorkbench()
268: .getProgressService(), scope,
269: IJavaSearchConstants.CLASS);
270: dialog
271: .setTitle(RefactoringMessages.ChangeExceptionsControl_choose_title);
272: dialog
273: .setMessage(RefactoringMessages.ChangeExceptionsControl_choose_message);
274: dialog.setInitialPattern("*Exception*"); //$NON-NLS-1$
275: dialog.setValidator(new ISelectionStatusValidator() {
276: public IStatus validate(Object[] selection) {
277: if (selection.length == 0)
278: return new StatusInfo(IStatus.ERROR, ""); //$NON-NLS-1$
279: try {
280: return checkException((IType) selection[0]);
281: } catch (JavaModelException e) {
282: JavaPlugin.log(e);
283: return StatusInfo.OK_STATUS;
284: }
285: }
286: });
287:
288: if (dialog.open() == Window.OK) {
289: return (IType) dialog.getFirstResult();
290: }
291: return null;
292: }
293:
294: private IStatus checkException(final IType type)
295: throws JavaModelException {
296: ITypeHierarchy hierarchy = type
297: .newSupertypeHierarchy(new NullProgressMonitor());
298: IType curr = type;
299: while (curr != null) {
300: String name = curr.getFullyQualifiedName();
301: if ("java.lang.Throwable".equals(name)) //$NON-NLS-1$
302: return StatusInfo.OK_STATUS;
303: curr = hierarchy.getSuperclass(curr);
304: }
305: return JavaUIStatus
306: .createError(
307: IStatus.ERROR,
308: RefactoringMessages.ChangeExceptionsControl_not_exception,
309: null);
310: }
311:
312: private ExceptionInfo findExceptionInfo(IType exception) {
313: for (Iterator iter = fExceptionInfos.iterator(); iter.hasNext();) {
314: ExceptionInfo info = (ExceptionInfo) iter.next();
315: if (info.getType().equals(exception))
316: return info;
317: }
318: return null;
319: }
320:
321: private Button createRemoveButton(Composite buttonComposite) {
322: final Button button = new Button(buttonComposite, SWT.PUSH);
323: button
324: .setText(RefactoringMessages.ChangeExceptionsControl_buttons_remove);
325: button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
326: SWTUtil.setButtonDimensionHint(button);
327: button.addSelectionListener(new SelectionAdapter() {
328: public void widgetSelected(SelectionEvent e) {
329: int index = getTable().getSelectionIndices()[0];
330: ExceptionInfo[] selected = getSelectedItems();
331: for (int i = 0; i < selected.length; i++) {
332: if (selected[i].isAdded())
333: fExceptionInfos.remove(selected[i]);
334: else
335: selected[i].markAsDeleted();
336: }
337: restoreSelection(index);
338: }
339:
340: private void restoreSelection(int index) {
341: fTableViewer.refresh();
342: fTableViewer.getControl().setFocus();
343: int itemCount = getTableItemCount();
344: if (itemCount != 0) {
345: if (index >= itemCount)
346: index = itemCount - 1;
347: getTable().setSelection(index);
348: }
349: fListener.exceptionListChanged();
350: updateButtonsEnabledState();
351: }
352: });
353: return button;
354: }
355:
356: }
|