KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > codemanipulation > SortMembersOperation


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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  *******************************************************************************/

11 package org.eclipse.jdt.internal.corext.codemanipulation;
12
13 import com.ibm.icu.text.Collator;
14
15 import java.util.Comparator JavaDoc;
16 import java.util.List JavaDoc;
17
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IProgressMonitor;
20 import org.eclipse.core.runtime.jobs.ISchedulingRule;
21
22 import org.eclipse.core.resources.IWorkspaceRunnable;
23 import org.eclipse.core.resources.ResourcesPlugin;
24
25 import org.eclipse.jdt.core.ICompilationUnit;
26 import org.eclipse.jdt.core.dom.AST;
27 import org.eclipse.jdt.core.dom.ASTNode;
28 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
29 import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
30 import org.eclipse.jdt.core.dom.BodyDeclaration;
31 import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
32 import org.eclipse.jdt.core.dom.FieldDeclaration;
33 import org.eclipse.jdt.core.dom.Initializer;
34 import org.eclipse.jdt.core.dom.MethodDeclaration;
35 import org.eclipse.jdt.core.dom.Modifier;
36 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
37 import org.eclipse.jdt.core.dom.Type;
38 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
39 import org.eclipse.jdt.core.util.CompilationUnitSorter;
40
41 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
42 import org.eclipse.jdt.internal.corext.util.JdtFlags;
43
44 import org.eclipse.jdt.internal.ui.JavaPlugin;
45 import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache;
46
47 /**
48  * Orders members is a compilation unit. A working copy must be passed.
49  */

50 public class SortMembersOperation implements IWorkspaceRunnable {
51
52
53     /**
54      * Default comparator for body declarations.
55      */

56     public static class DefaultJavaElementComparator implements Comparator JavaDoc {
57
58         private final Collator fCollator;
59         private final MembersOrderPreferenceCache fMemberOrderCache;
60         private final boolean fDoNotSortFields;
61
62         public DefaultJavaElementComparator(boolean doNotSortFields) {
63             fDoNotSortFields= doNotSortFields;
64             fCollator= Collator.getInstance();
65             fMemberOrderCache= JavaPlugin.getDefault().getMemberOrderPreferenceCache();
66         }
67
68         private int category(BodyDeclaration bodyDeclaration) {
69             switch (bodyDeclaration.getNodeType()) {
70                 case ASTNode.METHOD_DECLARATION:
71                     {
72                         MethodDeclaration method= (MethodDeclaration) bodyDeclaration;
73                         if (method.isConstructor()) {
74                             return getMemberCategory(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX);
75                         }
76                         int flags= method.getModifiers();
77                         if (Modifier.isStatic(flags))
78                             return getMemberCategory(MembersOrderPreferenceCache.STATIC_METHODS_INDEX);
79                         else
80                             return getMemberCategory(MembersOrderPreferenceCache.METHOD_INDEX);
81                     }
82                 case ASTNode.FIELD_DECLARATION :
83                     {
84                         int flags= ((FieldDeclaration) bodyDeclaration).getModifiers();
85                         if (Modifier.isStatic(flags))
86                             return getMemberCategory(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX);
87                         else
88                             return getMemberCategory(MembersOrderPreferenceCache.FIELDS_INDEX);
89                     }
90                 case ASTNode.INITIALIZER :
91                     {
92                         int flags= ((Initializer) bodyDeclaration).getModifiers();
93                         if (Modifier.isStatic(flags))
94                             return getMemberCategory(MembersOrderPreferenceCache.STATIC_INIT_INDEX);
95                         else
96                             return getMemberCategory(MembersOrderPreferenceCache.INIT_INDEX);
97                     }
98                 case ASTNode.TYPE_DECLARATION :
99                 case ASTNode.ENUM_DECLARATION :
100                 case ASTNode.ANNOTATION_TYPE_DECLARATION :
101                     return getMemberCategory(MembersOrderPreferenceCache.TYPE_INDEX);
102                 case ASTNode.ENUM_CONSTANT_DECLARATION :
103                     return getMemberCategory(MembersOrderPreferenceCache.ENUM_CONSTANTS_INDEX);
104                 case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION:
105                     return getMemberCategory(MembersOrderPreferenceCache.METHOD_INDEX); // reusing the method index
106

107             }
108             return 0; // should never happen
109
}
110
111         private int getMemberCategory(int kind) {
112             return fMemberOrderCache.getCategoryIndex(kind);
113         }
114
115         /**
116          * This comparator follows the contract defined in CompilationUnitSorter.sort.
117          * @see Comparator#compare(java.lang.Object, java.lang.Object)
118          * @see CompilationUnitSorter#sort(int, org.eclipse.jdt.core.ICompilationUnit, int[], java.util.Comparator, int, org.eclipse.core.runtime.IProgressMonitor)
119          */

120         public int compare(Object JavaDoc e1, Object JavaDoc e2) {
121             BodyDeclaration bodyDeclaration1= (BodyDeclaration) e1;
122             BodyDeclaration bodyDeclaration2= (BodyDeclaration) e2;
123             int cat1= category(bodyDeclaration1);
124             int cat2= category(bodyDeclaration2);
125
126             if (cat1 != cat2) {
127                 return cat1 - cat2;
128             }
129             
130             if (fMemberOrderCache.isSortByVisibility()) {
131                 int flags1= JdtFlags.getVisibilityCode(bodyDeclaration1);
132                 int flags2= JdtFlags.getVisibilityCode(bodyDeclaration2);
133                 int vis= fMemberOrderCache.getVisibilityIndex(flags1) - fMemberOrderCache.getVisibilityIndex(flags2);
134                 if (vis != 0) {
135                     return vis;
136                 }
137             }
138
139             switch (bodyDeclaration1.getNodeType()) {
140                 case ASTNode.METHOD_DECLARATION :
141                     {
142                         MethodDeclaration method1= (MethodDeclaration) bodyDeclaration1;
143                         MethodDeclaration method2= (MethodDeclaration) bodyDeclaration2;
144
145                         if (fMemberOrderCache.isSortByVisibility()) {
146                             int vis= fMemberOrderCache.getVisibilityIndex(method1.getModifiers()) - fMemberOrderCache.getVisibilityIndex(method2.getModifiers());
147                             if (vis != 0) {
148                                 return vis;
149                             }
150                         }
151                         
152                         String JavaDoc name1= method1.getName().getIdentifier();
153                         String JavaDoc name2= method2.getName().getIdentifier();
154
155                         // method declarations (constructors) are sorted by name
156
int cmp= this.fCollator.compare(name1, name2);
157                         if (cmp != 0) {
158                             return cmp;
159                         }
160
161                         // if names equal, sort by parameter types
162
List JavaDoc parameters1= method1.parameters();
163                         List JavaDoc parameters2= method2.parameters();
164                         int length1= parameters1.size();
165                         int length2= parameters2.size();
166
167                         int len= Math.min(length1, length2);
168                         for (int i= 0; i < len; i++) {
169                             SingleVariableDeclaration param1= (SingleVariableDeclaration) parameters1.get(i);
170                             SingleVariableDeclaration param2= (SingleVariableDeclaration) parameters2.get(i);
171                             cmp= this.fCollator.compare(buildSignature(param1.getType()), buildSignature(param2.getType()));
172                             if (cmp != 0) {
173                                 return cmp;
174                             }
175                         }
176                         if (length1 != length2) {
177                             return length1 - length2;
178                         }
179                         return preserveRelativeOrder(bodyDeclaration1, bodyDeclaration2);
180                     }
181                 case ASTNode.FIELD_DECLARATION :
182                     {
183                         if (!fDoNotSortFields) {
184                             FieldDeclaration field1= (FieldDeclaration) bodyDeclaration1;
185                             FieldDeclaration field2= (FieldDeclaration) bodyDeclaration2;
186     
187                             String JavaDoc name1= ((VariableDeclarationFragment) field1.fragments().get(0)).getName().getIdentifier();
188                             String JavaDoc name2= ((VariableDeclarationFragment) field2.fragments().get(0)).getName().getIdentifier();
189     
190                             // field declarations are sorted by name
191
return compareNames(bodyDeclaration1, bodyDeclaration2, name1, name2);
192                         } else {
193                             return preserveRelativeOrder(bodyDeclaration1, bodyDeclaration2);
194                         }
195                     }
196                 case ASTNode.INITIALIZER :
197                     {
198                         // preserve relative order
199
return preserveRelativeOrder(bodyDeclaration1, bodyDeclaration2);
200                     }
201                 case ASTNode.TYPE_DECLARATION :
202                 case ASTNode.ENUM_DECLARATION :
203                 case ASTNode.ANNOTATION_TYPE_DECLARATION :
204                     {
205                         AbstractTypeDeclaration type1= (AbstractTypeDeclaration) bodyDeclaration1;
206                         AbstractTypeDeclaration type2= (AbstractTypeDeclaration) bodyDeclaration2;
207
208                         String JavaDoc name1= type1.getName().getIdentifier();
209                         String JavaDoc name2= type2.getName().getIdentifier();
210
211                         // typedeclarations are sorted by name
212
return compareNames(bodyDeclaration1, bodyDeclaration2, name1, name2);
213                     }
214                 case ASTNode.ENUM_CONSTANT_DECLARATION :
215                     {
216                         if (!fDoNotSortFields) {
217                             EnumConstantDeclaration decl1= (EnumConstantDeclaration) bodyDeclaration1;
218                             EnumConstantDeclaration decl2= (EnumConstantDeclaration) bodyDeclaration2;
219                             
220                             String JavaDoc name1= decl1.getName().getIdentifier();
221                             String JavaDoc name2= decl2.getName().getIdentifier();
222                             
223                             // enum constants declarations are sorted by name
224
return compareNames(bodyDeclaration1, bodyDeclaration2, name1, name2);
225                         } else {
226                             return preserveRelativeOrder(bodyDeclaration1, bodyDeclaration2);
227                         }
228                     }
229                 case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION :
230                     {
231                         AnnotationTypeMemberDeclaration decl1= (AnnotationTypeMemberDeclaration) bodyDeclaration1;
232                         AnnotationTypeMemberDeclaration decl2= (AnnotationTypeMemberDeclaration) bodyDeclaration2;
233                         
234                         String JavaDoc name1= decl1.getName().getIdentifier();
235                         String JavaDoc name2= decl2.getName().getIdentifier();
236                         
237                         // enum constants declarations are sorted by name
238
return compareNames(bodyDeclaration1, bodyDeclaration2, name1, name2);
239                     }
240             }
241             return 0;
242         }
243
244         private int preserveRelativeOrder(BodyDeclaration bodyDeclaration1, BodyDeclaration bodyDeclaration2) {
245             int value1= ((Integer JavaDoc) bodyDeclaration1.getProperty(CompilationUnitSorter.RELATIVE_ORDER)).intValue();
246             int value2= ((Integer JavaDoc) bodyDeclaration2.getProperty(CompilationUnitSorter.RELATIVE_ORDER)).intValue();
247             return value1 - value2;
248         }
249
250         private int compareNames(BodyDeclaration bodyDeclaration1, BodyDeclaration bodyDeclaration2, String JavaDoc name1, String JavaDoc name2) {
251             int cmp= this.fCollator.compare(name1, name2);
252             if (cmp != 0) {
253                 return cmp;
254             }
255             return preserveRelativeOrder(bodyDeclaration1, bodyDeclaration2);
256         }
257
258         private String JavaDoc buildSignature(Type type) {
259             return ASTNodes.asString(type);
260         }
261     }
262
263
264     private ICompilationUnit fCompilationUnit;
265     private int[] fPositions;
266     private final boolean fDoNotSortFields;
267     
268     /**
269      * Creates the operation.
270      * @param cu The working copy of a compilation unit.
271      * @param positions Positions to track or <code>null</code> if no positions
272      * should be tracked.
273      */

274     public SortMembersOperation(ICompilationUnit cu, int[] positions, boolean doNotSortFields) {
275         fCompilationUnit= cu;
276         fPositions= positions;
277         fDoNotSortFields= doNotSortFields;
278     }
279
280
281     /**
282      * Runs the operation.
283      */

284     public void run(IProgressMonitor monitor) throws CoreException {
285         CompilationUnitSorter.sort(AST.JLS3, fCompilationUnit, fPositions, new DefaultJavaElementComparator(fDoNotSortFields), 0, monitor);
286     }
287
288     /**
289      * @return Returns the scheduling rule for this operation
290      */

291     public ISchedulingRule getScheduleRule() {
292         return ResourcesPlugin.getWorkspace().getRoot();
293     }
294     
295 }
296
Popular Tags