KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > structure > MemberVisibilityAdjustor


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  *******************************************************************************/

11 package org.eclipse.jdt.internal.corext.refactoring.structure;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.Map JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.eclipse.core.runtime.OperationCanceledException;
20 import org.eclipse.core.runtime.SubProgressMonitor;
21
22 import org.eclipse.ltk.core.refactoring.CategorizedTextEditGroup;
23 import org.eclipse.ltk.core.refactoring.GroupCategory;
24 import org.eclipse.ltk.core.refactoring.GroupCategorySet;
25 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
26 import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
27
28 import org.eclipse.jdt.core.Flags;
29 import org.eclipse.jdt.core.ICompilationUnit;
30 import org.eclipse.jdt.core.IField;
31 import org.eclipse.jdt.core.IInitializer;
32 import org.eclipse.jdt.core.IJavaElement;
33 import org.eclipse.jdt.core.IMember;
34 import org.eclipse.jdt.core.IMethod;
35 import org.eclipse.jdt.core.IPackageFragment;
36 import org.eclipse.jdt.core.IType;
37 import org.eclipse.jdt.core.ITypeHierarchy;
38 import org.eclipse.jdt.core.JavaCore;
39 import org.eclipse.jdt.core.JavaModelException;
40 import org.eclipse.jdt.core.WorkingCopyOwner;
41 import org.eclipse.jdt.core.dom.ASTNode;
42 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
43 import org.eclipse.jdt.core.dom.BodyDeclaration;
44 import org.eclipse.jdt.core.dom.CompilationUnit;
45 import org.eclipse.jdt.core.dom.FieldDeclaration;
46 import org.eclipse.jdt.core.dom.IExtendedModifier;
47 import org.eclipse.jdt.core.dom.Modifier;
48 import org.eclipse.jdt.core.dom.SimpleName;
49 import org.eclipse.jdt.core.dom.Type;
50 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
51 import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
52 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
53 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
54 import org.eclipse.jdt.core.search.IJavaSearchConstants;
55 import org.eclipse.jdt.core.search.IJavaSearchScope;
56 import org.eclipse.jdt.core.search.SearchMatch;
57 import org.eclipse.jdt.core.search.SearchPattern;
58
59 import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
60 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
61 import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
62 import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine2;
63 import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
64 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
65 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
66 import org.eclipse.jdt.internal.corext.util.Messages;
67 import org.eclipse.jdt.internal.corext.util.SearchUtils;
68
69 import org.eclipse.jdt.ui.JavaElementLabels;
70
71 /**
72  * Helper class to adjust the visibilities of members with respect to a reference element.
73  *
74  * @since 3.1
75  */

76 public final class MemberVisibilityAdjustor {
77
78     /**
79      * The visibility group category set.
80      *
81      * @since 3.2
82      */

83     public static final GroupCategorySet SET_VISIBILITY_ADJUSTMENTS= new GroupCategorySet(new GroupCategory("org.eclipse.jdt.internal.corext.visibilityAdjustments", //$NON-NLS-1$
84
RefactoringCoreMessages.MemberVisibilityAdjustor_adjustments_name, RefactoringCoreMessages.MemberVisibilityAdjustor_adjustments_description));
85
86     /** Description of a member visibility adjustment */
87     public static class IncomingMemberVisibilityAdjustment implements IVisibilityAdjustment {
88
89         /** The keyword representing the adjusted visibility */
90         protected final ModifierKeyword fKeyword;
91
92         /** The member whose visibility has been adjusted */
93         protected final IMember fMember;
94
95         /** Does the visibility adjustment need rewriting? */
96         protected boolean fNeedsRewriting= true;
97
98         /** The associated refactoring status */
99         protected final RefactoringStatus fRefactoringStatus;
100
101         /**
102          * Creates a new incoming member visibility adjustment.
103          *
104          * @param member the member which is adjusted
105          * @param keyword the keyword representing the adjusted visibility
106          * @param status the associated status, or <code>null</code>
107          */

108         public IncomingMemberVisibilityAdjustment(final IMember member, final ModifierKeyword keyword, final RefactoringStatus status) {
109             Assert.isNotNull(member);
110             Assert.isTrue(!(member instanceof IInitializer));
111             Assert.isTrue(isVisibilityKeyword(keyword));
112             fMember= member;
113             fKeyword= keyword;
114             fRefactoringStatus= status;
115         }
116
117         /**
118          * Returns the visibility keyword.
119          *
120          * @return the visibility keyword
121          */

122         public final ModifierKeyword getKeyword() {
123             return fKeyword;
124         }
125
126         /**
127          * Returns the adjusted member.
128          *
129          * @return the adjusted member
130          */

131         public final IMember getMember() {
132             return fMember;
133         }
134
135         /**
136          * Returns the associated refactoring status.
137          *
138          * @return the associated refactoring status
139          */

140         public final RefactoringStatus getStatus() {
141             return fRefactoringStatus;
142         }
143
144         /**
145          * Does the visibility adjustment need rewriting?
146          *
147          * @return <code>true</code> if it needs rewriting, <code>false</code> otherwise
148          */

149         public final boolean needsRewriting() {
150             return fNeedsRewriting;
151         }
152
153         /**
154          * Rewrites the visibility adjustment.
155          *
156          * @param adjustor the java element visibility adjustor
157          * @param rewrite the AST rewrite to use
158          * @param root the root of the AST used in the rewrite
159          * @param group the text edit group description to use, or <code>null</code>
160          * @param status the refactoring status, or <code>null</code>
161          * @throws JavaModelException if an error occurs
162          */

163         protected final void rewriteVisibility(final MemberVisibilityAdjustor adjustor, final ASTRewrite rewrite, final CompilationUnit root, final CategorizedTextEditGroup group, final RefactoringStatus status) throws JavaModelException {
164             Assert.isNotNull(adjustor);
165             Assert.isNotNull(rewrite);
166             Assert.isNotNull(root);
167             final int visibility= fKeyword != null ? fKeyword.toFlagValue() : Modifier.NONE;
168             if (fMember instanceof IField && !Flags.isEnum(fMember.getFlags())) {
169                 final VariableDeclarationFragment fragment= ASTNodeSearchUtil.getFieldDeclarationFragmentNode((IField) fMember, root);
170                 final FieldDeclaration declaration= (FieldDeclaration) fragment.getParent();
171                 if (declaration.fragments().size() == 1)
172                     ModifierRewrite.create(rewrite, declaration).setVisibility(visibility, group);
173                 else {
174                     final VariableDeclarationFragment newFragment= rewrite.getAST().newVariableDeclarationFragment();
175                     newFragment.setName((SimpleName) rewrite.createCopyTarget(fragment.getName()));
176                     final FieldDeclaration newDeclaration= rewrite.getAST().newFieldDeclaration(newFragment);
177                     newDeclaration.setType((Type) rewrite.createCopyTarget(declaration.getType()));
178                     IExtendedModifier extended= null;
179                     for (final Iterator JavaDoc iterator= declaration.modifiers().iterator(); iterator.hasNext();) {
180                         extended= (IExtendedModifier) iterator.next();
181                         if (extended.isModifier()) {
182                             final Modifier modifier= (Modifier) extended;
183                             final int flag= modifier.getKeyword().toFlagValue();
184                             if ((flag & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE)) != 0)
185                                 continue;
186                         }
187                         newDeclaration.modifiers().add(rewrite.createCopyTarget((ASTNode) extended));
188                     }
189                     ModifierRewrite.create(rewrite, newDeclaration).setVisibility(visibility, group);
190                     final AbstractTypeDeclaration type= (AbstractTypeDeclaration) declaration.getParent();
191                     rewrite.getListRewrite(type, type.getBodyDeclarationsProperty()).insertAfter(newDeclaration, declaration, null);
192                     final ListRewrite list= rewrite.getListRewrite(declaration, FieldDeclaration.FRAGMENTS_PROPERTY);
193                     list.remove(fragment, group);
194                     if (list.getRewrittenList().isEmpty())
195                         rewrite.remove(declaration, null);
196                 }
197                 if (status != null)
198                     adjustor.fStatus.merge(status);
199             } else if (fMember != null) {
200                 final BodyDeclaration declaration= ASTNodeSearchUtil.getBodyDeclarationNode(fMember, root);
201                 if (declaration != null) {
202                     ModifierRewrite.create(rewrite, declaration).setVisibility(visibility, group);
203                     if (status != null)
204                         adjustor.fStatus.merge(status);
205                 }
206             }
207         }
208
209         /*
210          * @see org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor.IVisibilityAdjustment#rewriteVisibility(org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor, org.eclipse.core.runtime.IProgressMonitor)
211          */

212         public void rewriteVisibility(final MemberVisibilityAdjustor adjustor, final IProgressMonitor monitor) throws JavaModelException {
213             Assert.isNotNull(adjustor);
214             Assert.isNotNull(monitor);
215             try {
216                 monitor.beginTask("", 1); //$NON-NLS-1$
217
monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_adjusting);
218                 if (fNeedsRewriting) {
219                     if (adjustor.fRewrite != null && adjustor.fRoot != null)
220                         rewriteVisibility(adjustor, adjustor.fRewrite, adjustor.fRoot, null, fRefactoringStatus);
221                     else {
222                         final CompilationUnitRewrite rewrite= adjustor.getCompilationUnitRewrite(fMember.getCompilationUnit());
223                         rewriteVisibility(adjustor, rewrite.getASTRewrite(), rewrite.getRoot(), rewrite.createCategorizedGroupDescription(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility, getLabel(getKeyword())), SET_VISIBILITY_ADJUSTMENTS), fRefactoringStatus);
224                     }
225                 } else if (fRefactoringStatus != null)
226                     adjustor.fStatus.merge(fRefactoringStatus);
227                 monitor.worked(1);
228             } finally {
229                 monitor.done();
230             }
231         }
232
233         /**
234          * Determines whether the visibility adjustment needs rewriting.
235          *
236          * @param rewriting <code>true</code> if it needs rewriting, <code>false</code> otherwise
237          */

238         public final void setNeedsRewriting(final boolean rewriting) {
239             fNeedsRewriting= rewriting;
240         }
241     }
242
243     /** Interface for visibility adjustments */
244     public interface IVisibilityAdjustment {
245
246         /**
247          * Rewrites the visibility adjustment.
248          *
249          * @param adjustor the java element visibility adjustor
250          * @param monitor the progress monitor to use
251          * @throws JavaModelException if an error occurs
252          */

253         public void rewriteVisibility(MemberVisibilityAdjustor adjustor, IProgressMonitor monitor) throws JavaModelException;
254     }
255
256     /** Description of an outgoing member visibility adjustment */
257     public static class OutgoingMemberVisibilityAdjustment extends IncomingMemberVisibilityAdjustment {
258
259         /**
260          * Creates a new outgoing member visibility adjustment.
261          *
262          * @param member the member which is adjusted
263          * @param keyword the keyword representing the adjusted visibility
264          * @param status the associated status
265          */

266         public OutgoingMemberVisibilityAdjustment(final IMember member, final ModifierKeyword keyword, final RefactoringStatus status) {
267             super(member, keyword, status);
268         }
269
270         /*
271          * @see org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor.IVisibilityAdjustment#rewriteVisibility(org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor, org.eclipse.core.runtime.IProgressMonitor)
272          */

273         public void rewriteVisibility(final MemberVisibilityAdjustor adjustor, final IProgressMonitor monitor) throws JavaModelException {
274             Assert.isNotNull(adjustor);
275             Assert.isNotNull(monitor);
276             try {
277                 monitor.beginTask("", 1); //$NON-NLS-1$
278
monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_adjusting);
279                 if (fNeedsRewriting) {
280                     final CompilationUnitRewrite rewrite= adjustor.getCompilationUnitRewrite(fMember.getCompilationUnit());
281                     rewriteVisibility(adjustor, rewrite.getASTRewrite(), rewrite.getRoot(), rewrite.createCategorizedGroupDescription(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility, getLabel(getKeyword())), SET_VISIBILITY_ADJUSTMENTS), fRefactoringStatus);
282                 }
283                 monitor.worked(1);
284             } finally {
285                 monitor.done();
286             }
287         }
288     }
289
290     /**
291      * Returns the label for the specified java element.
292      *
293      * @param element the element to get the label for
294      * @return the label for the element
295      */

296     public static String JavaDoc getLabel(final IJavaElement element) {
297         Assert.isNotNull(element);
298         return JavaElementLabels.getElementLabel(element, JavaElementLabels.ALL_FULLY_QUALIFIED | JavaElementLabels.ALL_DEFAULT);
299     }
300
301     /**
302      * Returns the label for the specified visibility keyword.
303      *
304      * @param keyword the keyword to get the label for, or <code>null</code> for default visibility
305      * @return the label for the keyword
306      */

307     public static String JavaDoc getLabel(final ModifierKeyword keyword) {
308         Assert.isTrue(isVisibilityKeyword(keyword));
309         if (keyword == null)
310             return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_default;
311         else if (ModifierKeyword.PUBLIC_KEYWORD.equals(keyword))
312             return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_public;
313         else if (ModifierKeyword.PROTECTED_KEYWORD.equals(keyword))
314             return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_protected;
315         else
316             return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_private;
317     }
318
319     /**
320      * Returns the message string for the specified member.
321      *
322      * @param member the member to get the string for
323      * @return the string for the member
324      */

325     public static String JavaDoc getMessage(final IMember member) {
326         Assert.isTrue(member instanceof IType || member instanceof IMethod || member instanceof IField);
327         if (member instanceof IType)
328             return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_type_warning;
329         else if (member instanceof IMethod)
330             return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning;
331         else
332             return RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_field_warning;
333     }
334
335     /**
336      * Do the specified modifiers represent a lower visibility than the required threshold?
337      *
338      * @param modifiers the modifiers to test
339      * @param threshold the visibility threshold to compare with
340      * @return <code>true</code> if the visibility is lower than required, <code>false</code> otherwise
341      */

342     public static boolean hasLowerVisibility(final int modifiers, final int threshold) {
343         if (Modifier.isPrivate(threshold))
344             return false;
345         else if (Modifier.isPublic(threshold))
346             return !Modifier.isPublic(modifiers);
347         else if (Modifier.isProtected(threshold))
348             return !Modifier.isProtected(modifiers) && !Modifier.isPublic(modifiers);
349         else
350             return Modifier.isPrivate(modifiers);
351     }
352
353     /**
354      * Does the specified modifier keyword represent a lower visibility than the required threshold?
355      *
356      * @param keyword the visibility keyword to test, or <code>null</code> for default visibility
357      * @param threshold the visibility threshold keyword to compare with, or <code>null</code> to compare with default visibility
358      * @return <code>true</code> if the visibility is lower than required, <code>false</code> otherwise
359      */

360     public static boolean hasLowerVisibility(final ModifierKeyword keyword, final ModifierKeyword threshold) {
361         Assert.isTrue(isVisibilityKeyword(keyword));
362         Assert.isTrue(isVisibilityKeyword(threshold));
363         return hasLowerVisibility(keyword != null ? keyword.toFlagValue() : Modifier.NONE, threshold != null ? threshold.toFlagValue() : Modifier.NONE);
364     }
365
366     /**
367      * Is the specified severity a refactoring status severity?
368      *
369      * @param severity the severity to test
370      * @return <code>true</code> if it is a refactoring status severity, <code>false</code> otherwise
371      */

372     private static boolean isStatusSeverity(final int severity) {
373         return severity == RefactoringStatus.ERROR || severity == RefactoringStatus.FATAL || severity == RefactoringStatus.INFO || severity == RefactoringStatus.OK || severity == RefactoringStatus.WARNING;
374     }
375
376     /**
377      * Is the specified modifier keyword a visibility keyword?
378      *
379      * @param keyword the keyword to test, or <code>null</code>
380      * @return <code>true</code> if it is a visibility keyword, <code>false</code> otherwise
381      */

382     private static boolean isVisibilityKeyword(final ModifierKeyword keyword) {
383         return keyword == null || ModifierKeyword.PUBLIC_KEYWORD.equals(keyword) || ModifierKeyword.PROTECTED_KEYWORD.equals(keyword) || ModifierKeyword.PRIVATE_KEYWORD.equals(keyword);
384     }
385
386     /**
387      * Is the specified modifier a visibility modifier?
388      *
389      * @param modifier the keyword to test
390      * @return <code>true</code> if it is a visibility modifier, <code>false</code> otherwise
391      */

392     private static boolean isVisibilityModifier(final int modifier) {
393         return modifier == Modifier.NONE || modifier == Modifier.PUBLIC || modifier == Modifier.PROTECTED || modifier == Modifier.PRIVATE;
394     }
395
396     /**
397      * Converts a given modifier keyword into a visibility flag.
398      *
399      * @param keyword the keyword to convert
400      * @return the visibility flag
401      */

402     private static int keywordToVisibility(final ModifierKeyword keyword) {
403         int visibility= 0;
404         if (keyword == ModifierKeyword.PUBLIC_KEYWORD)
405             visibility= Flags.AccPublic;
406         else if (keyword == ModifierKeyword.PRIVATE_KEYWORD)
407             visibility= Flags.AccPrivate;
408         else if (keyword == ModifierKeyword.PROTECTED_KEYWORD)
409             visibility= Flags.AccProtected;
410         return visibility;
411     }
412
413     /**
414      * Does the specified member need further visibility adjustment?
415      *
416      * @param member the member to test
417      * @param threshold the visibility threshold to test for
418      * @param adjustments the map of members to visibility adjustments
419      * @return <code>true</code> if the member needs further adjustment, <code>false</code> otherwise
420      */

421     public static boolean needsVisibilityAdjustments(final IMember member, final int threshold, final Map JavaDoc adjustments) {
422         Assert.isNotNull(member);
423         Assert.isTrue(isVisibilityModifier(threshold));
424         Assert.isNotNull(adjustments);
425         final IncomingMemberVisibilityAdjustment adjustment= (IncomingMemberVisibilityAdjustment) adjustments.get(member);
426         if (adjustment != null) {
427             final ModifierKeyword keyword= adjustment.getKeyword();
428             return hasLowerVisibility(keyword == null ? Modifier.NONE : keyword.toFlagValue(), threshold);
429         }
430         return true;
431     }
432
433     /**
434      * Does the specified member need further visibility adjustment?
435      *
436      * @param member the member to test
437      * @param threshold the visibility threshold to test for, or <code>null</code> for default visibility
438      * @param adjustments the map of members to visibility adjustments
439      * @return <code>true</code> if the member needs further adjustment, <code>false</code> otherwise
440      */

441     public static boolean needsVisibilityAdjustments(final IMember member, final ModifierKeyword threshold, final Map JavaDoc adjustments) {
442         Assert.isNotNull(member);
443         Assert.isNotNull(adjustments);
444         final IncomingMemberVisibilityAdjustment adjustment= (IncomingMemberVisibilityAdjustment) adjustments.get(member);
445         if (adjustment != null)
446             return hasLowerVisibility(adjustment.getKeyword(), threshold);
447         return true;
448     }
449
450     /** The map of members to visibility adjustments */
451     private Map JavaDoc fAdjustments= new HashMap JavaDoc();
452
453     /** Should incoming references be adjusted? */
454     private boolean fIncoming= true;
455
456     /** Should outgoing references be adjusted? */
457     private boolean fOutgoing= true;
458
459     /** The referenced element causing the visibility adjustment */
460     private final IMember fReferenced;
461
462     /** The referencing java element */
463     private final IJavaElement fReferencing;
464
465     /** The AST rewrite to use for reference visibility adjustments, or <code>null</code> to use a compilation unit rewrite */
466     private ASTRewrite fRewrite= null;
467
468     /** The map of compilation units to compilation unit rewrites */
469     private Map JavaDoc fRewrites= new HashMap JavaDoc(3);
470
471     /** The root node of the AST rewrite for reference visibility adjustments, or <code>null</code> to use a compilation unit rewrite */
472     private CompilationUnit fRoot= null;
473
474     /** The incoming search scope */
475     private IJavaSearchScope fScope;
476
477     /** The status of the visibility adjustment */
478     private RefactoringStatus fStatus= new RefactoringStatus();
479
480     /** The type hierarchy cache */
481     private final Map JavaDoc fTypeHierarchies= new HashMap JavaDoc();
482
483     /** The visibility message severity */
484     private int fVisibilitySeverity= RefactoringStatus.WARNING;
485
486     /** The working copy owner, or <code>null</code> to use none */
487     private WorkingCopyOwner fOwner= null;
488
489     /**
490      * Creates a new java element visibility adjustor.
491      *
492      * @param referencing the referencing element used to compute the visibility
493      * @param referenced the referenced member which causes the visibility changes
494      */

495     public MemberVisibilityAdjustor(final IJavaElement referencing, final IMember referenced) {
496         Assert.isTrue(!(referenced instanceof IInitializer));
497         Assert.isTrue(referencing instanceof ICompilationUnit || referencing instanceof IType || referencing instanceof IPackageFragment);
498         fScope= RefactoringScopeFactory.createReferencedScope(new IJavaElement[] { referenced}, IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES);
499         fReferencing= referencing;
500         fReferenced= referenced;
501     }
502
503     /**
504      * Adjusts the visibility of the specified member.
505      *
506      * @param element the "source" point from which to calculate the visibility
507      * @param referencedMovedElement the moved element which may be adjusted in visibility
508      * @param monitor the progress monitor to use
509      * @throws JavaModelException if the visibility adjustment could not be computed
510      */

511     private void adjustIncomingVisibility(final IJavaElement element, IMember referencedMovedElement, final IProgressMonitor monitor) throws JavaModelException {
512         final ModifierKeyword threshold= getVisibilityThreshold(element, referencedMovedElement, monitor);
513         int flags= referencedMovedElement.getFlags();
514         IType declaring= referencedMovedElement.getDeclaringType();
515         if (declaring.isInterface())
516             return;
517         if (hasLowerVisibility(flags, threshold == null ? Modifier.NONE : threshold.toFlagValue()) && needsVisibilityAdjustment(referencedMovedElement, threshold))
518             fAdjustments.put(referencedMovedElement, new IncomingMemberVisibilityAdjustment(referencedMovedElement, threshold, RefactoringStatus.createStatus(fVisibilitySeverity, Messages.format(getMessage(referencedMovedElement), new String JavaDoc[] { getLabel(referencedMovedElement), getLabel(threshold)}), JavaStatusContext.create(referencedMovedElement), null, RefactoringStatusEntry.NO_CODE, null)));
519     }
520
521     /**
522      * Check whether anyone accesses the members of the moved type from the
523      * outside. Those may need to have their visibility adjusted.
524      * @param member
525      * @param monitor
526      * @throws JavaModelException
527      */

528     private void adjustMemberVisibility(final IMember member, final IProgressMonitor monitor) throws JavaModelException {
529
530         if (member instanceof IType) {
531             // recursively check accessibility of member type's members
532
final IJavaElement[] typeMembers= ((IType) member).getChildren();
533             for (int i= 0; i < typeMembers.length; i++) {
534                 if (! (typeMembers[i] instanceof IInitializer))
535                     adjustMemberVisibility((IMember) typeMembers[i], monitor);
536             }
537         }
538
539         if ((member.equals(fReferenced)) || (Modifier.isPublic(member.getFlags())))
540             return;
541
542         final SearchResultGroup[] references= findReferences(member, monitor);
543         for (int i= 0; i < references.length; i++) {
544             final SearchMatch[] searchResults= references[i].getSearchResults();
545             for (int k= 0; k < searchResults.length; k++) {
546                 final IJavaElement referenceToMember= (IJavaElement) searchResults[k].getElement();
547                 if (fAdjustments.get(member) == null && referenceToMember instanceof IMember && !isInsideMovedMember(referenceToMember)) {
548                     // check whether the member is still visible from the
549
// destination. As we are moving a type, the destination is
550
// a package or another type.
551
adjustIncomingVisibility(fReferencing, member, new SubProgressMonitor(monitor, 1));
552                 }
553             }
554         }
555     }
556
557     /**
558      * Is the specified member inside the moved member?
559      * @param element the element
560      * @return <code>true</code> if it is inside, <code>false</code> otherwise
561      */

562     private boolean isInsideMovedMember(final IJavaElement element) {
563         IJavaElement current= element;
564         while ((current= current.getParent()) != null)
565             if (current.equals(fReferenced))
566                 return true;
567         return false;
568     }
569
570     /**
571      * Finds references to the specified member.
572      * @param member the member
573      * @param monitor the progress monitor to use
574      * @return the search result groups
575      * @throws JavaModelException if an error occurs during search
576      */

577     private SearchResultGroup[] findReferences(final IMember member, final IProgressMonitor monitor) throws JavaModelException {
578         final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(member, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE));
579         engine.setOwner(fOwner);
580         engine.setFiltering(true, true);
581         engine.setScope(RefactoringScopeFactory.create(member));
582         engine.searchPattern(new SubProgressMonitor(monitor, 1));
583         return (SearchResultGroup[]) engine.getResults();
584     }
585
586     /**
587      * Adjusts the visibility of the member based on the incoming references
588      * represented by the specified search result groups.
589      *
590      * If there is at least one reference to the moved element from outside the
591      * moved element, visibility must be increased such that the moved element
592      * (fReferenced) is still visible at the target from all references. This
593      * effectively means that the old element (fReferenced) must be visible from
594      * the new location (fReferencing).
595      *
596      * @param groups the search result groups representing the references
597      * @param monitor the progress monitor to use
598      * @throws JavaModelException if the java elements could not be accessed
599      */

600     private void adjustIncomingVisibility(final SearchResultGroup[] groups, final IProgressMonitor monitor) throws JavaModelException {
601         try {
602             monitor.beginTask("", groups.length); //$NON-NLS-1$
603
monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking);
604             SearchMatch[] matches= null;
605             boolean adjusted= false;
606             for (int index= 0; index < groups.length; index++) {
607                 matches= groups[index].getSearchResults();
608                 for (int offset= 0; offset < matches.length; offset++) {
609                     final Object JavaDoc element= matches[offset].getElement();
610                     if (element instanceof IMember && !isInsideMovedMember((IMember) element)) {
611                         // found one reference which is not inside the moved
612
// element => adjust visibility of the moved element
613
adjustIncomingVisibility(fReferencing, fReferenced, monitor);
614                         adjusted= true; // one adjustment is enough
615
break;
616                     }
617                 }
618                 if (adjusted)
619                     break;
620                 monitor.worked(1);
621             }
622         } finally {
623             monitor.done();
624         }
625     }
626
627     /**
628      * Adjusts the visibility of the referenced field found in a compilation unit.
629      *
630      * @param field the referenced field to adjust
631      * @param threshold the visibility threshold, or <code>null</code> for default visibility
632      * @throws JavaModelException if an error occurs
633      */

634     private void adjustOutgoingVisibility(final IField field, final ModifierKeyword threshold) throws JavaModelException {
635         Assert.isTrue(!field.isBinary() && !field.isReadOnly());
636         //bug 100555 (moving inner class to top level class; taking private fields with you)
637
final IType declaring= field.getDeclaringType();
638         if (declaring != null && declaring.equals(fReferenced)) return;
639         if (hasLowerVisibility(field.getFlags(), keywordToVisibility(threshold)) && needsVisibilityAdjustment(field, threshold))
640             adjustOutgoingVisibility(field, threshold, RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_field_warning);
641     }
642
643     /**
644      * Adjusts the visibility of the referenced body declaration.
645      *
646      * @param member the member where to adjust the visibility
647      * @param threshold the visibility keyword representing the required visibility, or <code>null</code> for default visibility
648      * @param template the message template to use
649      * @throws JavaModelException if an error occurs
650      */

651     private void adjustOutgoingVisibility(final IMember member, final ModifierKeyword threshold, final String JavaDoc template) throws JavaModelException {
652         Assert.isTrue(!member.isBinary() && !member.isReadOnly());
653         boolean adjust= true;
654         final IType declaring= member.getDeclaringType();
655         if (declaring != null && (JavaModelUtil.isInterfaceOrAnnotation(declaring) || declaring.equals(fReferenced)))
656             adjust= false;
657         if (adjust && hasLowerVisibility(member.getFlags(), keywordToVisibility(threshold)) && needsVisibilityAdjustment(member, threshold))
658             fAdjustments.put(member, new OutgoingMemberVisibilityAdjustment(member, threshold, RefactoringStatus.createStatus(fVisibilitySeverity, Messages.format(template, new String JavaDoc[] { JavaElementLabels.getTextLabel(member, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.ALL_FULLY_QUALIFIED), getLabel(threshold)}), JavaStatusContext.create(member), null, RefactoringStatusEntry.NO_CODE, null)));
659     }
660
661     /**
662      * Adjusts the visibilities of the referenced element from the search match found in a compilation unit.
663      *
664      * @param match the search match representing the element declaration
665      * @param monitor the progress monitor to use
666      * @throws JavaModelException if the visibility could not be determined
667      */

668     private void adjustOutgoingVisibility(final SearchMatch match, final IProgressMonitor monitor) throws JavaModelException {
669         final Object JavaDoc element= match.getElement();
670         if (element instanceof IMember) {
671             final IMember member= (IMember) element;
672             if (!member.isBinary() && !member.isReadOnly() && !isInsideMovedMember(member)) {
673                 adjustOutgoingVisibilityChain(member, monitor);
674             }
675         }
676     }
677
678     private void adjustOutgoingVisibilityChain(final IMember member, final IProgressMonitor monitor) throws JavaModelException {
679
680         if (!Modifier.isPublic(member.getFlags())) {
681             final ModifierKeyword threshold= computeOutgoingVisibilityThreshold(fReferencing, member, monitor);
682             if (member instanceof IMethod) {
683                 adjustOutgoingVisibility(member, threshold, RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning);
684             } else if (member instanceof IField) {
685                 adjustOutgoingVisibility((IField) member, threshold);
686             } else if (member instanceof IType) {
687                 adjustOutgoingVisibility(member, threshold, RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_type_warning);
688             }
689         }
690
691         if (member.getDeclaringType() != null)
692             adjustOutgoingVisibilityChain(member.getDeclaringType(), monitor);
693     }
694
695     /**
696      * Adjusts the visibilities of the outgoing references from the member represented by the specified search result groups.
697      *
698      * @param groups the search result groups representing the references
699      * @param monitor the progress monitor to us
700      * @throws JavaModelException if the visibility could not be determined
701      */

702     private void adjustOutgoingVisibility(final SearchResultGroup[] groups, final IProgressMonitor monitor) throws JavaModelException {
703         try {
704             monitor.beginTask("", groups.length); //$NON-NLS-1$
705
monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking);
706             IJavaElement element= null;
707             SearchMatch[] matches= null;
708             SearchResultGroup group= null;
709             for (int index= 0; index < groups.length; index++) {
710                 group= groups[index];
711                 element= JavaCore.create(group.getResource());
712                 if (element instanceof ICompilationUnit) {
713                     matches= group.getSearchResults();
714                     for (int offset= 0; offset < matches.length; offset++)
715                         adjustOutgoingVisibility(matches[offset], new SubProgressMonitor(monitor, 1));
716                 } // else if (element != null)
717
// fStatus.merge(RefactoringStatus.createStatus(fFailureSeverity, RefactoringCoreMessages.getFormattedString("MemberVisibilityAdjustor.binary.outgoing.project", new String[] { element.getJavaProject().getElementName(), getLabel(fReferenced)}), null, null, RefactoringStatusEntry.NO_CODE, null)); //$NON-NLS-1$
718
// else if (group.getResource() != null)
719
// fStatus.merge(RefactoringStatus.createStatus(fFailureSeverity, RefactoringCoreMessages.getFormattedString("MemberVisibilityAdjustor.binary.outgoing.resource", new String[] { group.getResource().getName(), getLabel(fReferenced)}), null, null, RefactoringStatusEntry.NO_CODE, null)); //$NON-NLS-1$
720

721                 // TW: enable when bug 78387 is fixed
722

723                 monitor.worked(1);
724             }
725         } finally {
726             monitor.done();
727         }
728     }
729
730     /**
731      * Adjusts the visibilities of the referenced and referencing elements.
732      *
733      * @param monitor the progress monitor to use
734      * @throws JavaModelException if an error occurs during search
735      */

736     public final void adjustVisibility(final IProgressMonitor monitor) throws JavaModelException {
737         try {
738             monitor.beginTask("", 7); //$NON-NLS-1$
739
monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking);
740             final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(fReferenced, IJavaSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE));
741             engine.setScope(fScope);
742             engine.setStatus(fStatus);
743             engine.setOwner(fOwner);
744             if (fIncoming) {
745                 // check calls to the referenced (moved) element, adjust element
746
// visibility if necessary.
747
engine.searchPattern(new SubProgressMonitor(monitor, 1));
748                 adjustIncomingVisibility((SearchResultGroup[]) engine.getResults(), new SubProgressMonitor(monitor, 1));
749                 engine.clearResults();
750                 // If the moved element is a type: Adjust visibility of members
751
// of the type if they are accessed outside of the moved type
752
if (fReferenced instanceof IType) {
753                     final IType type= (IType) fReferenced;
754                     adjustMemberVisibility(type, new SubProgressMonitor(monitor, 1));
755                 }
756             }
757             if (fOutgoing) {
758                 /*
759                  * Search for the types, fields, and methods which
760                  * are called/acted upon inside the referenced element (the one
761                  * to be moved) and assure that they are also visible from
762                  * within the referencing element (the destination type (or
763                  * package if move to new type)).
764                  */

765                 engine.searchReferencedTypes(fReferenced, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
766                 engine.searchReferencedFields(fReferenced, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
767                 engine.searchReferencedMethods(fReferenced, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
768                 adjustOutgoingVisibility((SearchResultGroup[]) engine.getResults(), new SubProgressMonitor(monitor, 1));
769             }
770         } finally {
771             monitor.done();
772         }
773     }
774
775     /**
776      * Computes the visibility threshold for the referenced element.
777      *
778      * @param referencing the referencing element
779      * @param referenced the referenced element
780      * @param monitor the progress monitor to use
781      * @return the visibility keyword corresponding to the threshold, or <code>null</code> for default visibility
782      * @throws JavaModelException if the java elements could not be accessed
783      */

784     public ModifierKeyword getVisibilityThreshold(final IJavaElement referencing, final IMember referenced, final IProgressMonitor monitor) throws JavaModelException {
785         Assert.isTrue(!(referencing instanceof IInitializer));
786         Assert.isTrue(!(referenced instanceof IInitializer));
787         ModifierKeyword keyword= ModifierKeyword.PUBLIC_KEYWORD;
788         try {
789             monitor.beginTask("", 1); //$NON-NLS-1$
790
monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking);
791             final int referencingType= referencing.getElementType();
792             final int referencedType= referenced.getElementType();
793             switch (referencedType) {
794                 case IJavaElement.TYPE: {
795                     final IType typeReferenced= (IType) referenced;
796                     final ICompilationUnit referencedUnit= typeReferenced.getCompilationUnit();
797                     switch (referencingType) {
798                         case IJavaElement.TYPE: {
799                             keyword= thresholdTypeToType((IType) referencing, typeReferenced, monitor);
800                             break;
801                         }
802                         case IJavaElement.FIELD:
803                         case IJavaElement.METHOD: {
804                             final IMember member= (IMember) referencing;
805                             if (typeReferenced.equals(member.getDeclaringType()))
806                                 keyword= ModifierKeyword.PRIVATE_KEYWORD;
807                             else if (referencedUnit != null && referencedUnit.equals(member.getCompilationUnit()))
808                                 keyword= ModifierKeyword.PRIVATE_KEYWORD;
809                             else if (typeReferenced.getPackageFragment().equals(member.getDeclaringType().getPackageFragment()))
810                                 keyword= null;
811                             break;
812                         }
813                         case IJavaElement.PACKAGE_FRAGMENT: {
814                             final IPackageFragment fragment= (IPackageFragment) referencing;
815                             if (typeReferenced.getPackageFragment().equals(fragment))
816                                 keyword= null;
817                             break;
818                         }
819                         default:
820                             Assert.isTrue(false);
821                     }
822                     break;
823                 }
824                 case IJavaElement.FIELD: {
825                     final IField fieldReferenced= (IField) referenced;
826                     final ICompilationUnit referencedUnit= fieldReferenced.getCompilationUnit();
827                     switch (referencingType) {
828                         case IJavaElement.TYPE: {
829                             keyword= thresholdTypeToField((IType) referencing, fieldReferenced, monitor);
830                             break;
831                         }
832                         case IJavaElement.FIELD:
833                         case IJavaElement.METHOD: {
834                             final IMember member= (IMember) referencing;
835                             if (fieldReferenced.getDeclaringType().equals(member.getDeclaringType()))
836                                 keyword= ModifierKeyword.PRIVATE_KEYWORD;
837                             else if (referencedUnit != null && referencedUnit.equals(member.getCompilationUnit()))
838                                 keyword= ModifierKeyword.PRIVATE_KEYWORD;
839                             else if (fieldReferenced.getDeclaringType().getPackageFragment().equals(member.getDeclaringType().getPackageFragment()))
840                                 keyword= null;
841                             break;
842                         }
843                         case IJavaElement.PACKAGE_FRAGMENT: {
844                             final IPackageFragment fragment= (IPackageFragment) referencing;
845                             if (fieldReferenced.getDeclaringType().getPackageFragment().equals(fragment))
846                                 keyword= null;
847                             break;
848                         }
849                         default:
850                             Assert.isTrue(false);
851                     }
852                     break;
853                 }
854                 case IJavaElement.METHOD: {
855                     final IMethod methodReferenced= (IMethod) referenced;
856                     final ICompilationUnit referencedUnit= methodReferenced.getCompilationUnit();
857                     switch (referencingType) {
858                         case IJavaElement.TYPE: {
859                             keyword= thresholdTypeToMethod((IType) referencing, methodReferenced, monitor);
860                             break;
861                         }
862                         case IJavaElement.FIELD:
863                         case IJavaElement.METHOD: {
864                             final IMember member= (IMember) referencing;
865                             if (methodReferenced.getDeclaringType().equals(member.getDeclaringType()))
866                                 keyword= ModifierKeyword.PRIVATE_KEYWORD;
867                             else if (referencedUnit != null && referencedUnit.equals(member.getCompilationUnit()))
868                                 keyword= ModifierKeyword.PRIVATE_KEYWORD;
869                             else if (methodReferenced.getDeclaringType().getPackageFragment().equals(member.getDeclaringType().getPackageFragment()))
870                                 keyword= null;
871                             break;
872                         }
873                         case IJavaElement.PACKAGE_FRAGMENT: {
874                             final IPackageFragment fragment= (IPackageFragment) referencing;
875                             if (methodReferenced.getDeclaringType().getPackageFragment().equals(fragment))
876                                 keyword= null;
877                             break;
878                         }
879                         default:
880                             Assert.isTrue(false);
881                     }
882                     break;
883                 }
884                 default:
885                     Assert.isTrue(false);
886             }
887         } finally {
888             monitor.done();
889         }
890         return keyword;
891     }
892
893     /**
894      * Computes the visibility threshold for the referenced element.
895      *
896      * @param referencing the referencing element
897      * @param referenced the referenced element
898      * @param monitor the progress monitor to use
899      * @return the visibility keyword corresponding to the threshold, or <code>null</code> for default visibility
900      * @throws JavaModelException if the java elements could not be accessed
901      */

902     private ModifierKeyword computeOutgoingVisibilityThreshold(final IJavaElement referencing, final IMember referenced, final IProgressMonitor monitor) throws JavaModelException {
903         Assert.isTrue(referencing instanceof ICompilationUnit || referencing instanceof IType || referencing instanceof IPackageFragment);
904         Assert.isTrue(referenced instanceof IType || referenced instanceof IField || referenced instanceof IMethod);
905         ModifierKeyword keyword= ModifierKeyword.PUBLIC_KEYWORD;
906         try {
907             monitor.beginTask("", 1); //$NON-NLS-1$
908
monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking);
909             final int referencingType= referencing.getElementType();
910             final int referencedType= referenced.getElementType();
911             switch (referencedType) {
912                 case IJavaElement.TYPE: {
913                     final IType typeReferenced= (IType) referenced;
914                     switch (referencingType) {
915                         case IJavaElement.COMPILATION_UNIT: {
916                             final ICompilationUnit unit= (ICompilationUnit) referencing;
917                             final ICompilationUnit referencedUnit= typeReferenced.getCompilationUnit();
918                             if (referencedUnit != null && referencedUnit.equals(unit))
919                                 keyword= ModifierKeyword.PRIVATE_KEYWORD;
920                             else if (referencedUnit != null && referencedUnit.getParent().equals(unit.getParent()))
921                                 keyword= null;
922                             break;
923                         }
924                         case IJavaElement.TYPE: {
925                             keyword= thresholdTypeToType((IType) referencing, typeReferenced, monitor);
926                             break;
927                         }
928                         case IJavaElement.PACKAGE_FRAGMENT: {
929                             final IPackageFragment fragment= (IPackageFragment) referencing;
930                             if (typeReferenced.getPackageFragment().equals(fragment))
931                                 keyword= null;
932                             break;
933                         }
934                         default:
935                             Assert.isTrue(false);
936                     }
937                     break;
938                 }
939                 case IJavaElement.FIELD: {
940                     final IField fieldReferenced= (IField) referenced;
941                     final ICompilationUnit referencedUnit= fieldReferenced.getCompilationUnit();
942                     switch (referencingType) {
943                         case IJavaElement.COMPILATION_UNIT: {
944                             final ICompilationUnit unit= (ICompilationUnit) referencing;
945                             if (referencedUnit != null && referencedUnit.equals(unit))
946                                 keyword= ModifierKeyword.PRIVATE_KEYWORD;
947                             else if (referencedUnit != null && referencedUnit.getParent().equals(unit.getParent()))
948                                 keyword= null;
949                             break;
950                         }
951                         case IJavaElement.TYPE: {
952                             keyword= thresholdTypeToField((IType) referencing, fieldReferenced, monitor);
953                             break;
954                         }
955                         case IJavaElement.PACKAGE_FRAGMENT: {
956                             final IPackageFragment fragment= (IPackageFragment) referencing;
957                             if (fieldReferenced.getDeclaringType().getPackageFragment().equals(fragment))
958                                 keyword= null;
959                             break;
960                         }
961                         default:
962                             Assert.isTrue(false);
963                     }
964                     break;
965                 }
966                 case IJavaElement.METHOD: {
967                     final IMethod methodReferenced= (IMethod) referenced;
968                     final ICompilationUnit referencedUnit= methodReferenced.getCompilationUnit();
969                     switch (referencingType) {
970                         case IJavaElement.COMPILATION_UNIT: {
971                             final ICompilationUnit unit= (ICompilationUnit) referencing;
972                             if (referencedUnit != null && referencedUnit.equals(unit))
973                                 keyword= ModifierKeyword.PRIVATE_KEYWORD;
974                             else if (referencedUnit != null && referencedUnit.getParent().equals(unit.getParent()))
975                                 keyword= null;
976                             break;
977                         }
978                         case IJavaElement.TYPE: {
979                             keyword= thresholdTypeToMethod((IType) referencing, methodReferenced, monitor);
980                             break;
981                         }
982                         case IJavaElement.PACKAGE_FRAGMENT: {
983                             final IPackageFragment fragment= (IPackageFragment) referencing;
984                             if (methodReferenced.getDeclaringType().getPackageFragment().equals(fragment))
985                                 keyword= null;
986                             break;
987                         }
988                         default:
989                             Assert.isTrue(false);
990                     }
991                     break;
992                 }
993                 default:
994                     Assert.isTrue(false);
995             }
996         } finally {
997             monitor.done();
998         }
999         return keyword;
1000    }
1001
1002    /**
1003     * Returns the existing visibility adjustments (element type: Map <IMember, IVisibilityAdjustment>).
1004     *
1005     * @return the visibility adjustments
1006     */

1007    public final Map JavaDoc getAdjustments() {
1008        return fAdjustments;
1009    }
1010
1011    /**
1012     * Returns a compilation unit rewrite for the specified compilation unit.
1013     *
1014     * @param unit the compilation unit to get the rewrite for
1015     * @return the rewrite for the compilation unit
1016     */

1017    private CompilationUnitRewrite getCompilationUnitRewrite(final ICompilationUnit unit) {
1018        CompilationUnitRewrite rewrite= (CompilationUnitRewrite) fRewrites.get(unit);
1019        if (rewrite == null) {
1020            if (fOwner == null)
1021                rewrite= new CompilationUnitRewrite(unit);
1022            else
1023                rewrite= new CompilationUnitRewrite(fOwner, unit);
1024        }
1025        return rewrite;
1026    }
1027
1028    /**
1029     * Returns a cached type hierarchy for the specified type.
1030     *
1031     * @param type the type to get the hierarchy for
1032     * @param monitor the progress monitor to use
1033     * @return the type hierarchy
1034     * @throws JavaModelException if the type hierarchy could not be created
1035     */

1036    private ITypeHierarchy getTypeHierarchy(final IType type, final IProgressMonitor monitor) throws JavaModelException {
1037        ITypeHierarchy hierarchy= null;
1038        try {
1039            monitor.beginTask("", 1); //$NON-NLS-1$
1040
monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_checking);
1041            try {
1042                hierarchy= (ITypeHierarchy) fTypeHierarchies.get(type);
1043                if (hierarchy == null) {
1044                    if (fOwner == null)
1045                        hierarchy= type.newSupertypeHierarchy(new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
1046                    else
1047                        hierarchy= type.newSupertypeHierarchy(fOwner, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
1048                }
1049            } finally {
1050                monitor.done();
1051            }
1052        } finally {
1053            monitor.done();
1054        }
1055        return hierarchy;
1056    }
1057
1058    /**
1059     * Does the specified member need further visibility adjustment?
1060     *
1061     * @param member the member to test
1062     * @param threshold the visibility threshold to test for
1063     * @return <code>true</code> if the member needs further adjustment, <code>false</code> otherwise
1064     */

1065    private boolean needsVisibilityAdjustment(final IMember member, final ModifierKeyword threshold) {
1066        Assert.isNotNull(member);
1067        return needsVisibilityAdjustments(member, threshold, fAdjustments);
1068    }
1069
1070    /**
1071     * Rewrites the computed adjustments for the specified compilation unit.
1072     *
1073     * @param unit the compilation unit to rewrite the adjustments
1074     * @param monitor the progress monitor to use
1075     * @throws JavaModelException if an error occurs during search
1076     */

1077    public final void rewriteVisibility(final ICompilationUnit unit, final IProgressMonitor monitor) throws JavaModelException {
1078        try {
1079            monitor.beginTask("", fAdjustments.keySet().size()); //$NON-NLS-1$
1080
monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_adjusting);
1081            IMember member= null;
1082            IVisibilityAdjustment adjustment= null;
1083            for (final Iterator JavaDoc iterator= fAdjustments.keySet().iterator(); iterator.hasNext();) {
1084                member= (IMember) iterator.next();
1085                if (unit.equals(member.getCompilationUnit())) {
1086                    adjustment= (IVisibilityAdjustment) fAdjustments.get(member);
1087                    if (adjustment != null)
1088                        adjustment.rewriteVisibility(this, new SubProgressMonitor(monitor, 1));
1089                }
1090            }
1091        } finally {
1092            fTypeHierarchies.clear();
1093            monitor.done();
1094        }
1095    }
1096
1097    /**
1098     * Rewrites the computed adjustments.
1099     *
1100     * @param monitor the progress monitor to use
1101     * @throws JavaModelException if an error occurs during search
1102     */

1103    public final void rewriteVisibility(final IProgressMonitor monitor) throws JavaModelException {
1104        try {
1105            monitor.beginTask("", fAdjustments.keySet().size()); //$NON-NLS-1$
1106
monitor.setTaskName(RefactoringCoreMessages.MemberVisibilityAdjustor_adjusting);
1107            IMember member= null;
1108            IVisibilityAdjustment adjustment= null;
1109            for (final Iterator JavaDoc iterator= fAdjustments.keySet().iterator(); iterator.hasNext();) {
1110                member= (IMember) iterator.next();
1111                adjustment= (IVisibilityAdjustment) fAdjustments.get(member);
1112                if (adjustment != null)
1113                    adjustment.rewriteVisibility(this, new SubProgressMonitor(monitor, 1));
1114                if (monitor.isCanceled())
1115                    throw new OperationCanceledException();
1116            }
1117        } finally {
1118            fTypeHierarchies.clear();
1119            monitor.done();
1120        }
1121    }
1122
1123    /**
1124     * Sets the existing visibility adjustments to be taken into account (element type: Map <IMember, IVisibilityAdjustment>).
1125     * <p>
1126     * This method must be called before calling {@link MemberVisibilityAdjustor#adjustVisibility(IProgressMonitor)}. The default is to take no existing adjustments into account.
1127     *
1128     * @param adjustments the existing adjustments to set
1129     */

1130    public final void setAdjustments(final Map JavaDoc adjustments) {
1131        Assert.isNotNull(adjustments);
1132        fAdjustments= adjustments;
1133    }
1134
1135    /**
1136     * Sets the severity of failure messages.
1137     * <p>
1138     * This method must be called before calling {@link MemberVisibilityAdjustor#adjustVisibility(IProgressMonitor)}. The default is a status with value {@link RefactoringStatus#ERROR}.
1139     *
1140     * @param severity the severity of failure messages
1141     */

1142    public final void setFailureSeverity(final int severity) {
1143        Assert.isTrue(isStatusSeverity(severity));
1144    }
1145
1146    /**
1147     * Determines whether incoming references should be adjusted.
1148     * <p>
1149     * This method must be called before calling {@link MemberVisibilityAdjustor#adjustVisibility(IProgressMonitor)}. The default is to adjust incoming references.
1150     *
1151     * @param incoming <code>true</code> if incoming references should be adjusted, <code>false</code> otherwise
1152     */

1153    public final void setIncoming(final boolean incoming) {
1154        fIncoming= incoming;
1155    }
1156
1157    /**
1158     * Determines whether outgoing references should be adjusted.
1159     * <p>
1160     * This method must be called before calling {@link MemberVisibilityAdjustor#adjustVisibility(IProgressMonitor)}. The default is to adjust outgoing references.
1161     *
1162     * @param outgoing <code>true</code> if outgoing references should be adjusted, <code>false</code> otherwise
1163     */

1164    public final void setOutgoing(final boolean outgoing) {
1165        fOutgoing= outgoing;
1166    }
1167
1168    /**
1169     * Sets the AST rewrite to use for member visibility adjustments.
1170     * <p>
1171     * This method must be called before calling {@link MemberVisibilityAdjustor#adjustVisibility(IProgressMonitor)}. The default is to use a compilation unit rewrite.
1172     *
1173     * @param rewrite the AST rewrite to set
1174     * @param root the root of the AST used in the rewrite
1175     */

1176    public final void setRewrite(final ASTRewrite rewrite, final CompilationUnit root) {
1177        Assert.isTrue(rewrite == null || root != null);
1178        fRewrite= rewrite;
1179        fRoot= root;
1180    }
1181
1182    /**
1183     * Sets the compilation unit rewrites used by this adjustor (element type: Map <ICompilationUnit, CompilationUnitRewrite>).
1184     * <p>
1185     * This method must be called before calling {@link MemberVisibilityAdjustor#adjustVisibility(IProgressMonitor)}. The default is to use no existing rewrites.
1186     *
1187     * @param rewrites the map of compilation units to compilation unit rewrites to set
1188     */

1189    public final void setRewrites(final Map JavaDoc rewrites) {
1190        Assert.isNotNull(rewrites);
1191        fRewrites= rewrites;
1192    }
1193
1194    /**
1195     * Sets the incoming search scope used by this adjustor.
1196     * <p>
1197     * This method must be called before calling {@link MemberVisibilityAdjustor#adjustVisibility(IProgressMonitor)}. The default is the whole workspace as scope.
1198     *
1199     * @param scope the search scope to set
1200     */

1201    public final void setScope(final IJavaSearchScope scope) {
1202        Assert.isNotNull(scope);
1203        fScope= scope;
1204    }
1205
1206    /**
1207     * Sets the working copy owner used by this adjustor.
1208     * <p>
1209     * This method must be called before calling {@link MemberVisibilityAdjustor#adjustVisibility(IProgressMonitor)}. The default is to use none.
1210     *
1211     * @param owner the working copy owner, or <code>null</code> to use none
1212     */

1213    public final void setOwner(final WorkingCopyOwner owner) {
1214        fOwner= owner;
1215    }
1216
1217    /**
1218     * Sets the refactoring status used by this adjustor.
1219     * <p>
1220     * This method must be called before calling {@link MemberVisibilityAdjustor#adjustVisibility(IProgressMonitor)}. The default is a fresh status with status {@link RefactoringStatus#OK}.
1221     *
1222     * @param status the refactoring status to set
1223     */

1224    public final void setStatus(final RefactoringStatus status) {
1225        Assert.isNotNull(status);
1226        fStatus= status;
1227    }
1228
1229    /**
1230     * Sets the severity of visibility messages.
1231     * <p>
1232     * This method must be called before calling {@link MemberVisibilityAdjustor#adjustVisibility(IProgressMonitor)}. The default is a status with value {@link RefactoringStatus#WARNING}.
1233     *
1234     * @param severity the severity of visibility messages
1235     */

1236    public final void setVisibilitySeverity(final int severity) {
1237        Assert.isTrue(isStatusSeverity(severity));
1238        fVisibilitySeverity= severity;
1239    }
1240
1241    /**
1242     * Returns the visibility threshold from a type to a field.
1243     *
1244     * @param referencing the referencing type
1245     * @param referenced the referenced field
1246     * @param monitor the progress monitor to use
1247     * @return the visibility keyword corresponding to the threshold, or <code>null</code> for default visibility
1248     * @throws JavaModelException if the java elements could not be accessed
1249     */

1250    private ModifierKeyword thresholdTypeToField(final IType referencing, final IField referenced, final IProgressMonitor monitor) throws JavaModelException {
1251        ModifierKeyword keyword= ModifierKeyword.PUBLIC_KEYWORD;
1252        final ICompilationUnit referencedUnit= referenced.getCompilationUnit();
1253        if (referenced.getDeclaringType().equals(referencing))
1254            keyword= ModifierKeyword.PRIVATE_KEYWORD;
1255        else {
1256            final ITypeHierarchy hierarchy= getTypeHierarchy(referencing, new SubProgressMonitor(monitor, 1));
1257            final IType[] types= hierarchy.getSupertypes(referencing);
1258            IType superType= null;
1259            for (int index= 0; index < types.length; index++) {
1260                superType= types[index];
1261                if (superType.equals(referenced.getDeclaringType())) {
1262                    keyword= ModifierKeyword.PROTECTED_KEYWORD;
1263                    return keyword;
1264                }
1265            }
1266        }
1267        final ICompilationUnit typeUnit= referencing.getCompilationUnit();
1268        if (referencedUnit != null && referencedUnit.equals(typeUnit))
1269            keyword= ModifierKeyword.PRIVATE_KEYWORD;
1270        else if (referencedUnit != null && typeUnit != null && referencedUnit.getParent().equals(typeUnit.getParent()))
1271            keyword= null;
1272        return keyword;
1273    }
1274
1275    /**
1276     * Returns the visibility threshold from a type to a method.
1277     *
1278     * @param referencing the referencing type
1279     * @param referenced the referenced method
1280     * @param monitor the progress monitor to use
1281     * @return the visibility keyword corresponding to the threshold, or <code>null</code> for default visibility
1282     * @throws JavaModelException if the java elements could not be accessed
1283     */

1284    private ModifierKeyword thresholdTypeToMethod(final IType referencing, final IMethod referenced, final IProgressMonitor monitor) throws JavaModelException {
1285        final ICompilationUnit referencedUnit= referenced.getCompilationUnit();
1286        ModifierKeyword keyword= ModifierKeyword.PUBLIC_KEYWORD;
1287        if (referenced.getDeclaringType().equals(referencing))
1288            keyword= ModifierKeyword.PRIVATE_KEYWORD;
1289        else {
1290            final ITypeHierarchy hierarchy= getTypeHierarchy(referencing, new SubProgressMonitor(monitor, 1));
1291            final IType[] types= hierarchy.getSupertypes(referencing);
1292            IType superType= null;
1293            for (int index= 0; index < types.length; index++) {
1294                superType= types[index];
1295                if (superType.equals(referenced.getDeclaringType())) {
1296                    keyword= ModifierKeyword.PROTECTED_KEYWORD;
1297                    return keyword;
1298                }
1299            }
1300        }
1301        final ICompilationUnit typeUnit= referencing.getCompilationUnit();
1302        if (referencedUnit != null && referencedUnit.equals(typeUnit)) {
1303            if (referenced.getDeclaringType().getDeclaringType() != null)
1304                keyword= null;
1305            else
1306                keyword= ModifierKeyword.PRIVATE_KEYWORD;
1307        } else if (referencedUnit != null && referencedUnit.getParent().equals(typeUnit.getParent()))
1308            keyword= null;
1309        return keyword;
1310    }
1311
1312    /**
1313     * Returns the visibility threshold from a type to another type.
1314     *
1315     * @param referencing the referencing type
1316     * @param referenced the referenced type
1317     * @param monitor the progress monitor to use
1318     * @return the visibility keyword corresponding to the threshold, or <code>null</code> for default visibility
1319     * @throws JavaModelException if the java elements could not be accessed
1320     */

1321    private ModifierKeyword thresholdTypeToType(final IType referencing, final IType referenced, final IProgressMonitor monitor) throws JavaModelException {
1322        ModifierKeyword keyword= ModifierKeyword.PUBLIC_KEYWORD;
1323        final ICompilationUnit referencedUnit= referenced.getCompilationUnit();
1324        if (referencing.equals(referenced.getDeclaringType()))
1325            keyword= ModifierKeyword.PRIVATE_KEYWORD;
1326        else {
1327            final ITypeHierarchy hierarchy= getTypeHierarchy(referencing, new SubProgressMonitor(monitor, 1));
1328            final IType[] types= hierarchy.getSupertypes(referencing);
1329            IType superType= null;
1330            for (int index= 0; index < types.length; index++) {
1331                superType= types[index];
1332                if (superType.equals(referenced)) {
1333                    keyword= null;
1334                    return keyword;
1335                }
1336            }
1337        }
1338        final ICompilationUnit typeUnit= referencing.getCompilationUnit();
1339        if (referencedUnit != null && referencedUnit.equals(typeUnit)) {
1340            if (referenced.getDeclaringType() != null)
1341                keyword= null;
1342            else
1343                keyword= ModifierKeyword.PRIVATE_KEYWORD;
1344        } else if (referencedUnit != null && typeUnit != null && referencedUnit.getParent().equals(typeUnit.getParent()))
1345            keyword= null;
1346        return keyword;
1347    }
1348}
1349
Popular Tags