KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > ui > actions > AddGetterSetterAction


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Philippe Ombredanne - bug 149382
11  *******************************************************************************/

12 package org.eclipse.jdt.ui.actions;
13
14 import java.lang.reflect.InvocationTargetException JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.Arrays JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.LinkedHashMap JavaDoc;
20 import java.util.LinkedHashSet JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.Set JavaDoc;
24
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IStatus;
27
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.events.SelectionAdapter;
30 import org.eclipse.swt.events.SelectionEvent;
31 import org.eclipse.swt.events.SelectionListener;
32 import org.eclipse.swt.graphics.Image;
33 import org.eclipse.swt.layout.GridData;
34 import org.eclipse.swt.layout.GridLayout;
35 import org.eclipse.swt.widgets.Button;
36 import org.eclipse.swt.widgets.Combo;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Control;
39 import org.eclipse.swt.widgets.Label;
40 import org.eclipse.swt.widgets.Link;
41 import org.eclipse.swt.widgets.Shell;
42
43 import org.eclipse.jface.dialogs.IDialogConstants;
44 import org.eclipse.jface.dialogs.IDialogSettings;
45 import org.eclipse.jface.dialogs.MessageDialog;
46 import org.eclipse.jface.operation.IRunnableContext;
47 import org.eclipse.jface.resource.ImageDescriptor;
48 import org.eclipse.jface.viewers.CheckboxTreeViewer;
49 import org.eclipse.jface.viewers.ILabelProvider;
50 import org.eclipse.jface.viewers.IStructuredSelection;
51 import org.eclipse.jface.viewers.ITreeContentProvider;
52 import org.eclipse.jface.viewers.Viewer;
53 import org.eclipse.jface.viewers.ViewerFilter;
54 import org.eclipse.jface.window.Window;
55
56 import org.eclipse.jface.text.IRewriteTarget;
57 import org.eclipse.jface.text.ITextSelection;
58
59 import org.eclipse.ui.IEditorPart;
60 import org.eclipse.ui.IWorkbenchSite;
61 import org.eclipse.ui.PlatformUI;
62 import org.eclipse.ui.dialogs.ISelectionStatusValidator;
63
64 import org.eclipse.jdt.core.Flags;
65 import org.eclipse.jdt.core.ICompilationUnit;
66 import org.eclipse.jdt.core.IField;
67 import org.eclipse.jdt.core.IJavaElement;
68 import org.eclipse.jdt.core.IMember;
69 import org.eclipse.jdt.core.IType;
70 import org.eclipse.jdt.core.JavaModelException;
71 import org.eclipse.jdt.core.Signature;
72 import org.eclipse.jdt.core.dom.AST;
73 import org.eclipse.jdt.core.dom.CompilationUnit;
74
75 import org.eclipse.jdt.internal.corext.codemanipulation.AddGetterSetterOperation;
76 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
77 import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil;
78 import org.eclipse.jdt.internal.corext.codemanipulation.IRequestQuery;
79 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
80 import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType;
81 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
82 import org.eclipse.jdt.internal.corext.util.JdtFlags;
83 import org.eclipse.jdt.internal.corext.util.Messages;
84
85 import org.eclipse.jdt.ui.JavaElementComparator;
86 import org.eclipse.jdt.ui.JavaElementImageDescriptor;
87 import org.eclipse.jdt.ui.JavaElementLabelProvider;
88 import org.eclipse.jdt.ui.JavaElementLabels;
89 import org.eclipse.jdt.ui.JavaUI;
90
91 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
92 import org.eclipse.jdt.internal.ui.JavaPlugin;
93 import org.eclipse.jdt.internal.ui.actions.ActionMessages;
94 import org.eclipse.jdt.internal.ui.actions.ActionUtil;
95 import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
96 import org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter;
97 import org.eclipse.jdt.internal.ui.dialogs.SourceActionDialog;
98 import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
99 import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
100 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
101 import org.eclipse.jdt.internal.ui.util.BusyIndicatorRunnableContext;
102 import org.eclipse.jdt.internal.ui.util.ElementValidator;
103 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
104 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
105
106 /**
107  * Creates getter and setter methods for a type's fields. Opens a dialog with a list of
108  * fields for which a setter or getter can be generated. User is able to check or uncheck
109  * items before setters or getters are generated.
110  * <p>
111  * Will open the parent compilation unit in a Java editor. The result is unsaved, so the
112  * user can decide if the changes are acceptable.
113  * <p>
114  * The action is applicable to structured selections containing elements of type
115  * <code>IField</code> or <code>IType</code>.
116  *
117  * <p>
118  * This class may be instantiated; it is not intended to be subclassed.
119  * </p>
120  *
121  * @since 2.0
122  */

123 public class AddGetterSetterAction extends SelectionDispatchAction {
124
125     private boolean fSort;
126
127     private boolean fSynchronized;
128
129     private boolean fFinal;
130
131     private int fVisibility;
132
133     private boolean fGenerateComment;
134
135     private int fNumEntries;
136
137     private CompilationUnitEditor fEditor;
138
139     private static final String JavaDoc DIALOG_TITLE= ActionMessages.AddGetterSetterAction_error_title;
140
141     /**
142      * Creates a new <code>AddGetterSetterAction</code>. The action requires that the
143      * selection provided by the site's selection provider is of type <code>
144      * org.eclipse.jface.viewers.IStructuredSelection</code>.
145      *
146      * @param site the site providing context information for this action
147      */

148     public AddGetterSetterAction(IWorkbenchSite site) {
149         super(site);
150         setText(ActionMessages.AddGetterSetterAction_label);
151         setDescription(ActionMessages.AddGetterSetterAction_description);
152         setToolTipText(ActionMessages.AddGetterSetterAction_tooltip);
153
154         PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.GETTERSETTER_ACTION);
155     }
156
157     /**
158      * Note: This constructor is for internal use only. Clients should not call this
159      * constructor.
160      *
161      * @param editor the compilation unit editor
162      */

163     public AddGetterSetterAction(CompilationUnitEditor editor) {
164         this(editor.getEditorSite());
165         fEditor= editor;
166         setEnabled(SelectionConverter.getInputAsCompilationUnit(editor) != null);
167         fEditor.getEditorSite();
168     }
169
170     // ---- Structured Viewer -----------------------------------------------------------
171

172     /*
173      * (non-Javadoc) Method declared on SelectionDispatchAction
174      */

175     public void selectionChanged(IStructuredSelection selection) {
176         try {
177             setEnabled(canEnable(selection));
178         } catch (JavaModelException e) {
179             // http://bugs.eclipse.org/bugs/show_bug.cgi?id=19253
180
if (JavaModelUtil.isExceptionToBeLogged(e))
181                 JavaPlugin.log(e);
182             setEnabled(false);
183         }
184     }
185
186     /*
187      * (non-Javadoc) Method declared on SelectionDispatchAction
188      */

189     public void run(IStructuredSelection selection) {
190         try {
191             IField[] selectedFields= getSelectedFields(selection);
192             if (canRunOn(selectedFields)) {
193                 run(selectedFields[0].getDeclaringType(), selectedFields, false);
194                 return;
195             }
196             Object JavaDoc firstElement= selection.getFirstElement();
197
198             if (firstElement instanceof IType)
199                 run((IType) firstElement, new IField[0], false);
200             else if (firstElement instanceof ICompilationUnit) {
201                 // http://bugs.eclipse.org/bugs/show_bug.cgi?id=38500
202
IType type= ((ICompilationUnit) firstElement).findPrimaryType();
203                 // type can be null if file has a bad encoding
204
if (type == null) {
205                     MessageDialog.openError(getShell(),
206                         ActionMessages.AddGetterSetterAction_no_primary_type_title,
207                         ActionMessages.AddGetterSetterAction_no_primary_type_message);
208                     notifyResult(false);
209                     return;
210                 }
211                 if (type.isAnnotation()) {
212                     MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddGetterSetterAction_annotation_not_applicable);
213                     notifyResult(false);
214                     return;
215                 } else if (type.isInterface()) {
216                     MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddGetterSetterAction_interface_not_applicable);
217                     notifyResult(false);
218                     return;
219                 } else
220                     run(((ICompilationUnit) firstElement).findPrimaryType(), new IField[0], false);
221             }
222         } catch (CoreException e) {
223             ExceptionHandler.handle(e, getShell(), DIALOG_TITLE, ActionMessages.AddGetterSetterAction_error_actionfailed);
224         }
225
226     }
227
228     private boolean canEnable(IStructuredSelection selection) throws JavaModelException {
229         if (getSelectedFields(selection) != null)
230             return true;
231
232         if ((selection.size() == 1) && (selection.getFirstElement() instanceof IType)) {
233             IType type= (IType) selection.getFirstElement();
234             return type.getCompilationUnit() != null && !type.isInterface() && !type.isLocal();
235         }
236
237         if ((selection.size() == 1) && (selection.getFirstElement() instanceof ICompilationUnit))
238             return true;
239
240         return false;
241     }
242
243     private boolean canRunOn(IField[] fields) throws JavaModelException {
244         if (fields == null || fields.length == 0)
245             return false;
246         int count= 0;
247         for (int index= 0; index < fields.length; index++) {
248             if (!JdtFlags.isEnum(fields[index]))
249                 count++;
250         }
251         if (count == 0)
252             MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddGetterSetterAction_not_applicable);
253         return (count > 0);
254     }
255
256     private void resetNumEntries() {
257         fNumEntries= 0;
258     }
259
260     private void incNumEntries() {
261         fNumEntries++;
262     }
263
264     private void run(IType type, IField[] preselected, boolean editor) throws CoreException {
265         if (type.isAnnotation()) {
266             MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddGetterSetterAction_annotation_not_applicable);
267             notifyResult(false);
268             return;
269         } else if (type.isInterface()) {
270             MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddGetterSetterAction_interface_not_applicable);
271             notifyResult(false);
272             return;
273         } else if (type.getCompilationUnit() == null) {
274             MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddGetterSetterAction_error_not_in_source_file);
275             notifyResult(false);
276             return;
277         }
278         if (!ElementValidator.check(type, getShell(), DIALOG_TITLE, editor)) {
279             notifyResult(false);
280             return;
281         }
282         if (!ActionUtil.isEditable(getShell(), type)) {
283             notifyResult(false);
284             return;
285         }
286
287         ILabelProvider lp= new AddGetterSetterLabelProvider();
288         resetNumEntries();
289         Map JavaDoc entries= createGetterSetterMapping(type);
290         if (entries.isEmpty()) {
291             MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddGettSetterAction_typeContainsNoFields_message);
292             notifyResult(false);
293             return;
294         }
295         AddGetterSetterContentProvider cp= new AddGetterSetterContentProvider(entries);
296         GetterSetterTreeSelectionDialog dialog= new GetterSetterTreeSelectionDialog(getShell(), lp, cp, fEditor, type);
297         dialog.setComparator(new JavaElementComparator());
298         dialog.setTitle(DIALOG_TITLE);
299         String JavaDoc message= ActionMessages.AddGetterSetterAction_dialog_label;
300         dialog.setMessage(message);
301         dialog.setValidator(createValidator(fNumEntries));
302         dialog.setContainerMode(true);
303         dialog.setSize(60, 18);
304         dialog.setInput(type);
305
306         if (preselected.length > 0) {
307             dialog.setInitialSelections(preselected);
308             dialog.setExpandedElements(preselected);
309         }
310         final Set JavaDoc keySet= new LinkedHashSet JavaDoc(entries.keySet());
311         int dialogResult= dialog.open();
312         if (dialogResult == Window.OK) {
313             Object JavaDoc[] result= dialog.getResult();
314             if (result == null) {
315                 notifyResult(false);
316                 return;
317             }
318             fSort= dialog.getSortOrder();
319             fSynchronized= dialog.getSynchronized();
320             fFinal= dialog.getFinal();
321             fVisibility= dialog.getVisibilityModifier();
322             fGenerateComment= dialog.getGenerateComment();
323             IField[] getterFields, setterFields, getterSetterFields;
324             if (fSort) {
325                 getterFields= getGetterFields(result, keySet);
326                 setterFields= getSetterFields(result, keySet);
327                 getterSetterFields= new IField[0];
328             } else {
329                 getterFields= getGetterOnlyFields(result, keySet);
330                 setterFields= getSetterOnlyFields(result, keySet);
331                 getterSetterFields= getGetterSetterFields(result, keySet);
332             }
333             generate(type, getterFields, setterFields, getterSetterFields, new RefactoringASTParser(AST.JLS3).parse(type.getCompilationUnit(), true), dialog.getElementPosition());
334         }
335         notifyResult(dialogResult == Window.OK);
336     }
337
338     private static class AddGetterSetterSelectionStatusValidator implements ISelectionStatusValidator {
339
340         private static int fEntries;
341
342         AddGetterSetterSelectionStatusValidator(int entries) {
343             fEntries= entries;
344         }
345
346         public IStatus validate(Object JavaDoc[] selection) {
347             // https://bugs.eclipse.org/bugs/show_bug.cgi?id=38478
348
HashSet JavaDoc map= null;
349             if ((selection != null) && (selection.length > 1)) {
350                 map= new HashSet JavaDoc(selection.length);
351             }
352
353             int count= 0;
354             for (int i= 0; i < selection.length; i++) {
355                 try {
356                     if (selection[i] instanceof GetterSetterEntry) {
357                         Object JavaDoc key= selection[i];
358                         IField getsetField= ((GetterSetterEntry) selection[i]).field;
359                         if (((GetterSetterEntry) selection[i]).isGetter) {
360                             if (!map.add(GetterSetterUtil.getGetterName(getsetField, null)))
361                                 return new StatusInfo(IStatus.WARNING, ActionMessages.AddGetterSetterAction_error_duplicate_methods);
362                         } else {
363                             key= createSignatureKey(GetterSetterUtil.getSetterName(getsetField, null), getsetField);
364                             if (!map.add(key))
365                                 return new StatusInfo(IStatus.WARNING, ActionMessages.AddGetterSetterAction_error_duplicate_methods);
366                         }
367                         count++;
368                     }
369                 } catch (JavaModelException e) {
370                 }
371             }
372
373             if (count == 0)
374                 return new StatusInfo(IStatus.ERROR, ""); //$NON-NLS-1$
375
String JavaDoc message= Messages.format(ActionMessages.AddGetterSetterAction_methods_selected,
376                     new Object JavaDoc[] { String.valueOf(count), String.valueOf(fEntries)});
377             return new StatusInfo(IStatus.INFO, message);
378         }
379     }
380
381     /**
382      * Creates a key used in hash maps for a method signature
383      * (gettersettername+arguments(fqn)).
384      */

385     private static String JavaDoc createSignatureKey(String JavaDoc methodName, IField field) throws JavaModelException {
386         StringBuffer JavaDoc buffer= new StringBuffer JavaDoc();
387         buffer.append(methodName);
388         String JavaDoc fieldType= field.getTypeSignature();
389         String JavaDoc signature= Signature.getSimpleName(Signature.toString(fieldType));
390         buffer.append("#"); //$NON-NLS-1$
391
buffer.append(signature);
392
393         return buffer.toString();
394     }
395
396     private static ISelectionStatusValidator createValidator(int entries) {
397         AddGetterSetterSelectionStatusValidator validator= new AddGetterSetterSelectionStatusValidator(entries);
398         return validator;
399     }
400
401     // returns a list of fields with setter entries checked
402
private static IField[] getSetterFields(Object JavaDoc[] result, Set JavaDoc set) {
403         List JavaDoc list= new ArrayList JavaDoc(0);
404         Object JavaDoc each= null;
405         GetterSetterEntry entry= null;
406         for (int i= 0; i < result.length; i++) {
407             each= result[i];
408             if ((each instanceof GetterSetterEntry)) {
409                 entry= (GetterSetterEntry) each;
410                 if (!entry.isGetter) {
411                     list.add(entry.field);
412                 }
413             }
414         }
415         list= reorderFields(list, set);
416         return (IField[]) list.toArray(new IField[list.size()]);
417     }
418
419     // returns a list of fields with getter entries checked
420
private static IField[] getGetterFields(Object JavaDoc[] result, Set JavaDoc set) {
421         List JavaDoc list= new ArrayList JavaDoc(0);
422         Object JavaDoc each= null;
423         GetterSetterEntry entry= null;
424         for (int i= 0; i < result.length; i++) {
425             each= result[i];
426             if ((each instanceof GetterSetterEntry)) {
427                 entry= (GetterSetterEntry) each;
428                 if (entry.isGetter) {
429                     list.add(entry.field);
430                 }
431             }
432         }
433         list= reorderFields(list, set);
434         return (IField[]) list.toArray(new IField[list.size()]);
435     }
436
437     // returns a list of fields with only getter entries checked
438
private static IField[] getGetterOnlyFields(Object JavaDoc[] result, Set JavaDoc set) {
439         List JavaDoc list= new ArrayList JavaDoc(0);
440         Object JavaDoc each= null;
441         GetterSetterEntry entry= null;
442         boolean getterSet= false;
443         for (int i= 0; i < result.length; i++) {
444             each= result[i];
445             if ((each instanceof GetterSetterEntry)) {
446                 entry= (GetterSetterEntry) each;
447                 if (entry.isGetter) {
448                     list.add(entry.field);
449                     getterSet= true;
450                 }
451                 if ((!entry.isGetter) && (getterSet == true)) {
452                     list.remove(entry.field);
453                     getterSet= false;
454                 }
455             } else
456                 getterSet= false;
457         }
458         list= reorderFields(list, set);
459         return (IField[]) list.toArray(new IField[list.size()]);
460     }
461
462     // returns a list of fields with only setter entries checked
463
private static IField[] getSetterOnlyFields(Object JavaDoc[] result, Set JavaDoc set) {
464         List JavaDoc list= new ArrayList JavaDoc(0);
465         Object JavaDoc each= null;
466         GetterSetterEntry entry= null;
467         boolean getterSet= false;
468         for (int i= 0; i < result.length; i++) {
469             each= result[i];
470             if ((each instanceof GetterSetterEntry)) {
471                 entry= (GetterSetterEntry) each;
472                 if (entry.isGetter) {
473                     getterSet= true;
474                 }
475                 if ((!entry.isGetter) && (getterSet != true)) {
476                     list.add(entry.field);
477                     getterSet= false;
478                 }
479             } else
480                 getterSet= false;
481         }
482         list= reorderFields(list, set);
483         return (IField[]) list.toArray(new IField[list.size()]);
484     }
485
486     // returns a list of fields with both entries checked
487
private static IField[] getGetterSetterFields(Object JavaDoc[] result, Set JavaDoc set) {
488         List JavaDoc list= new ArrayList JavaDoc(0);
489         Object JavaDoc each= null;
490         GetterSetterEntry entry= null;
491         boolean getterSet= false;
492         for (int i= 0; i < result.length; i++) {
493             each= result[i];
494             if ((each instanceof GetterSetterEntry)) {
495                 entry= (GetterSetterEntry) each;
496                 if (entry.isGetter) {
497                     getterSet= true;
498                 }
499                 if ((!entry.isGetter) && (getterSet == true)) {
500                     list.add(entry.field);
501                     getterSet= false;
502                 }
503             } else
504                 getterSet= false;
505         }
506         list= reorderFields(list, set);
507         return (IField[]) list.toArray(new IField[list.size()]);
508     }
509
510     private static List JavaDoc reorderFields(List JavaDoc collection, Set JavaDoc set) {
511         final List JavaDoc list= new ArrayList JavaDoc(collection.size());
512         for (final Iterator JavaDoc iterator= set.iterator(); iterator.hasNext();) {
513             final IField field= (IField) iterator.next();
514             if (collection.contains(field))
515                 list.add(field);
516         }
517         return list;
518     }
519
520     private void generate(IType type, IField[] getterFields, IField[] setterFields, IField[] getterSetterFields, CompilationUnit unit, IJavaElement elementPosition) throws CoreException {
521         if (getterFields.length == 0 && setterFields.length == 0 && getterSetterFields.length == 0)
522             return;
523
524         ICompilationUnit cu= null;
525         if (getterFields.length != 0)
526             cu= getterFields[0].getCompilationUnit();
527         else if (setterFields.length != 0)
528             cu= setterFields[0].getCompilationUnit();
529         else
530             cu= getterSetterFields[0].getCompilationUnit();
531         // open the editor, forces the creation of a working copy
532
run(cu, type, getterFields, setterFields, getterSetterFields, JavaUI.openInEditor(cu), unit, elementPosition);
533     }
534
535     // ---- Java Editor --------------------------------------------------------------
536

537     /*
538      * (non-Javadoc) Method declared on SelectionDispatchAction
539      */

540     public void selectionChanged(ITextSelection selection) {
541     }
542
543     /*
544      * (non-Javadoc) Method declared on SelectionDispatchAction
545      */

546     public void run(ITextSelection selection) {
547         try {
548             if (!ActionUtil.isProcessable(fEditor)) {
549                 notifyResult(false);
550                 return;
551             }
552
553             IJavaElement[] elements= SelectionConverter.codeResolveForked(fEditor, true);
554             if (elements.length == 1 && (elements[0] instanceof IField)) {
555                 IField field= (IField) elements[0];
556                 run(field.getDeclaringType(), new IField[] { field}, true);
557                 return;
558             }
559             IJavaElement element= SelectionConverter.getElementAtOffset(fEditor);
560
561             if (element != null) {
562                 IType type= (IType) element.getAncestor(IJavaElement.TYPE);
563                 if (type != null) {
564                     if (type.getFields().length > 0) {
565                         run(type, new IField[0], true);
566                         return;
567                     }
568                 }
569             }
570             MessageDialog.openInformation(getShell(), DIALOG_TITLE, ActionMessages.AddGetterSetterAction_not_applicable);
571         } catch (CoreException e) {
572             ExceptionHandler.handle(e, getShell(), DIALOG_TITLE, ActionMessages.AddGetterSetterAction_error_actionfailed);
573         } catch (InvocationTargetException JavaDoc e) {
574             ExceptionHandler.handle(e, getShell(), DIALOG_TITLE, ActionMessages.AddGetterSetterAction_error_actionfailed);
575         } catch (InterruptedException JavaDoc e) {
576             // cancelled
577
}
578     }
579
580     // ---- Helpers -------------------------------------------------------------------
581

582     private void run(ICompilationUnit cu, IType type, IField[] getterFields, IField[] setterFields, IField[] getterSetterFields, IEditorPart editor, CompilationUnit unit, IJavaElement elementPosition) {
583         IRewriteTarget target= (IRewriteTarget) editor.getAdapter(IRewriteTarget.class);
584         if (target != null) {
585             target.beginCompoundChange();
586         }
587         try {
588             CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(cu.getJavaProject());
589             settings.createComments= fGenerateComment;
590
591             AddGetterSetterOperation op= new AddGetterSetterOperation(type, getterFields, setterFields, getterSetterFields, unit, skipReplaceQuery(), elementPosition, settings, true, false);
592             setOperationStatusFields(op);
593
594             IRunnableContext context= JavaPlugin.getActiveWorkbenchWindow();
595             if (context == null) {
596                 context= new BusyIndicatorRunnableContext();
597             }
598
599             PlatformUI.getWorkbench().getProgressService().runInUI(context, new WorkbenchRunnableAdapter(op, op.getSchedulingRule()), op.getSchedulingRule());
600
601         } catch (InvocationTargetException JavaDoc e) {
602             String JavaDoc message= ActionMessages.AddGetterSetterAction_error_actionfailed;
603             ExceptionHandler.handle(e, getShell(), DIALOG_TITLE, message);
604         } catch (InterruptedException JavaDoc e) {
605             // operation canceled
606
} finally {
607             if (target != null) {
608                 target.endCompoundChange();
609             }
610         }
611     }
612
613     private void setOperationStatusFields(AddGetterSetterOperation op) {
614         // Set the status fields corresponding to the visibility and modifiers set
615
int flags= fVisibility;
616         if (fSynchronized) {
617             flags|= Flags.AccSynchronized;
618         }
619         if (fFinal) {
620             flags|= Flags.AccFinal;
621         }
622         op.setSort(fSort);
623         op.setVisibility(flags);
624     }
625
626     private IRequestQuery skipReplaceQuery() {
627         return new IRequestQuery() {
628
629             public int doQuery(IMember method) {
630                 int[] returnCodes= { IRequestQuery.YES, IRequestQuery.NO, IRequestQuery.YES_ALL, IRequestQuery.CANCEL};
631                 String JavaDoc skipLabel= ActionMessages.AddGetterSetterAction_SkipExistingDialog_skip_label;
632                 String JavaDoc replaceLabel= ActionMessages.AddGetterSetterAction_SkipExistingDialog_replace_label;
633                 String JavaDoc skipAllLabel= ActionMessages.AddGetterSetterAction_SkipExistingDialog_skipAll_label;
634                 String JavaDoc[] options= { skipLabel, replaceLabel, skipAllLabel, IDialogConstants.CANCEL_LABEL};
635                 String JavaDoc methodName= JavaElementLabels.getElementLabel(method, JavaElementLabels.M_PARAMETER_TYPES);
636                 String JavaDoc formattedMessage= Messages.format(ActionMessages.AddGetterSetterAction_SkipExistingDialog_message, methodName);
637                 return showQueryDialog(formattedMessage, options, returnCodes);
638             }
639         };
640     }
641
642     private int showQueryDialog(final String JavaDoc message, final String JavaDoc[] buttonLabels, int[] returnCodes) {
643         final Shell shell= getShell();
644         if (shell == null) {
645             JavaPlugin.logErrorMessage("AddGetterSetterAction.showQueryDialog: No active shell found"); //$NON-NLS-1$
646
return IRequestQuery.CANCEL;
647         }
648         final int[] result= { Window.CANCEL};
649         shell.getDisplay().syncExec(new Runnable JavaDoc() {
650
651             public void run() {
652                 String JavaDoc title= ActionMessages.AddGetterSetterAction_QueryDialog_title;
653                 MessageDialog dialog= new MessageDialog(shell, title, null, message, MessageDialog.QUESTION, buttonLabels, 0);
654                 result[0]= dialog.open();
655             }
656         });
657         int returnVal= result[0];
658         return returnVal < 0 ? IRequestQuery.CANCEL : returnCodes[returnVal];
659     }
660
661     /*
662      * Returns fields in the selection or <code>null</code> if the selection is empty or
663      * not valid.
664      */

665     private IField[] getSelectedFields(IStructuredSelection selection) {
666         List JavaDoc elements= selection.toList();
667         int nElements= elements.size();
668         if (nElements > 0) {
669             IField[] res= new IField[nElements];
670             ICompilationUnit cu= null;
671             for (int i= 0; i < nElements; i++) {
672                 Object JavaDoc curr= elements.get(i);
673                 if (curr instanceof IField) {
674                     IField fld= (IField) curr;
675
676                     if (i == 0) {
677                         // remember the cu of the first element
678
cu= fld.getCompilationUnit();
679                         if (cu == null) {
680                             return null;
681                         }
682                     } else if (!cu.equals(fld.getCompilationUnit())) {
683                         // all fields must be in the same CU
684
return null;
685                     }
686                     try {
687                         final IType declaringType= fld.getDeclaringType();
688                         if (declaringType.isInterface())
689                             return null;
690                     } catch (JavaModelException e) {
691                         JavaPlugin.log(e);
692                         return null;
693                     }
694
695                     res[i]= fld;
696                 } else {
697                     return null;
698                 }
699             }
700             return res;
701         }
702         return null;
703     }
704
705     private static class AddGetterSetterLabelProvider extends JavaElementLabelProvider {
706
707         AddGetterSetterLabelProvider() {
708         }
709
710         /*
711          * @see ILabelProvider#getText(Object)
712          */

713         public String JavaDoc getText(Object JavaDoc element) {
714             if (element instanceof GetterSetterEntry) {
715                 GetterSetterEntry entry= (GetterSetterEntry) element;
716                 try {
717                     if (entry.isGetter) {
718                         return GetterSetterUtil.getGetterName(entry.field, null) + "()"; //$NON-NLS-1$
719
} else {
720                         return GetterSetterUtil.getSetterName(entry.field, null) + '(' + Signature.getSimpleName(Signature.toString(entry.field.getTypeSignature())) + ')';
721                     }
722                 } catch (JavaModelException e) {
723                     return ""; //$NON-NLS-1$
724
}
725             }
726             return super.getText(element);
727         }
728
729         /*
730          * @see ILabelProvider#getImage(Object)
731          */

732         public Image getImage(Object JavaDoc element) {
733             if (element instanceof GetterSetterEntry) {
734                 int flags= 0;
735                 try {
736                     flags= ((GetterSetterEntry) element).field.getFlags();
737                 } catch (JavaModelException e) {
738                     JavaPlugin.log(e);
739                 }
740                 ImageDescriptor desc= JavaElementImageProvider.getFieldImageDescriptor(false, Flags.AccPublic);
741                 int adornmentFlags= Flags.isStatic(flags) ? JavaElementImageDescriptor.STATIC : 0;
742                 desc= new JavaElementImageDescriptor(desc, adornmentFlags, JavaElementImageProvider.BIG_SIZE);
743                 return JavaPlugin.getImageDescriptorRegistry().get(desc);
744             }
745             return super.getImage(element);
746         }
747     }
748
749     /**
750      * @return map IField -> GetterSetterEntry[]
751      */

752     private Map JavaDoc createGetterSetterMapping(IType type) throws JavaModelException {
753         IField[] fields= type.getFields();
754         Map JavaDoc result= new LinkedHashMap JavaDoc();
755         for (int i= 0; i < fields.length; i++) {
756             IField field= fields[i];
757             int flags= field.getFlags();
758             if (!Flags.isEnum(flags)) {
759                 List JavaDoc l= new ArrayList JavaDoc(2);
760                 if (GetterSetterUtil.getGetter(field) == null) {
761                     l.add(new GetterSetterEntry(field, true, Flags.isFinal(flags)));
762                     incNumEntries();
763                 }
764
765                 if (GetterSetterUtil.getSetter(field) == null) {
766                     l.add(new GetterSetterEntry(field, false, Flags.isFinal(flags)));
767                     incNumEntries();
768                 }
769
770                 if (!l.isEmpty())
771                     result.put(field, l.toArray(new GetterSetterEntry[l.size()]));
772             }
773         }
774         return result;
775     }
776
777     private static class AddGetterSetterContentProvider implements ITreeContentProvider {
778
779         private static final Object JavaDoc[] EMPTY= new Object JavaDoc[0];
780
781         private Viewer fViewer;
782
783         private Map JavaDoc fGetterSetterEntries;
784
785         public AddGetterSetterContentProvider(Map JavaDoc entries) {
786             fGetterSetterEntries= entries;
787         }
788
789         /*
790          * @see IContentProvider#inputChanged(Viewer, Object, Object)
791          */

792         public void inputChanged(Viewer viewer, Object JavaDoc oldInput, Object JavaDoc newInput) {
793             fViewer= viewer;
794         }
795
796         public Viewer getViewer() {
797             return fViewer;
798         }
799             
800         /*
801          * @see ITreeContentProvider#getChildren(Object)
802          */

803         public Object JavaDoc[] getChildren(Object JavaDoc parentElement) {
804             if (parentElement instanceof IField)
805                 return (Object JavaDoc[]) fGetterSetterEntries.get(parentElement);
806             return EMPTY;
807         }
808
809         /*
810          * @see ITreeContentProvider#getParent(Object)
811          */

812         public Object JavaDoc getParent(Object JavaDoc element) {
813             if (element instanceof IMember)
814                 return ((IMember) element).getDeclaringType();
815             if (element instanceof GetterSetterEntry)
816                 return ((GetterSetterEntry) element).field;
817             return null;
818         }
819
820         /*
821          * @see ITreeContentProvider#hasChildren(Object)
822          */

823         public boolean hasChildren(Object JavaDoc element) {
824             return getChildren(element).length > 0;
825         }
826
827         /*
828          * @see IStructuredContentProvider#getElements(Object)
829          */

830         public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
831             return fGetterSetterEntries.keySet().toArray();
832         }
833
834         /*
835          * @see IContentProvider#dispose()
836          */

837         public void dispose() {
838             fGetterSetterEntries.clear();
839             fGetterSetterEntries= null;
840         }
841     }
842     
843     private static class SettersForFinalFieldsFilter extends ViewerFilter {
844         
845         private final AddGetterSetterContentProvider fContentProvider;
846
847         public SettersForFinalFieldsFilter(AddGetterSetterContentProvider contentProvider) {
848             fContentProvider= contentProvider;
849         }
850
851         public boolean select(Viewer viewer, Object JavaDoc parentElement, Object JavaDoc element) {
852             if (element instanceof GetterSetterEntry) {
853                 GetterSetterEntry getterSetterEntry= (GetterSetterEntry) element;
854                 return getterSetterEntry.isGetter || !getterSetterEntry.isFinal;
855             } else if (element instanceof IField) {
856                 Object JavaDoc[] children= fContentProvider.getChildren(element);
857                 for (int i= 0; i < children.length; i++) {
858                     GetterSetterEntry curr= (GetterSetterEntry) children[i];
859                     if (curr.isGetter || !curr.isFinal) {
860                         return true;
861                     }
862                 }
863                 return false;
864             }
865             return true;
866         }
867     }
868     
869
870     private static class GetterSetterTreeSelectionDialog extends SourceActionDialog {
871
872         private AddGetterSetterContentProvider fContentProvider;
873
874         private static final int SELECT_GETTERS_ID= IDialogConstants.CLIENT_ID + 1;
875         private static final int SELECT_SETTERS_ID= IDialogConstants.CLIENT_ID + 2;
876         private final String JavaDoc SETTINGS_SECTION= "AddGetterSetterDialog"; //$NON-NLS-1$
877
private final String JavaDoc SORT_ORDER= "SortOrdering"; //$NON-NLS-1$
878
private final String JavaDoc ALLOW_SETTERS_FOR_FINALS= "RemoveFinal"; //$NON-NLS-1$
879

880         private IDialogSettings fSettings;
881         private SettersForFinalFieldsFilter fSettersForFinalFieldsFilter;
882
883         private boolean fSortOrder;
884         private boolean fAllowSettersForFinals;
885         
886         private ArrayList JavaDoc fPreviousSelectedFinals;
887
888
889         public GetterSetterTreeSelectionDialog(Shell parent, ILabelProvider labelProvider, AddGetterSetterContentProvider contentProvider, CompilationUnitEditor editor, IType type) throws JavaModelException {
890             super(parent, labelProvider, contentProvider, editor, type, false);
891             fContentProvider= contentProvider;
892             fPreviousSelectedFinals= new ArrayList JavaDoc();
893
894             // http://bugs.eclipse.org/bugs/show_bug.cgi?id=19253
895
IDialogSettings dialogSettings= JavaPlugin.getDefault().getDialogSettings();
896             fSettings= dialogSettings.getSection(SETTINGS_SECTION);
897             if (fSettings == null) {
898                 fSettings= dialogSettings.addNewSection(SETTINGS_SECTION);
899                 fSettings.put(SORT_ORDER, false);
900                 fSettings.put(ALLOW_SETTERS_FOR_FINALS, false);
901             }
902
903             fSortOrder= fSettings.getBoolean(SORT_ORDER);
904             fAllowSettersForFinals= fSettings.getBoolean(ALLOW_SETTERS_FOR_FINALS);
905             
906             fSettersForFinalFieldsFilter= new SettersForFinalFieldsFilter(contentProvider);
907         }
908
909         public boolean getSortOrder() {
910             return fSortOrder;
911         }
912
913         public void setSortOrder(boolean sort) {
914             if (fSortOrder != sort) {
915                 fSortOrder= sort;
916                 fSettings.put(SORT_ORDER, sort);
917                 if (getTreeViewer() != null) {
918                     getTreeViewer().refresh();
919                 }
920             }
921         }
922         
923         private boolean allowSettersForFinals() {
924             return fAllowSettersForFinals;
925         }
926         
927         public void allowSettersForFinals(boolean allowSettersForFinals) {
928             if (fAllowSettersForFinals != allowSettersForFinals) {
929                 fAllowSettersForFinals= allowSettersForFinals;
930                 fSettings.put(ALLOW_SETTERS_FOR_FINALS, allowSettersForFinals);
931                 CheckboxTreeViewer treeViewer= getTreeViewer();
932                 if (treeViewer != null) {
933                     ArrayList JavaDoc newChecked= new ArrayList JavaDoc();
934                     if (allowSettersForFinals) {
935                         newChecked.addAll(fPreviousSelectedFinals);
936                     }
937                     fPreviousSelectedFinals.clear();
938                     Object JavaDoc[] checkedElements= treeViewer.getCheckedElements();
939                     for (int i= 0; i < checkedElements.length; i++) {
940                         if (checkedElements[i] instanceof GetterSetterEntry) {
941                             GetterSetterEntry entry= (GetterSetterEntry) checkedElements[i];
942                             if (allowSettersForFinals || entry.isGetter || !entry.isFinal) {
943                                 newChecked.add(entry);
944                             } else {
945                                 fPreviousSelectedFinals.add(entry);
946                             }
947                         }
948                     }
949                     if (allowSettersForFinals) {
950                         treeViewer.removeFilter(fSettersForFinalFieldsFilter);
951                     } else {
952                         treeViewer.addFilter(fSettersForFinalFieldsFilter);
953                     }
954                     treeViewer.setCheckedElements(newChecked.toArray());
955                 }
956                 updateOKStatus();
957             }
958         }
959         
960         /* (non-Javadoc)
961          * @see org.eclipse.ui.dialogs.CheckedTreeSelectionDialog#createTreeViewer(org.eclipse.swt.widgets.Composite)
962          */

963         protected CheckboxTreeViewer createTreeViewer(Composite parent) {
964              CheckboxTreeViewer treeViewer= super.createTreeViewer(parent);
965              if (!fAllowSettersForFinals) {
966                  treeViewer.addFilter(fSettersForFinalFieldsFilter);
967              }
968             return treeViewer;
969         }
970
971         protected void configureShell(Shell shell) {
972             super.configureShell(shell);
973             PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IJavaHelpContextIds.ADD_GETTER_SETTER_SELECTION_DIALOG);
974         }
975         
976         private void createGetterSetterButtons(Composite buttonComposite) {
977             createButton(buttonComposite, SELECT_GETTERS_ID, ActionMessages.GetterSetterTreeSelectionDialog_select_getters, false);
978             createButton(buttonComposite, SELECT_SETTERS_ID, ActionMessages.GetterSetterTreeSelectionDialog_select_setters, false);
979         }
980
981         protected void buttonPressed(int buttonId) {
982             super.buttonPressed(buttonId);
983             switch (buttonId) {
984                 case SELECT_GETTERS_ID: {
985                     getTreeViewer().setCheckedElements(getGetterSetterElements(true));
986                     updateOKStatus();
987                     break;
988                 }
989                 case SELECT_SETTERS_ID: {
990                     getTreeViewer().setCheckedElements(getGetterSetterElements(false));
991                     updateOKStatus();
992                     break;
993                 }
994             }
995         }
996
997         protected Composite createInsertPositionCombo(Composite composite) {
998             Button addRemoveFinalCheckbox= addAllowSettersForFinalslCheckbox(composite);
999             addRemoveFinalCheckbox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
1000            
1001            Composite entryComposite= super.createInsertPositionCombo(composite);
1002            addSortOrder(entryComposite);
1003            addVisibilityAndModifiersChoices(entryComposite);
1004            return entryComposite;
1005        }
1006
1007        private Button addAllowSettersForFinalslCheckbox(Composite entryComposite) {
1008            Button allowSettersForFinalsButton= new Button(entryComposite, SWT.CHECK);
1009            allowSettersForFinalsButton.setText(ActionMessages.AddGetterSetterAction_allow_setters_for_finals_description);
1010
1011            allowSettersForFinalsButton.addSelectionListener(new SelectionListener() {
1012                public void widgetSelected(SelectionEvent e) {
1013                    boolean isSelected= (((Button) e.widget).getSelection());
1014                    allowSettersForFinals(isSelected);
1015                }
1016
1017                public void widgetDefaultSelected(SelectionEvent e) {
1018                    widgetSelected(e);
1019                }
1020            });
1021            allowSettersForFinalsButton.setSelection(allowSettersForFinals());
1022            return allowSettersForFinalsButton;
1023        }
1024
1025        private Composite addSortOrder(Composite composite) {
1026            Label label= new Label(composite, SWT.NONE);
1027            label.setText(ActionMessages.GetterSetterTreeSelectionDialog_sort_label);
1028            GridData gd= new GridData(GridData.FILL_BOTH);
1029            label.setLayoutData(gd);
1030
1031            final Combo combo= new Combo(composite, SWT.READ_ONLY);
1032            combo.setItems(new String JavaDoc[] { ActionMessages.GetterSetterTreeSelectionDialog_alpha_pair_sort,
1033                    ActionMessages.GetterSetterTreeSelectionDialog_alpha_method_sort});
1034            final int methodIndex= 1; // Hard-coded. Change this if the
1035
// list gets more complicated.
1036
// http://bugs.eclipse.org/bugs/show_bug.cgi?id=38400
1037
int sort= getSortOrder() ? 1 : 0;
1038            combo.setText(combo.getItem(sort));
1039            gd= new GridData(GridData.FILL_BOTH);
1040            combo.setLayoutData(gd);
1041            combo.addSelectionListener(new SelectionAdapter() {
1042
1043                public void widgetSelected(SelectionEvent e) {
1044                    setSortOrder(combo.getSelectionIndex() == methodIndex);
1045                }
1046            });
1047            return composite;
1048        }
1049
1050        private Object JavaDoc[] getGetterSetterElements(boolean isGetter) {
1051            Object JavaDoc[] allFields= fContentProvider.getElements(null);
1052            Set JavaDoc result= new HashSet JavaDoc();
1053            for (int i= 0; i < allFields.length; i++) {
1054                IField field= (IField) allFields[i];
1055                GetterSetterEntry[] entries= getEntries(field);
1056                for (int j= 0; j < entries.length; j++) {
1057                    AddGetterSetterAction.GetterSetterEntry entry= entries[j];
1058                    if (entry.isGetter == isGetter)
1059                        result.add(entry);
1060                }
1061            }
1062            return result.toArray();
1063        }
1064
1065        private GetterSetterEntry[] getEntries(IField field) {
1066            List JavaDoc result= Arrays.asList(fContentProvider.getChildren(field));
1067            return (GetterSetterEntry[]) result.toArray(new GetterSetterEntry[result.size()]);
1068        }
1069
1070        protected Composite createSelectionButtons(Composite composite) {
1071            Composite buttonComposite= super.createSelectionButtons(composite);
1072
1073            GridLayout layout= new GridLayout();
1074            buttonComposite.setLayout(layout);
1075
1076            createGetterSetterButtons(buttonComposite);
1077
1078            layout.marginHeight= 0;
1079            layout.marginWidth= 0;
1080            layout.numColumns= 1;
1081
1082            return buttonComposite;
1083        }
1084
1085        /*
1086         * @see org.eclipse.jdt.internal.ui.dialogs.SourceActionDialog#createLinkControl(org.eclipse.swt.widgets.Composite)
1087         */

1088        protected Control createLinkControl(Composite composite) {
1089            Link link= new Link(composite, SWT.WRAP);
1090            link.setText(ActionMessages.AddGetterSetterAction_template_link_description);
1091            link.addSelectionListener(new SelectionAdapter() {
1092                public void widgetSelected(SelectionEvent e) {
1093                    openCodeTempatePage(CodeTemplateContextType.GETTERCOMMENT_ID);
1094                }
1095            });
1096            link.setToolTipText(ActionMessages.AddGetterSetterAction_template_link_tooltip);
1097            
1098            GridData gridData= new GridData(SWT.FILL, SWT.BEGINNING, true, false);
1099            gridData.widthHint= convertWidthInCharsToPixels(40); // only expand further if anyone else requires it
1100
link.setLayoutData(gridData);
1101            return link;
1102        }
1103    }
1104
1105    private static class GetterSetterEntry {
1106        public final IField field;
1107        public final boolean isGetter;
1108        public final boolean isFinal;
1109
1110        GetterSetterEntry(IField field, boolean isGetterEntry, boolean isFinal) {
1111            this.field= field;
1112            this.isGetter= isGetterEntry;
1113            this.isFinal= isFinal;
1114        }
1115    }
1116}
1117
Popular Tags