fix #774 infinite loop in net.sourceforge.phpeclipse.builder.IdentifierIndexManager...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / EditorUtility.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpeclipse.phpeditor;
13
14 import net.sourceforge.phpdt.core.ICompilationUnit;
15 import net.sourceforge.phpdt.core.IJavaElement;
16 import net.sourceforge.phpdt.core.IJavaProject;
17 import net.sourceforge.phpdt.core.IMember;
18 import net.sourceforge.phpdt.core.IWorkingCopy;
19 import net.sourceforge.phpdt.core.JavaCore;
20 import net.sourceforge.phpdt.core.JavaModelException;
21 import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
22 import net.sourceforge.phpdt.ui.JavaUI;
23 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
24
25 import org.eclipse.core.resources.IFile;
26 import org.eclipse.core.resources.IProject;
27 import org.eclipse.core.resources.IResource;
28 import org.eclipse.jface.action.Action;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.ui.IEditorDescriptor;
31 import org.eclipse.ui.IEditorInput;
32 import org.eclipse.ui.IEditorPart;
33 import org.eclipse.ui.IEditorRegistry;
34 import org.eclipse.ui.IFileEditorInput;
35 import org.eclipse.ui.IWorkbenchPage;
36 import org.eclipse.ui.PartInitException;
37 import org.eclipse.ui.PlatformUI;
38 import org.eclipse.ui.ide.IDE;
39 import org.eclipse.ui.part.FileEditorInput;
40 import org.eclipse.ui.texteditor.ITextEditor;
41
42 /**
43  * A number of routines for working with JavaElements in editors
44  * 
45  * Use 'isOpenInEditor' to test if an element is already open in a editor Use
46  * 'openInEditor' to force opening an element in a editor With 'getWorkingCopy'
47  * you get the working copy (element in the editor) of an element
48  */
49 public class EditorUtility {
50
51         public static boolean isEditorInput(Object element, IEditorPart editor) {
52                 if (editor != null) {
53                         try {
54                                 return editor.getEditorInput().equals(getEditorInput(element));
55                         } catch (JavaModelException x) {
56                                 PHPeclipsePlugin.log(x.getStatus());
57                         }
58                 }
59                 return false;
60         }
61
62         /**
63          * Tests if a cu is currently shown in an editor
64          * 
65          * @return the IEditorPart if shown, null if element is not open in an
66          *         editor
67          */
68         public static IEditorPart isOpenInEditor(Object inputElement) {
69                 IEditorInput input = null;
70
71                 try {
72                         input = getEditorInput(inputElement);
73                 } catch (JavaModelException x) {
74                         PHPeclipsePlugin.log(x.getStatus());
75                 }
76
77                 if (input != null) {
78                         IWorkbenchPage p = PHPeclipsePlugin.getActivePage();
79                         if (p != null) {
80                                 return p.findEditor(input);
81                         }
82                 }
83
84                 return null;
85         }
86
87         /**
88          * Opens a Java editor for an element such as <code>IJavaElement</code>,
89          * <code>IFile</code>, or <code>IStorage</code>. The editor is
90          * activated by default.
91          * 
92          * @return the IEditorPart or null if wrong element type or opening failed
93          */
94         public static IEditorPart openInEditor(Object inputElement)
95                         throws JavaModelException, PartInitException {
96                 return openInEditor(inputElement, true);
97         }
98
99         /**
100          * Opens a Java editor for an element (IJavaElement, IFile, IStorage...)
101          * 
102          * @return the IEditorPart or null if wrong element type or opening failed
103          */
104         public static IEditorPart openInEditor(Object inputElement, boolean activate)
105                         throws JavaModelException, PartInitException {
106
107                 if (inputElement instanceof IFile)
108                         return openInEditor((IFile) inputElement, activate);
109
110                 IEditorInput input = getEditorInput(inputElement);
111                 if (input instanceof IFileEditorInput) {
112                         IFileEditorInput fileInput = (IFileEditorInput) input;
113                         return openInEditor(fileInput.getFile(), activate);
114                 }
115
116                 if (input != null)
117                         return openInEditor(input, getEditorID(input, inputElement),
118                                         activate);
119
120                 return null;
121         }
122
123         /**
124          * Selects a Java Element in an editor
125          */
126         public static void revealInEditor(IEditorPart part, IJavaElement element) {
127                 if (element != null && part instanceof PHPEditor) {
128                         ((PHPEditor) part).setSelection(element);
129                 }
130         }
131
132         private static IEditorPart openInEditor(IFile file, boolean activate)
133                         throws PartInitException {
134                 if (file != null) {
135                         IWorkbenchPage p = PHPeclipsePlugin.getActivePage();
136                         if (p != null) {
137                                 IEditorPart editorPart = IDE.openEditor(p, file, activate);
138                                 initializeHighlightRange(editorPart);
139                                 return editorPart;
140                         }
141                 }
142                 return null;
143         }
144
145         private static IEditorPart openInEditor(IEditorInput input,
146                         String editorID, boolean activate) throws PartInitException {
147                 if (input != null) {
148                         IWorkbenchPage p = PHPeclipsePlugin.getActivePage();
149                         if (p != null) {
150                                 IEditorPart editorPart = p
151                                                 .openEditor(input, editorID, activate);
152                                 initializeHighlightRange(editorPart);
153                                 return editorPart;
154                         }
155                 }
156                 return null;
157         }
158
159         private static void initializeHighlightRange(IEditorPart editorPart) {
160                 if (editorPart instanceof ITextEditor) {
161                         TogglePresentationAction toggleAction = new TogglePresentationAction();
162                         // Initialize editor
163                         toggleAction.setEditor((ITextEditor) editorPart);
164                         // Reset action
165                         toggleAction.setEditor(null);
166                 }
167         }
168
169         /**
170          * @deprecated Made it public again for java debugger UI.
171          */
172         public static String getEditorID(IEditorInput input, Object inputObject) {
173                 IEditorRegistry registry = PlatformUI.getWorkbench()
174                                 .getEditorRegistry();
175                 IEditorDescriptor descriptor = registry.getDefaultEditor(input
176                                 .getName());
177                 if (descriptor != null)
178                         return descriptor.getId();
179                 return null;
180         }
181
182         private static IEditorInput getEditorInput(IJavaElement element)
183                         throws JavaModelException {
184                 while (element != null) {
185                         if (element instanceof IWorkingCopy
186                                         && ((IWorkingCopy) element).isWorkingCopy())
187                                 element = ((IWorkingCopy) element).getOriginalElement();
188
189                         if (element instanceof ICompilationUnit) {
190                                 ICompilationUnit unit = (ICompilationUnit) element;
191                                 IResource resource = unit.getResource();
192                                 if (resource instanceof IFile)
193                                         return new FileEditorInput((IFile) resource);
194                         }
195
196                         // if (element instanceof IClassFile)
197                         // return new InternalClassFileEditorInput((IClassFile) element);
198                         //                      
199                         element = element.getParent();
200                 }
201
202                 return null;
203         }
204
205         public static IEditorInput getEditorInput(Object input)
206                         throws JavaModelException {
207
208                 if (input instanceof IJavaElement)
209                         return getEditorInput((IJavaElement) input);
210
211                 if (input instanceof IFile)
212                         return new FileEditorInput((IFile) input);
213
214                 // if (input instanceof IStorage)
215                 // return new JarEntryEditorInput((IStorage)input);
216
217                 return null;
218         }
219
220         /**
221          * If the current active editor edits a java element return it, else return
222          * null
223          */
224         public static IJavaElement getActiveEditorJavaInput() {
225                 IWorkbenchPage page = PHPeclipsePlugin.getActivePage();
226                 if (page != null) {
227                         IEditorPart part = page.getActiveEditor();
228                         if (part != null) {
229                                 IEditorInput editorInput = part.getEditorInput();
230                                 if (editorInput != null) {
231                                         return (IJavaElement) editorInput
232                                                         .getAdapter(IJavaElement.class);
233                                 }
234                         }
235                 }
236                 return null;
237         }
238
239         /**
240          * Gets the working copy of an compilation unit opened in an editor
241          * 
242          * @param part
243          *            the editor part
244          * @param cu
245          *            the original compilation unit (or another working copy)
246          * @return the working copy of the compilation unit, or null if not found
247          */
248         public static ICompilationUnit getWorkingCopy(ICompilationUnit cu) {
249                 if (cu == null)
250                         return null;
251                 if (cu.isWorkingCopy())
252                         return cu;
253
254                 return (ICompilationUnit) cu.findSharedWorkingCopy(JavaUI
255                                 .getBufferFactory());
256         }
257
258         /**
259          * Gets the working copy of an member opened in an editor
260          * 
261          * @param member
262          *            the original member or a member in a working copy
263          * @return the corresponding member in the shared working copy or
264          *         <code>null</code> if not found
265          */
266         public static IMember getWorkingCopy(IMember member)
267                         throws JavaModelException {
268                 ICompilationUnit cu = member.getCompilationUnit();
269                 if (cu != null) {
270                         ICompilationUnit workingCopy = getWorkingCopy(cu);
271                         if (workingCopy != null) {
272                                 return JavaModelUtil.findMemberInCompilationUnit(workingCopy,
273                                                 member);
274                         }
275                 }
276                 return null;
277         }
278
279         /**
280          * Returns the compilation unit for the given java element.
281          * 
282          * @param element
283          *            the java element whose compilation unit is searched for
284          * @return the compilation unit of the given java element
285          */
286         private static ICompilationUnit getCompilationUnit(IJavaElement element) {
287
288                 if (element == null)
289                         return null;
290
291                 if (element instanceof IMember)
292                         return ((IMember) element).getCompilationUnit();
293
294                 int type = element.getElementType();
295                 if (IJavaElement.COMPILATION_UNIT == type)
296                         return (ICompilationUnit) element;
297                 if (IJavaElement.CLASS_FILE == type)
298                         return null;
299
300                 return getCompilationUnit(element.getParent());
301         }
302
303         /**
304          * Returns the working copy of the given java element.
305          * 
306          * @param javaElement
307          *            the javaElement for which the working copyshould be found
308          * @param reconcile
309          *            indicates whether the working copy must be reconcile prior to
310          *            searching it
311          * @return the working copy of the given element or <code>null</code> if
312          *         none
313          */
314         public static IJavaElement getWorkingCopy(IJavaElement element,
315                         boolean reconcile) throws JavaModelException {
316                 ICompilationUnit unit = getCompilationUnit(element);
317                 if (unit == null)
318                         return null;
319
320                 if (unit.isWorkingCopy())
321                         return element;
322
323                 ICompilationUnit workingCopy = getWorkingCopy(unit);
324                 if (workingCopy != null) {
325                         if (reconcile) {
326                                 synchronized (workingCopy) {
327                                         workingCopy.reconcile();
328                                         return JavaModelUtil.findInCompilationUnit(workingCopy,
329                                                         element);
330                                 }
331                         } else {
332                                 return JavaModelUtil
333                                                 .findInCompilationUnit(workingCopy, element);
334                         }
335                 }
336
337                 return null;
338         }
339
340         /**
341          * Maps the localized modifier name to a code in the same manner as
342          * #findModifier.
343          * 
344          * @return the SWT modifier bit, or <code>0</code> if no match was found
345          * @see findModifier
346          * @since 2.1.1
347          */
348         public static int findLocalizedModifier(String token) {
349                 if (token == null)
350                         return 0;
351
352                 if (token.equalsIgnoreCase(Action.findModifierString(SWT.CTRL)))
353                         return SWT.CTRL;
354                 if (token.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT)))
355                         return SWT.SHIFT;
356                 if (token.equalsIgnoreCase(Action.findModifierString(SWT.ALT)))
357                         return SWT.ALT;
358                 if (token.equalsIgnoreCase(Action.findModifierString(SWT.COMMAND)))
359                         return SWT.COMMAND;
360
361                 return 0;
362         }
363
364         /**
365          * Returns the modifier string for the given SWT modifier modifier bits.
366          * 
367          * @param stateMask
368          *            the SWT modifier bits
369          * @return the modifier string
370          * @since 2.1.1
371          */
372         public static String getModifierString(int stateMask) {
373                 String modifierString = ""; //$NON-NLS-1$
374                 if ((stateMask & SWT.CTRL) == SWT.CTRL)
375                         modifierString = appendModifierString(modifierString, SWT.CTRL);
376                 if ((stateMask & SWT.ALT) == SWT.ALT)
377                         modifierString = appendModifierString(modifierString, SWT.ALT);
378                 if ((stateMask & SWT.SHIFT) == SWT.SHIFT)
379                         modifierString = appendModifierString(modifierString, SWT.SHIFT);
380                 if ((stateMask & SWT.COMMAND) == SWT.COMMAND)
381                         modifierString = appendModifierString(modifierString, SWT.COMMAND);
382
383                 return modifierString;
384         }
385
386         /**
387          * Appends to modifier string of the given SWT modifier bit to the given
388          * modifierString.
389          * 
390          * @param modifierString
391          *            the modifier string
392          * @param modifier
393          *            an int with SWT modifier bit
394          * @return the concatenated modifier string
395          * @since 2.1.1
396          */
397         private static String appendModifierString(String modifierString,
398                         int modifier) {
399                 if (modifierString == null)
400                         modifierString = ""; //$NON-NLS-1$
401                 String newModifierString = Action.findModifierString(modifier);
402                 if (modifierString.length() == 0)
403                         return newModifierString;
404                 return PHPEditorMessages
405                                 .getFormattedString(
406                                                 "EditorUtility.concatModifierStrings", new String[] { modifierString, newModifierString }); //$NON-NLS-1$
407         }
408
409         /**
410          * Returns the Java project for a given editor input or <code>null</code>
411          * if no corresponding Java project exists.
412          * 
413          * @param input
414          *            the editor input
415          * @return the corresponding Java project
416          * 
417          * @since 3.0
418          */
419         public static IJavaProject getJavaProject(IEditorInput input) {
420                 IJavaProject jProject = null;
421                 if (input instanceof IFileEditorInput) {
422                         IProject project = ((IFileEditorInput) input).getFile()
423                                         .getProject();
424                         if (project != null) {
425                                 jProject = JavaCore.create(project);
426                                 if (!jProject.exists())
427                                         jProject = null;
428                         }
429                 }
430                 // else if (input instanceof IClassFileEditorInput) {
431                 // jProject=
432                 // ((IClassFileEditorInput)input).getClassFile().getJavaProject();
433                 // }
434                 return jProject;
435         }
436 }