1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ide.eclipse.pdt.internal;
18 
19 import com.android.ide.eclipse.ddms.ISourceRevealer;
20 
21 import org.eclipse.core.resources.IProject;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.NullProgressMonitor;
24 import org.eclipse.jdt.core.IJavaProject;
25 import org.eclipse.jdt.core.IMethod;
26 import org.eclipse.jdt.core.IType;
27 import org.eclipse.jdt.core.JavaCore;
28 import org.eclipse.jdt.core.JavaModelException;
29 import org.eclipse.jdt.core.search.IJavaSearchConstants;
30 import org.eclipse.jdt.core.search.SearchEngine;
31 import org.eclipse.jdt.core.search.SearchMatch;
32 import org.eclipse.jdt.core.search.SearchParticipant;
33 import org.eclipse.jdt.core.search.SearchPattern;
34 import org.eclipse.jdt.core.search.SearchRequestor;
35 import org.eclipse.jdt.ui.JavaUI;
36 import org.eclipse.jdt.ui.actions.OpenJavaPerspectiveAction;
37 import org.eclipse.jface.text.BadLocationException;
38 import org.eclipse.jface.text.IDocument;
39 import org.eclipse.jface.text.IRegion;
40 import org.eclipse.ui.IEditorInput;
41 import org.eclipse.ui.IEditorPart;
42 import org.eclipse.ui.IPerspectiveRegistry;
43 import org.eclipse.ui.IWorkbench;
44 import org.eclipse.ui.IWorkbenchPage;
45 import org.eclipse.ui.IWorkbenchWindow;
46 import org.eclipse.ui.PartInitException;
47 import org.eclipse.ui.PlatformUI;
48 import org.eclipse.ui.WorkbenchException;
49 import org.eclipse.ui.texteditor.IDocumentProvider;
50 import org.eclipse.ui.texteditor.ITextEditor;
51 
52 /**
53  * Implementation of the com.android.ide.ddms.sourceRevealer extension point.
54  * This implementation is a copy of com.android.ide.eclipse.adt.SourceRevealer.
55  */
56 public class SourceRevealer extends DevTreeProjectProvider implements ISourceRevealer {
57 
58     @Override
reveal(String applicationName, String className, int line)59     public boolean reveal(String applicationName, String className, int line) {
60         IProject project = getProject();
61 
62         if (project != null) {
63             // Inner classes are pointless: All we need is the enclosing type to find the file,
64             // and the line number.
65             // Since the anonymous ones will cause IJavaProject#findType to fail, we remove
66             // all of them.
67             int pos = className.indexOf('$');
68             if (pos != -1) {
69                 className = className.substring(0, pos);
70             }
71 
72             // get the java project
73             IJavaProject javaProject = JavaCore.create(project);
74 
75             try {
76                 // look for the IType matching the class name.
77                 IType result = javaProject.findType(className);
78                 if (result != null && result.exists()) {
79                     // before we show the type in an editor window, we make sure the current
80                     // workbench page has an editor area (typically the ddms perspective doesn't).
81                     IWorkbench workbench = PlatformUI.getWorkbench();
82                     IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
83                     IWorkbenchPage page = window.getActivePage();
84                     if (page.isEditorAreaVisible() == false) {
85                         // no editor area? we open the java perspective.
86                         new OpenJavaPerspectiveAction().run();
87                     }
88 
89                     IEditorPart editor = JavaUI.openInEditor(result);
90                     if (editor instanceof ITextEditor) {
91                         // get the text editor that was just opened.
92                         ITextEditor textEditor = (ITextEditor)editor;
93 
94                         IEditorInput input = textEditor.getEditorInput();
95 
96                         // get the location of the line to show.
97                         IDocumentProvider documentProvider = textEditor.getDocumentProvider();
98                         IDocument document = documentProvider.getDocument(input);
99                         IRegion lineInfo = document.getLineInformation(line - 1);
100 
101                         // select and reveal the line.
102                         textEditor.selectAndReveal(lineInfo.getOffset(), lineInfo.getLength());
103                     }
104 
105                     return true;
106                 }
107             } catch (JavaModelException e) {
108             } catch (PartInitException e) {
109             } catch (BadLocationException e) {
110             }
111         }
112 
113         return false;
114     }
115 
116     @Override
revealMethod(String fqmn, String fileName, int lineNumber, String perspective)117     public boolean revealMethod(String fqmn, String fileName, int lineNumber, String perspective) {
118         SearchEngine se = new SearchEngine();
119         SearchPattern searchPattern = SearchPattern.createPattern(
120                 fqmn,
121                 IJavaSearchConstants.METHOD,
122                 IJavaSearchConstants.DECLARATIONS,
123                 SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
124         MethodSearchRequestor requestor = new MethodSearchRequestor(perspective);
125         try {
126             se.search(searchPattern,
127                     new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
128                     SearchEngine.createWorkspaceScope(),
129                     requestor,
130                     new NullProgressMonitor());
131         } catch (CoreException e) {
132             return false;
133         }
134 
135         return requestor.didMatch();
136     }
137 
138     private static class MethodSearchRequestor extends SearchRequestor {
139         private boolean mFoundMatch = false;
140         private final String mPerspective;
141 
MethodSearchRequestor(String perspective)142         public MethodSearchRequestor(String perspective) {
143             mPerspective = perspective;
144         }
145 
didMatch()146         public boolean didMatch() {
147             return mFoundMatch;
148         }
149 
150         @Override
acceptSearchMatch(SearchMatch match)151         public void acceptSearchMatch(SearchMatch match) throws CoreException {
152             Object element = match.getElement();
153             if (element instanceof IMethod && !mFoundMatch) {
154                 if (mPerspective != null) {
155                     SourceRevealer.switchToPerspective(mPerspective);
156                 }
157 
158                 IMethod method = (IMethod) element;
159                 JavaUI.openInEditor(method);
160                 mFoundMatch = true;
161             }
162         }
163     }
164 
switchToPerspective(String perspectiveId)165     public static void switchToPerspective(String perspectiveId) {
166         IWorkbench workbench = PlatformUI.getWorkbench();
167         IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
168         IPerspectiveRegistry perspectiveRegistry = workbench.getPerspectiveRegistry();
169         if (perspectiveId != null
170                 && perspectiveId.length() > 0
171                 && perspectiveRegistry.findPerspectiveWithId(perspectiveId) != null) {
172             try {
173                 workbench.showPerspective(perspectiveId, window);
174             } catch (WorkbenchException e) {
175                 // ignore exception, perspective won't be switched
176             }
177         }
178     }
179 
180 }
181