KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > refactoring > java > plugins > PullUpRefactoringPlugin


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.refactoring.java.plugins;
20
21 import org.netbeans.modules.refactoring.api.Problem;
22 import org.netbeans.modules.refactoring.java.api.PullUpRefactoring;
23 import org.netbeans.modules.refactoring.java.plugins.JavaRefactoringPlugin;
24 import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
25
26
27 /** Plugin that implements the core functionality of Pull Up refactoring.
28  *
29  * @author Martin Matula
30  */

31 public class PullUpRefactoringPlugin extends JavaRefactoringPlugin {
32     /** Reference to the parent refactoring instance */
33     private final PullUpRefactoring refactoring;
34     
35     /** Creates a new instance of PullUpRefactoringPlugin
36      * @param refactoring Parent refactoring instance.
37      */

38     PullUpRefactoringPlugin(PullUpRefactoring refactoring) {
39         this.refactoring = refactoring;
40     }
41     
42     public Problem preCheck() {
43         throw new UnsupportedOperationException JavaDoc("Not supported yet.");
44     }
45
46     public Problem checkParameters() {
47         throw new UnsupportedOperationException JavaDoc("Not supported yet.");
48     }
49
50     public Problem fastCheckParameters() {
51         throw new UnsupportedOperationException JavaDoc("Not supported yet.");
52     }
53
54     public Problem prepare(RefactoringElementsBag refactoringElements) {
55         throw new UnsupportedOperationException JavaDoc("Not supported yet.");
56     }
57
58 // /** Checks pre-conditions of the refactoring.
59
// * @return Problems found or <code>null</code>.
60
// */
61
// public Problem preCheck() {
62
// // fire operation start on the registered progress listeners (3 steps)
63
// fireProgressListenerStart(AbstractRefactoring.PRE_CHECK, 4);
64
// try {
65
// JavaClass sourceType = refactoring.getSourceType();
66
//
67
// // check whether the element is valid
68
// Problem result = isElementAvail(sourceType);
69
// if (result != null) {
70
// // fatal error -> don't continue with further checks
71
// return result;
72
// }
73
// if (!CheckUtils.isElementInOpenProject(sourceType)) {
74
// return new Problem(true, NbBundle.getMessage(JavaRefactoringPlugin.class, "ERR_ProjectNotOpened"));
75
// }
76
//
77
// // check whether the element is an unresolved class
78
// if (sourceType instanceof UnresolvedClass) {
79
// // fatal error -> return
80
// return new Problem(true, NbBundle.getMessage(JavaRefactoringPlugin.class, "ERR_ElementNotAvailable")); // NOI18N
81
// }
82
//
83
// // increase progress (step 1)
84
// fireProgressListenerStep();
85
//
86
// // #1 - check if the class has any supertypes from the opened project
87
// JavaClass supertypes[] = refactoring.collectSupertypes();
88
// if (supertypes.length == 0) {
89
// // fatal error -> return
90
// return new Problem(true, NbBundle.getMessage(PullUpRefactoringPlugin.class, "ERR_PullUp_NoSuperTypes")); // NOI18N
91
// }
92
//
93
// // increase progress (step 2)
94
// fireProgressListenerStep();
95
//
96
// // #2 - check if there are any members to pull up
97
// if (!hasMembers(sourceType, supertypes)) {
98
// // fatal error -> return
99
// return new Problem(true, NbBundle.getMessage(PullUpRefactoringPlugin.class, "ERR_PullUp_NoMembers")); // NOI18N
100
// }
101
//
102
// // increase progress (step 3)
103
// fireProgressListenerStep();
104
//
105
// // all checks passed -> return null
106
// return null;
107
// } finally {
108
// // fire operation end on the registered progress listeners
109
// fireProgressListenerStop();
110
// }
111
// }
112
//
113
// public Problem fastCheckParameters() {
114
// MemberInfo[] info = refactoring.getMembers();
115
// // #1 - check whether there are any members to pull up
116
// if (info.length == 0) {
117
// return new Problem(true, NbBundle.getMessage(PullUpRefactoringPlugin.class, "ERR_PullUp_NoMembersSelected")); // NOI18N
118
// }
119
//
120
// if (info.length > 1) {
121
// for (int i=0; i<info.length - 1; i++) {
122
// for (int j = i + 1; j < info.length; j++) {
123
// if (CheckUtils.membersEqual(info[i].member, info[j].member)) {
124
// return new Problem(true, NbBundle.getMessage(PullUpRefactoringPlugin.class, "ERR_CannotPullupDuplicateMembers"));
125
// }
126
// }
127
// }
128
// }
129
//
130
// // #2 - check if the targed type is not null
131
// if (refactoring.getTargetType() == null) {
132
// return new Problem(true, NbBundle.getMessage(PullUpRefactoringPlugin.class, "ERR_PullUp_NoTargetType")); // NOI18N
133
// }
134
//
135
// return null;
136
// }
137
//
138
// public Problem checkParameters() {
139
// HashSet supers = new HashSet(Arrays.asList(refactoring.collectSupertypes()));
140
// JavaClass targetType = refactoring.getTargetType();
141
// PullUpRefactoring.MemberInfo[] members = refactoring.getMembers();
142
//
143
// fireProgressListenerStart(AbstractRefactoring.PARAMETERS_CHECK, members.length + 1);
144
// try {
145
// // #1 - check whether the target type is a legal super type
146
// if (!supers.contains(targetType)) {
147
// return new Problem(true, NbBundle.getMessage(PullUpRefactoringPlugin.class, "ERR_PullUp_IllegalTargetType")); // NOI18N
148
// }
149
//
150
// fireProgressListenerStep();
151
//
152
// // #2 - check whether all the members are legal members that can be pulled up
153
// HashSet visitedSources = new HashSet();
154
//// HashSet allMembers = new HashSet(Arrays.asList(members));
155
// Problem problems = null;
156
// visitedSources.add(refactoring.getSourceType());
157
// for (int i = 0; i < members.length; i++) {
158
// ClassDefinition cls;
159
// NamedElement member = members[i].member;
160
// if (member instanceof Feature) {
161
// // member is a feature (inner class, field or method)
162
// cls = ((Feature) member).getDeclaringClass();
163
// } else {
164
// // member is an interface from implements clause
165
// MultipartId ifcName = (MultipartId) member;
166
// // get parent of the element (should be class if this is really
167
// // a name from implements clause
168
// Object parent = ifcName.refImmediateComposite();
169
// // if parent is not a class, member is invalid
170
// if (!(parent instanceof JavaClass)) {
171
// cls = null;
172
// } else {
173
// // check if the parent class contains this MultipartId
174
// // in interfaceNames
175
// if (!((JavaClass) parent).getInterfaceNames().contains(ifcName)) {
176
// cls = null;
177
// } else {
178
// cls = (ClassDefinition) parent;
179
// }
180
// }
181
// }
182
// // if the declaring class has not been visited yet, perform checks on it
183
// if (visitedSources.add(cls)) {
184
// // if the declaring class of a feature is not a JavaClass,
185
// // or if it is not from the set of source type's supertypes
186
// // or if the declaring class is not a subtype of target class
187
// // then this member is illegal
188
// if (!(cls instanceof JavaClass) || !supers.contains(cls) || cls.equals(targetType) || !cls.isSubTypeOf(targetType)) {
189
// return createProblem(problems, true, NbBundle.getMessage(PullUpRefactoringPlugin.class, "ERR_PullUp_IllegalMember", member.getName())); // NOI18N
190
// }
191
// }
192
// // #3 - check if the member already exists in the target class
193
// boolean exists;
194
// if (member instanceof Field) {
195
// exists = (targetType.getField(member.getName(), false) != null);
196
// } else if (member instanceof Method) {
197
// exists = (targetType.getMethod(member.getName(), Utilities.getFeatureParamTypes((CallableFeature) member), false) != null);
198
// } else if (member instanceof JavaClass) {
199
// exists = (targetType.getInnerClass(member.getName(), false) != null);
200
// } else {
201
// exists = targetType.getInterfaces().contains(((MultipartId) member).getElement());
202
// }
203
// if (exists) {
204
// return createProblem(problems, true, NbBundle.getMessage(PullUpRefactoringPlugin.class, "ERR_PullUp_MemberAlreadyExists", member.getName())); // NOI18N
205
// }
206
//
207
// // #4 - check if the field does not use something that is not going to be pulled up
208
//// Resource sourceResource = refactoring.getSourceType().getResource();
209
//// Resource targetResource = targetType.getResource();
210
//// if (!sourceResource.equals(targetResource)) {
211
//// problems = checkUsedByElement(member, allMembers, problems,
212
//// !sourceResource.equals(targetResource),
213
//// !sourceResource.getPackageName().equals(targetResource.getPackageName()));
214
//// }
215
//
216
// fireProgressListenerStep();
217
// }
218
//
219
// // TODO: implement non-fatal checks
220
//
221
// return null;
222
// } finally {
223
// fireProgressListenerStop();
224
// }
225
// }
226
//
227
// public Problem prepare(RefactoringElementsBag refactoringElements) {
228
// PullUpRefactoring.MemberInfo[] members = refactoring.getMembers();
229
//
230
// boolean makeTargetTypeAbstract = false;
231
//
232
// for (int i = 0; i < members.length; i++) {
233
// int modifiers = (members[i].member instanceof MultipartId) ? 0 : ((Feature) members[i].member).getModifiers();
234
// int newmodifiers = 0;
235
// if (refactoring.getTargetType().isInterface()) {
236
// newmodifiers = (modifiers | Modifier.PUBLIC) & ~Modifier.PRIVATE & ~Modifier.PROTECTED;
237
// } else {
238
// if (!(Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers))) {
239
// newmodifiers = (modifiers | Modifier.PROTECTED) & ~Modifier.PRIVATE;
240
// }
241
// }
242
// if (members[i].makeAbstract) {
243
// refactoringElements.add(refactoring, new AddAbstractMethodElement((Method) members[i].member, refactoring.getTargetType(), newmodifiers));
244
// makeTargetTypeAbstract = true;
245
// if (newmodifiers != 0) {
246
// refactoringElements.add(refactoring, new ChangeModElement((Feature) members[i].member, newmodifiers));
247
// }
248
// } else {
249
// refactoringElements.add(refactoring, new MoveMemberElement(members[i].member, refactoring.getTargetType(), newmodifiers));
250
// if (Modifier.isAbstract(modifiers)) {
251
// makeTargetTypeAbstract = true;
252
// }
253
// }
254
// }
255
//
256
// if (makeTargetTypeAbstract && !Modifier.isAbstract(refactoring.getTargetType().getModifiers()) && !refactoring.getTargetType().isInterface()) {
257
// refactoringElements.add(refactoring, new ChangeModElement(refactoring.getTargetType(), refactoring.getTargetType().getModifiers() | Modifier.ABSTRACT));
258
// }
259
//
260
// UndoWatcher.watch(((JMManager) JMManager.getManager()).getDataObject(refactoring.getTargetType().getResource()));
261
//
262
//
263
// // TODO: add refactoring element for changing modifiers of the target class
264
// // if necessary
265
//
266
// return null;
267
// }
268
//
269
// // --- REFACTORING ELEMENTS ------------------------------------------------
270
//
271
// /** Refactoring element that takes care of adding an abstract method declaration
272
// * to the target class.
273
// */
274
// private static class AddAbstractMethodElement extends SimpleRefactoringElementImpl {
275
// private final Method methodToAdd;
276
// private final JavaClass target;
277
// private final int newModifiers;
278
// private final String text;
279
//
280
// /** Creates a new instance of this refactoring element.
281
// * @methodToAdd Method in the source class that should be declared as abstract
282
// * in the target class.
283
// * @target Target class.
284
// * @newModifiers New modifiers of the method or 0 if the modifiers should be
285
// * the same as for the original method (+ <code>abstract</code> modifier).
286
// */
287
// AddAbstractMethodElement(Method methodToAdd, JavaClass target, int newModifiers) {
288
// this.methodToAdd = methodToAdd;
289
// this.target = target;
290
// this.newModifiers = newModifiers;
291
// this.text = NbBundle.getMessage(PullUpRefactoringPlugin.class, "TXT_PullUp_AddMethod", UIUtilities.getDisplayText(methodToAdd)); // NOI18N
292
// }
293
//
294
// public void performChange() {
295
// // get extent of the target method
296
// JavaModelPackage extent = (JavaModelPackage) target.refImmediatePackage();
297
// // create the abstract method in this extent (duplicating the header
298
// // of the existing method
299
// Method newMethod = extent.getMethod().createMethod(
300
// methodToAdd.getName(),
301
// Utilities.duplicateList(methodToAdd.getAnnotations(), extent),
302
// (newModifiers == 0 ? methodToAdd.getModifiers() : newModifiers) | Modifier.ABSTRACT,
303
// methodToAdd.getJavadocText(),
304
// null,
305
// null,
306
// null,
307
// Utilities.duplicateList(methodToAdd.getTypeParameters(), extent),
308
// Utilities.duplicateList(methodToAdd.getParameters(), extent),
309
// Utilities.duplicateList(methodToAdd.getExceptionNames(), extent),
310
// (TypeReference) ((MetadataElement) methodToAdd.getTypeName()).duplicate(extent),
311
// methodToAdd.getDimCount()
312
// );
313
// // add the new method to the target class
314
// if (target.isInterface()) {
315
// newMethod.setModifiers(newMethod.getModifiers() & ~Modifier.ABSTRACT & ~Modifier.PUBLIC & ~Modifier.PROTECTED & ~Modifier.PRIVATE);
316
// }
317
// target.getContents().add(newMethod);
318
// }
319
//
320
// public String getText() {
321
// return text;
322
// }
323
//
324
// public String getDisplayText() {
325
// return text;
326
// }
327
//
328
// public FileObject getParentFile() {
329
// return JavaMetamodel.getManager().getFileObject(target.getResource());
330
// }
331
//
332
// public Element getJavaElement() {
333
// return target;
334
// }
335
//
336
// public PositionBounds getPosition() {
337
// return null;
338
// }
339
// }
340
//
341
// /** Refactoring element that takes care of moving an element to the target type.
342
// */
343
// private static class MoveMemberElement extends SimpleRefactoringElementImpl {
344
// private final NamedElement elementToMove;
345
// private final JavaClass target;
346
// private final int newModifiers;
347
// private final String text;
348
//
349
// /** Creates a new instance of this refactoring element.
350
// * @elementToMove Element to be moved to the target type.
351
// * @target The target type the element should be moved to.
352
// * @newModifiers New modifiers of the element or 0 if the modifiers should
353
// * remain unchanged.
354
// */
355
// MoveMemberElement(NamedElement elementToMove, JavaClass target, int newModifiers) {
356
// this.elementToMove = elementToMove;
357
// this.target = target;
358
// this.newModifiers = newModifiers;
359
// this.text = NbBundle.getMessage(PullUpRefactoringPlugin.class, "TXT_PullUp_Member", UIUtilities.getDisplayText(elementToMove)); // NOI18N
360
// }
361
//
362
// public void performChange() {
363
// JavaModelPackage targetExtent = (JavaModelPackage) target.refImmediatePackage();
364
// JavaClass elementParent;
365
// Element newElement;
366
// boolean deleteElementToMove = false;
367
// // processing is different for Feature (field, inner class, method)
368
// // and MultipartId (interface in the implements clause)
369
// if (elementToMove instanceof Feature) {
370
// // get the declaring class of the element
371
// elementParent = (JavaClass) ((Feature) elementToMove).getDeclaringClass();
372
// // check if the declaring type is in the same extent as the target type
373
// if (targetExtent.equals(elementParent.refImmediatePackage())) {
374
// // if so, a simple move is possible
375
// elementParent.getFeatures().remove(elementToMove);
376
// newElement = elementToMove;
377
// } else {
378
// // otherwise we need to create a copy of the element in the target extent
379
// newElement = ((MetadataElement) elementToMove).duplicate(targetExtent);
380
// // and delete the original element in the source extent
381
// deleteElementToMove = true;
382
// }
383
// // add the element to the target class
384
// target.getContents().add(newElement);
385
// // change modifiers if necessary
386
// if (newModifiers != 0) {
387
// ((Feature) newElement).setModifiers(newModifiers);
388
// }
389
// } else {
390
// // get parent type of the element
391
// elementParent = (JavaClass) elementToMove.refImmediateComposite();
392
// // check if the target extent is the same as the source extent
393
// if (targetExtent.equals(elementParent.refImmediatePackage())) {
394
// // yes -> simple move
395
// elementParent.getInterfaceNames().remove(elementToMove);
396
// newElement = elementToMove;
397
// } else {
398
// // no -> a new copy in the target extent needs to be created
399
// newElement = ((MetadataElement) elementToMove).duplicate(targetExtent);
400
// deleteElementToMove = true;
401
// }
402
// // add the new element to the implements clause of the target type
403
// target.getInterfaceNames().add(newElement);
404
// }
405
// ((MetadataElement) newElement).fixImports(target, elementToMove);
406
// if (deleteElementToMove) {
407
// elementToMove.refDelete();
408
// }
409
// }
410
//
411
// public String getText() {
412
// return text;
413
// }
414
//
415
// public String getDisplayText() {
416
// return text;
417
// }
418
//
419
// public FileObject getParentFile() {
420
// return JavaMetamodel.getManager().getFileObject(elementToMove.getResource());
421
// }
422
//
423
// public Element getJavaElement() {
424
// return JavaModelUtil.getDeclaringFeature(elementToMove);
425
// }
426
//
427
// public PositionBounds getPosition() {
428
// return JavaMetamodel.getManager().getElementPosition(elementToMove);
429
// }
430
// }
431
//
432
// // --- HELPER METHODS ------------------------------------------------------
433
//
434
// // checks if the source type or any of its supertypes has any members that could
435
// // be pulled up
436
// private static boolean hasMembers(JavaClass sourceType, JavaClass[] supertypes) {
437
// boolean result = Utilities.hasMembers(sourceType);
438
//
439
// for (int i = 0; i < (supertypes.length - 1) && !result; i++) {
440
// result = Utilities.hasMembers(supertypes[i]);
441
// }
442
//
443
// return result;
444
// }
445
//
446
// // checks if the element is used by other element which will not be pulled up
447
// private Problem checkUsedByElement(Element element, Set allMembers, Problem problems, boolean resourceChange, boolean packageChange) {
448
// if (element instanceof MultipartId) {
449
// // TODO: check with import management tool, whether an import should be added
450
// } else if (element instanceof MethodInvocation
451
// || element instanceof NewClassExpression
452
// || element instanceof VariableAccess) {
453
// NamedElement referencedElement = ((ElementReference) element).getElement();
454
// if (referencedElement instanceof Feature) {
455
// Feature referencedFeature = (Feature) referencedElement;
456
// int modifiers = referencedFeature.getModifiers();
457
// ClassDefinition declClass = referencedFeature.getDeclaringClass();
458
// PrimaryExpression parentClass;
459
// if (element instanceof VariableAccess) {
460
// parentClass = ((VariableAccess) element).getParentClass();
461
// } else if (element instanceof MethodInvocation) {
462
// parentClass = ((MethodInvocation) element).getParentClass();
463
// } else {
464
// if ((declClass instanceof JavaClass) && !Modifier.isStatic(((JavaClass) declClass).getModifiers())) {
465
// parentClass = ((NewClassExpression) element).getEnclosingClass();
466
// } else {
467
// parentClass = null;
468
// }
469
// }
470
// boolean isSameInstance = (parentClass == null) || (parentClass instanceof ThisExpression);
471
// if (Modifier.isPrivate(modifiers)) {
472
// if (resourceChange || isSameInstance) {
473
// problems = createProblem(problems, false, "will not be accessible"); // NOI18N
474
// }
475
// } else if (packageChange && !Modifier.isPublic(modifiers)) {
476
// if (Modifier.isProtected(modifiers) && (referencedElement instanceof Method)) {
477
// // TODO: check if the method is not defined also in target or one of its supers ->
478
// // in that case do not generate a problem
479
// }
480
// problems = createProblem(problems, false, "will not be accessible - is protected/package private"); // NOI18N
481
// }
482
// }
483
// }
484
//
485
// for (Iterator it = element.getChildren().iterator(); it.hasNext();) {
486
// problems = checkUsedByElement((Element) it.next(), allMembers, problems, resourceChange, packageChange);
487
// }
488
//
489
// return problems;
490
// }
491
}
492
Popular Tags