KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > javaeditor > selectionactions > GoToNextPreviousMemberAction


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

11 package org.eclipse.jdt.internal.ui.javaeditor.selectionactions;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18
19 import org.eclipse.jface.action.Action;
20 import org.eclipse.jface.text.ITextSelection;
21
22 import org.eclipse.ui.IEditorInput;
23 import org.eclipse.ui.PlatformUI;
24 import org.eclipse.ui.texteditor.IUpdate;
25
26 import org.eclipse.jdt.core.IInitializer;
27 import org.eclipse.jdt.core.IJavaElement;
28 import org.eclipse.jdt.core.IMember;
29 import org.eclipse.jdt.core.ISourceRange;
30 import org.eclipse.jdt.core.ISourceReference;
31 import org.eclipse.jdt.core.IType;
32 import org.eclipse.jdt.core.JavaModelException;
33 import org.eclipse.jdt.core.ToolFactory;
34 import org.eclipse.jdt.core.compiler.IScanner;
35 import org.eclipse.jdt.core.compiler.ITerminalSymbols;
36 import org.eclipse.jdt.core.compiler.InvalidInputException;
37
38 import org.eclipse.jdt.internal.corext.SourceRange;
39
40 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
41 import org.eclipse.jdt.internal.ui.JavaPlugin;
42 import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput;
43 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
44
45 public class GoToNextPreviousMemberAction extends Action implements IUpdate {
46
47     public static final String JavaDoc NEXT_MEMBER= "GoToNextMember"; //$NON-NLS-1$
48
public static final String JavaDoc PREVIOUS_MEMBER= "GoToPreviousMember"; //$NON-NLS-1$
49
private JavaEditor fEditor;
50     private boolean fIsGotoNext;
51
52     public static GoToNextPreviousMemberAction newGoToNextMemberAction(JavaEditor editor) {
53         String JavaDoc text= SelectionActionMessages.GotoNextMember_label;
54         return new GoToNextPreviousMemberAction(editor, text, true);
55     }
56
57     public static GoToNextPreviousMemberAction newGoToPreviousMemberAction(JavaEditor editor) {
58         String JavaDoc text= SelectionActionMessages.GotoPreviousMember_label;
59         return new GoToNextPreviousMemberAction(editor, text, false);
60     }
61
62     private GoToNextPreviousMemberAction(JavaEditor editor, String JavaDoc text, boolean isGotoNext) {
63         super(text);
64         Assert.isNotNull(editor);
65         fEditor= editor;
66         fIsGotoNext= isGotoNext;
67         update();
68         if (isGotoNext)
69             PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.GOTO_NEXT_MEMBER_ACTION);
70         else
71             PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.GOTO_PREVIOUS_MEMBER_ACTION);
72     }
73
74     /*
75      * This constructor is for testing purpose only.
76      */

77     public GoToNextPreviousMemberAction(boolean isSelectNext) {
78         super(""); //$NON-NLS-1$
79
fIsGotoNext= isSelectNext;
80     }
81
82     public void update() {
83         boolean enabled= false;
84         ISourceReference ref= getSourceReference();
85         if (ref != null) {
86             ISourceRange range;
87             try {
88                 range= ref.getSourceRange();
89                 enabled= range != null && range.getLength() > 0;
90             } catch (JavaModelException e) {
91                 // enabled= false;
92
}
93         }
94         setEnabled(enabled);
95     }
96
97     /* (non-JavaDoc)
98      * Method declared in IAction.
99      */

100     public final void run() {
101         ITextSelection selection= getTextSelection();
102         ISourceRange newRange= getNewSelectionRange(createSourceRange(selection), null);
103         // Check if new selection differs from current selection
104
if (selection.getOffset() == newRange.getOffset() && selection.getLength() == newRange.getLength())
105             return;
106         fEditor.selectAndReveal(newRange.getOffset(), newRange.getLength());
107     }
108
109     private IType[] getTypes() throws JavaModelException {
110         IEditorInput input= fEditor.getEditorInput();
111         if (input instanceof IClassFileEditorInput) {
112             return new IType[] { ((IClassFileEditorInput)input).getClassFile().getType() };
113         } else {
114             return JavaPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(input).getAllTypes();
115         }
116     }
117
118     private ISourceReference getSourceReference() {
119         IEditorInput input= fEditor.getEditorInput();
120         if (input instanceof IClassFileEditorInput) {
121             return ((IClassFileEditorInput)input).getClassFile();
122         } else {
123             return JavaPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(input);
124         }
125     }
126
127     private ITextSelection getTextSelection() {
128         return (ITextSelection)fEditor.getSelectionProvider().getSelection();
129     }
130
131     public ISourceRange getNewSelectionRange(ISourceRange oldSourceRange, IType[] types) {
132         try{
133             if (types == null)
134                 types= getTypes();
135             Integer JavaDoc[] offsetArray= createOffsetArray(types);
136             if (offsetArray.length == 0)
137                 return oldSourceRange;
138             Arrays.sort(offsetArray);
139             Integer JavaDoc oldOffset= new Integer JavaDoc(oldSourceRange.getOffset());
140             int index= Arrays.binarySearch(offsetArray, oldOffset);
141
142             if (fIsGotoNext)
143                 return createNewSourceRange(getNextOffset(index, offsetArray, oldOffset));
144             else
145                 return createNewSourceRange(getPreviousOffset(index, offsetArray, oldOffset));
146
147         } catch (JavaModelException e){
148             JavaPlugin.log(e); //dialog would be too heavy here
149
return oldSourceRange;
150         }
151     }
152
153     private static Integer JavaDoc getPreviousOffset(int index, Integer JavaDoc[] offsetArray, Integer JavaDoc oldOffset) {
154         if (index == -1)
155             return oldOffset;
156         if (index == 0)
157             return offsetArray[0];
158         if (index > 0)
159             return offsetArray[index - 1];
160         Assert.isTrue(index < -1);
161         int absIndex= Math.abs(index);
162         return offsetArray[absIndex - 2];
163     }
164
165     private static Integer JavaDoc getNextOffset(int index, Integer JavaDoc[] offsetArray, Integer JavaDoc oldOffset) {
166         if (index == -1)
167             return offsetArray[0];
168
169         if (index == 0){
170             if (offsetArray.length != 1)
171                 return offsetArray[1];
172             else
173                 return offsetArray[0];
174         }
175         if (index > 0){
176             if (index == offsetArray.length - 1)
177                 return oldOffset;
178             return offsetArray[index + 1];
179         }
180         Assert.isTrue(index < -1);
181         int absIndex= Math.abs(index);
182         if (absIndex > offsetArray.length)
183             return oldOffset;
184         else
185             return offsetArray[absIndex - 1];
186     }
187
188     private static ISourceRange createNewSourceRange(Integer JavaDoc offset){
189         return new SourceRange(offset.intValue(), 0);
190     }
191
192     private static Integer JavaDoc[] createOffsetArray(IType[] types) throws JavaModelException {
193         List JavaDoc result= new ArrayList JavaDoc();
194         for (int i= 0; i < types.length; i++) {
195             IType iType= types[i];
196             addOffset(result, iType.getNameRange().getOffset());
197             addOffset(result, iType.getSourceRange().getOffset() + iType.getSourceRange().getLength());
198             addMemberOffsetList(result, iType.getMethods());
199             addMemberOffsetList(result, iType.getFields());
200             addMemberOffsetList(result, iType.getInitializers());
201         }
202         return (Integer JavaDoc[]) result.toArray(new Integer JavaDoc[result.size()]);
203     }
204
205     private static void addMemberOffsetList(List JavaDoc result, IMember[] members) throws JavaModelException {
206         for (int i= 0; i < members.length; i++) {
207             addOffset(result, getOffset(members[i]));
208         }
209     }
210
211     private static int getOffset(IMember iMember) throws JavaModelException {
212         //special case
213
if (iMember.getElementType() == IJavaElement.INITIALIZER)
214             return firstOpeningBraceOffset((IInitializer)iMember);
215
216         if (iMember.getNameRange() != null && iMember.getNameRange().getOffset() >= 0)
217             return iMember.getNameRange().getOffset();
218         return iMember.getSourceRange().getOffset();
219     }
220
221     private static int firstOpeningBraceOffset(IInitializer iInitializer) throws JavaModelException {
222         try {
223             IScanner scanner= ToolFactory.createScanner(false, false, false, false);
224             scanner.setSource(iInitializer.getSource().toCharArray());
225             int token= scanner.getNextToken();
226             while (token != ITerminalSymbols.TokenNameEOF && token != ITerminalSymbols.TokenNameLBRACE)
227                 token= scanner.getNextToken();
228             if (token == ITerminalSymbols.TokenNameLBRACE)
229                 return iInitializer.getSourceRange().getOffset() + scanner.getCurrentTokenStartPosition() + scanner.getRawTokenSource().length;
230             return iInitializer.getSourceRange().getOffset();
231         } catch (InvalidInputException e) {
232             return iInitializer.getSourceRange().getOffset();
233         }
234     }
235
236     //-- private helper methods
237

238     private static ISourceRange createSourceRange(ITextSelection ts) {
239         return new SourceRange(ts.getOffset(), ts.getLength());
240     }
241
242     private static void addOffset(List JavaDoc result, int offset) {
243         if (offset >= 0)
244             result.add(new Integer JavaDoc(offset));
245     }
246 }
247
Popular Tags