001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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.HashMap;
013: import java.util.HashSet;
014: import java.util.Iterator;
015: import java.util.Map;
016: import java.util.Set;
017:
018: import org.eclipse.swt.SWT;
019: import org.eclipse.swt.events.SelectionAdapter;
020: import org.eclipse.swt.events.SelectionEvent;
021: import org.eclipse.swt.layout.GridData;
022: import org.eclipse.swt.layout.GridLayout;
023: import org.eclipse.swt.widgets.Button;
024: import org.eclipse.swt.widgets.Composite;
025: import org.eclipse.swt.widgets.Label;
026: import org.eclipse.swt.widgets.Tree;
027: import org.eclipse.swt.widgets.TreeItem;
028:
029: import org.eclipse.jface.dialogs.Dialog;
030: import org.eclipse.jface.dialogs.IDialogSettings;
031: import org.eclipse.jface.dialogs.IMessageProvider;
032: import org.eclipse.jface.viewers.ISelectionChangedListener;
033: import org.eclipse.jface.viewers.IStructuredSelection;
034: import org.eclipse.jface.viewers.ITreeContentProvider;
035: import org.eclipse.jface.viewers.SelectionChangedEvent;
036: import org.eclipse.jface.viewers.TreeViewer;
037: import org.eclipse.jface.viewers.Viewer;
038: import org.eclipse.jface.viewers.ViewerComparator;
039: import org.eclipse.jface.wizard.IWizardPage;
040:
041: import org.eclipse.ui.PlatformUI;
042:
043: import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
044: import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
045:
046: import org.eclipse.jdt.core.IType;
047: import org.eclipse.jdt.core.ITypeHierarchy;
048: import org.eclipse.jdt.core.JavaModelException;
049:
050: import org.eclipse.jdt.internal.corext.refactoring.structure.UseSuperTypeProcessor;
051: import org.eclipse.jdt.internal.corext.refactoring.structure.UseSuperTypeRefactoring;
052: import org.eclipse.jdt.internal.corext.util.Messages;
053: import org.eclipse.jdt.internal.corext.util.SuperTypeHierarchyCache;
054:
055: import org.eclipse.jdt.ui.JavaElementLabelProvider;
056: import org.eclipse.jdt.ui.JavaElementLabels;
057:
058: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
059: import org.eclipse.jdt.internal.ui.JavaPlugin;
060:
061: public class UseSupertypeWizard extends RefactoringWizard {
062:
063: /* package */static final String DIALOG_SETTING_SECTION = "UseSupertypeWizard"; //$NON-NLS-1$
064:
065: public UseSupertypeWizard(UseSuperTypeRefactoring ref) {
066: super (ref, DIALOG_BASED_USER_INTERFACE);
067: setDefaultPageTitle(RefactoringMessages.UseSupertypeWizard_Use_Super_Type_Where_Possible);
068: }
069:
070: protected void addUserInputPages() {
071: addPage(new UseSupertypeInputPage());
072: }
073:
074: private static class UseSupertypeInputPage extends
075: UserInputWizardPage {
076:
077: private class UseSupertypeContentProvider implements
078: ITreeContentProvider {
079:
080: private ITypeHierarchy fHierarchy;
081:
082: public Object[] getChildren(Object element) {
083: if (element instanceof ITypeHierarchy)
084: return getElements(element);
085: return getDirectSuperTypes((IType) element).toArray();
086: }
087:
088: public Set/*<IType>*/getDirectSuperTypes(IType type) {
089: Set/*<IType>*/result = new HashSet();
090: final IType super class = fHierarchy.getSuperclass(type);
091: if (super class != null) {
092: result.add(super class);
093: }
094: IType[] super Interface = fHierarchy
095: .getSuperInterfaces(type);
096: for (int i = 0; i < super Interface.length; i++) {
097: result.add(super Interface[i]);
098: }
099: try {
100: if (type.isInterface()) {
101: IType found = type.getJavaProject().findType(
102: "java.lang.Object"); //$NON-NLS-1$
103: result.add(found);
104: }
105: } catch (JavaModelException exception) {
106: JavaPlugin.log(exception);
107: }
108: return result;
109: }
110:
111: public Object[] getElements(Object element) {
112: if (element instanceof ITypeHierarchy)
113: return getChildren(((ITypeHierarchy) element)
114: .getType());
115: return new Object[0];
116: }
117:
118: public boolean hasChildren(Object element) {
119: return getChildren(element).length > 0;
120: }
121:
122: public Object getParent(Object element) {
123: return null;
124: }
125:
126: public void dispose() {
127: // Do nothing
128: }
129:
130: public void inputChanged(Viewer viewer, Object oldInput,
131: Object newInput) {
132: if (newInput instanceof ITypeHierarchy)
133: fHierarchy = (ITypeHierarchy) newInput;
134: else
135: fHierarchy = null;
136: }
137: }
138:
139: private static final String REWRITE_INSTANCEOF = "rewriteInstanceOf"; //$NON-NLS-1$
140: public static final String PAGE_NAME = "UseSupertypeInputPage";//$NON-NLS-1$
141: private TreeViewer fTreeViewer;
142: private final Map fFileCount; //IType -> Integer
143: private final static String MESSAGE = RefactoringMessages.UseSupertypeInputPage_Select_super type;
144: private JavaElementLabelProvider fLabelProvider;
145: private IDialogSettings fSettings;
146:
147: public UseSupertypeInputPage() {
148: super (PAGE_NAME);
149: fFileCount = new HashMap(2);
150: setMessage(MESSAGE);
151: }
152:
153: private void loadSettings() {
154: fSettings = getDialogSettings().getSection(
155: UseSupertypeWizard.DIALOG_SETTING_SECTION);
156: if (fSettings == null) {
157: fSettings = getDialogSettings().addNewSection(
158: UseSupertypeWizard.DIALOG_SETTING_SECTION);
159: fSettings.put(REWRITE_INSTANCEOF, false);
160: }
161: getUseSupertypeProcessor().setInstanceOf(
162: fSettings.getBoolean(REWRITE_INSTANCEOF));
163: }
164:
165: private UseSuperTypeProcessor getUseSupertypeProcessor() {
166: return getUseSupertypeRefactoring()
167: .getUseSuperTypeProcessor();
168: }
169:
170: private UseSuperTypeRefactoring getUseSupertypeRefactoring() {
171: return ((UseSuperTypeRefactoring) getRefactoring());
172: }
173:
174: public void createControl(Composite parent) {
175: initializeDialogUnits(parent);
176: loadSettings();
177: Composite composite = new Composite(parent, SWT.NONE);
178: setControl(composite);
179: composite.setLayout(new GridLayout());
180:
181: Label label = new Label(composite, SWT.NONE);
182: label
183: .setText(Messages
184: .format(
185: RefactoringMessages.UseSupertypeInputPage_Select_super type_to_use,
186: JavaElementLabels
187: .getElementLabel(
188: getUseSupertypeProcessor()
189: .getSubType(),
190: JavaElementLabels.T_FULLY_QUALIFIED)));
191: label.setLayoutData(new GridData());
192:
193: addTreeViewer(composite);
194:
195: final Button checkbox = new Button(composite, SWT.CHECK);
196: checkbox
197: .setText(RefactoringMessages.UseSupertypeInputPage_Use_in_instanceof );
198: checkbox.setLayoutData(new GridData());
199: checkbox.setSelection(getUseSupertypeProcessor()
200: .isInstanceOf());
201: checkbox.addSelectionListener(new SelectionAdapter() {
202: public void widgetSelected(SelectionEvent e) {
203: getUseSupertypeProcessor().setInstanceOf(
204: checkbox.getSelection());
205: fSettings.put(REWRITE_INSTANCEOF, checkbox
206: .getSelection());
207: setMessage(MESSAGE);
208: setPageComplete(true);
209: fFileCount.clear();
210: fTreeViewer.refresh();
211: }
212: });
213:
214: Dialog.applyDialogFont(composite);
215: PlatformUI.getWorkbench().getHelpSystem().setHelp(
216: getControl(),
217: IJavaHelpContextIds.USE_SUPERTYPE_WIZARD_PAGE);
218: }
219:
220: private void addTreeViewer(Composite composite) {
221: fTreeViewer = new TreeViewer(composite, SWT.SINGLE
222: | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
223: final Tree tree = fTreeViewer.getTree();
224: final GridData data = new GridData(GridData.FILL_BOTH);
225: data.heightHint = convertHeightInCharsToPixels(12);
226: tree.setLayoutData(data);
227: fLabelProvider = new UseSupertypeLabelProvider(fFileCount);
228: fTreeViewer.setLabelProvider(fLabelProvider);
229: fTreeViewer
230: .setContentProvider(new UseSupertypeContentProvider());
231: fTreeViewer.setComparator(new ViewerComparator() {
232:
233: public boolean isSorterProperty(Object element,
234: String property) {
235: return true;
236: }
237:
238: public int compare(Viewer viewer, Object first,
239: Object second) {
240: final IType type1 = (IType) first;
241: final IType type2 = (IType) second;
242: try {
243: final int kind1 = type1.isInterface() ? 1 : 0;
244: final int kind2 = type2.isInterface() ? 1 : 0;
245: if (kind1 - kind2 != 0)
246: return kind1 - kind2;
247: } catch (JavaModelException exception) {
248: JavaPlugin.log(exception);
249: }
250: return getComparator().compare(
251: type1.getElementName(),
252: type2.getElementName());
253: }
254: });
255: fTreeViewer
256: .addSelectionChangedListener(new ISelectionChangedListener() {
257: public void selectionChanged(
258: SelectionChangedEvent event) {
259: IStructuredSelection ss = (IStructuredSelection) event
260: .getSelection();
261: if (new Integer(0).equals(fFileCount.get(ss
262: .getFirstElement()))) {
263: setMessage(
264: RefactoringMessages.UseSupertypeInputPage_No_updates,
265: IMessageProvider.INFORMATION);
266: setPageComplete(false);
267: } else {
268: setMessage(MESSAGE);
269: setPageComplete(true);
270: }
271: fTreeViewer.refresh();
272: }
273: });
274: try {
275: fTreeViewer.setInput(SuperTypeHierarchyCache
276: .getTypeHierarchy(getUseSupertypeProcessor()
277: .getSubType()));
278: } catch (JavaModelException exception) {
279: JavaPlugin.log(exception);
280: }
281: fTreeViewer.expandAll();
282: final TreeItem[] items = tree.getItems();
283: if (items.length > 0)
284: tree.setSelection(new TreeItem[] { items[0] });
285: }
286:
287: public IWizardPage getNextPage() {
288: initializeRefactoring();
289: IWizardPage nextPage = super .getNextPage();
290: updateUpdateLabels();
291: return nextPage;
292: }
293:
294: private void updateUpdateLabels() {
295: IType selectedType = getSelectedSupertype();
296: final int count = getUseSupertypeProcessor().getChanges();
297: fFileCount.put(selectedType, new Integer(count));
298: if (count == 0) {
299: setMessage(
300: RefactoringMessages.UseSupertypeInputPage_No_updates,
301: IMessageProvider.INFORMATION);
302: setPageComplete(false);
303: }
304: fTreeViewer.refresh();
305: if (noSupertypeCanBeUsed()) {
306: setMessage(RefactoringMessages.UseSupertypeWizard_10,
307: IMessageProvider.INFORMATION);
308: setPageComplete(false);
309: }
310: }
311:
312: private boolean noSupertypeCanBeUsed() {
313: return fTreeViewer.getTree().getItemCount() == countFilesWithValue(0);
314: }
315:
316: private int countFilesWithValue(int i) {
317: int count = 0;
318: for (Iterator iter = fFileCount.keySet().iterator(); iter
319: .hasNext();) {
320: if (((Integer) fFileCount.get(iter.next())).intValue() == i)
321: count++;
322: }
323: return count;
324: }
325:
326: private IType getSelectedSupertype() {
327: IStructuredSelection ss = (IStructuredSelection) fTreeViewer
328: .getSelection();
329: return (IType) ss.getFirstElement();
330: }
331:
332: public boolean performFinish() {
333: initializeRefactoring();
334: boolean super Finish = super .performFinish();
335: if (!super Finish)
336: return false;
337: final int count = getUseSupertypeProcessor().getChanges();
338: if (count == 0) {
339: updateUpdateLabels();
340: return false;
341: }
342: return super Finish;
343: }
344:
345: private void initializeRefactoring() {
346: IStructuredSelection ss = (IStructuredSelection) fTreeViewer
347: .getSelection();
348: getUseSupertypeProcessor().setSuperType(
349: (IType) ss.getFirstElement());
350: }
351:
352: public void dispose() {
353: fTreeViewer = null;
354: fFileCount.clear();
355: fLabelProvider = null;
356: super .dispose();
357: }
358:
359: private static class UseSupertypeLabelProvider extends
360: JavaElementLabelProvider {
361: private final Map fFileCount;
362:
363: private UseSupertypeLabelProvider(Map fileCount) {
364: fFileCount = fileCount;
365: }
366:
367: public String getText(Object element) {
368: String super Text = super .getText(element);
369: if (!fFileCount.containsKey(element))
370: return super Text;
371: int count = ((Integer) fFileCount.get(element))
372: .intValue();
373: if (count == 0) {
374: String[] keys = { super Text };
375: return Messages
376: .format(
377: RefactoringMessages.UseSupertypeInputPage_no_possible_updates,
378: keys);
379: } else if (count == 1) {
380: String[] keys = { super Text };
381: return Messages
382: .format(
383: RefactoringMessages.UseSupertypeInputPage_updates_possible_in_file,
384: keys);
385: } else {
386: String[] keys = { super Text, String.valueOf(count) };
387: return Messages
388: .format(
389: RefactoringMessages.UseSupertypeInputPage_updates_possible_in_files,
390: keys);
391: }
392: }
393: }
394:
395: public void setVisible(boolean visible) {
396: super.setVisible(visible);
397: if (visible && fTreeViewer != null)
398: fTreeViewer.getTree().setFocus();
399: }
400: }
401: }
|