fix #774 infinite loop in net.sourceforge.phpeclipse.builder.IdentifierIndexManager...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / viewsupport / JavaElementImageProvider.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 package net.sourceforge.phpdt.internal.ui.viewsupport;
12
13 import net.sourceforge.phpdt.core.Flags;
14 import net.sourceforge.phpdt.core.IField;
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.IMethod;
19 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
20 import net.sourceforge.phpdt.core.IType;
21 import net.sourceforge.phpdt.core.JavaModelException;
22 import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
23 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
24 import net.sourceforge.phpdt.ui.JavaElementImageDescriptor;
25 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
26
27 import org.eclipse.core.resources.IFile;
28 import org.eclipse.core.resources.IProject;
29 import org.eclipse.core.runtime.IAdaptable;
30 import org.eclipse.jface.resource.ImageDescriptor;
31 import org.eclipse.jface.util.Assert;
32 import org.eclipse.swt.graphics.Image;
33 import org.eclipse.swt.graphics.Point;
34 import org.eclipse.ui.ISharedImages;
35 import org.eclipse.ui.ide.IDE.SharedImages;
36 import org.eclipse.ui.model.IWorkbenchAdapter;
37
38 /**
39  * Default strategy of the Java plugin for the construction of Java element
40  * icons.
41  */
42 public class JavaElementImageProvider {
43
44         /**
45          * Flags for the JavaImageLabelProvider: Generate images with overlays.
46          */
47         public final static int OVERLAY_ICONS = 0x1;
48
49         /**
50          * Generate small sized images.
51          */
52         public final static int SMALL_ICONS = 0x2;
53
54         /**
55          * Use the 'light' style for rendering types.
56          */
57         public final static int LIGHT_TYPE_ICONS = 0x4;
58
59         public static final Point SMALL_SIZE = new Point(16, 16);
60
61         public static final Point BIG_SIZE = new Point(22, 16);
62
63         private static ImageDescriptor DESC_OBJ_PROJECT_CLOSED;
64
65         private static ImageDescriptor DESC_OBJ_PROJECT;
66
67         private static ImageDescriptor DESC_OBJ_FOLDER;
68         {
69                 ISharedImages images = PHPeclipsePlugin.getDefault().getWorkbench()
70                                 .getSharedImages();
71                 DESC_OBJ_PROJECT_CLOSED = images
72                                 .getImageDescriptor(SharedImages.IMG_OBJ_PROJECT_CLOSED);
73                 DESC_OBJ_PROJECT = images
74                                 .getImageDescriptor(SharedImages.IMG_OBJ_PROJECT);
75                 DESC_OBJ_FOLDER = images
76                                 .getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER);
77         }
78
79         private ImageDescriptorRegistry fRegistry;
80
81         public JavaElementImageProvider() {
82                 fRegistry = null; // lazy initialization
83         }
84
85         /**
86          * Returns the icon for a given element. The icon depends on the element
87          * type and element properties. If configured, overlay icons are constructed
88          * for <code>ISourceReference</code>s.
89          * 
90          * @param flags
91          *            Flags as defined by the JavaImageLabelProvider
92          */
93         public Image getImageLabel(Object element, int flags) {
94                 return getImageLabel(computeDescriptor(element, flags));
95         }
96
97         private Image getImageLabel(ImageDescriptor descriptor) {
98                 if (descriptor == null)
99                         return null;
100                 return getRegistry().get(descriptor);
101         }
102
103         private ImageDescriptorRegistry getRegistry() {
104                 if (fRegistry == null) {
105                         fRegistry = PHPeclipsePlugin.getImageDescriptorRegistry();
106                 }
107                 return fRegistry;
108         }
109
110         private ImageDescriptor computeDescriptor(Object element, int flags) {
111                 if (element instanceof IJavaElement) {
112                         return getJavaImageDescriptor((IJavaElement) element, flags);
113                 } else if (element instanceof IFile) {
114                         IFile file = (IFile) element;
115                         if ("java".equals(file.getFileExtension())) { //$NON-NLS-1$
116                                 return getCUResourceImageDescriptor(file, flags); // image for
117                                                                                                                                         // a CU not
118                                                                                                                                         // on the
119                                                                                                                                         // build
120                                                                                                                                         // path
121                         }
122                         return getWorkbenchImageDescriptor(file, flags);
123                 } else if (element instanceof IAdaptable) {
124                         return getWorkbenchImageDescriptor((IAdaptable) element, flags);
125                 }
126                 return null;
127         }
128
129         private static boolean showOverlayIcons(int flags) {
130                 return (flags & OVERLAY_ICONS) != 0;
131         }
132
133         private static boolean useSmallSize(int flags) {
134                 return (flags & SMALL_ICONS) != 0;
135         }
136
137         private static boolean useLightIcons(int flags) {
138                 return (flags & LIGHT_TYPE_ICONS) != 0;
139         }
140
141         /**
142          * Returns an image descriptor for a compilatio unit not on the class path.
143          * The descriptor includes overlays, if specified.
144          */
145         public ImageDescriptor getCUResourceImageDescriptor(IFile file, int flags) {
146                 Point size = useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE;
147                 return new JavaElementImageDescriptor(
148                                 PHPUiImages.DESC_OBJS_CUNIT_RESOURCE, 0, size);
149         }
150
151         /**
152          * Returns an image descriptor for a java element. The descriptor includes
153          * overlays, if specified.
154          */
155         public ImageDescriptor getJavaImageDescriptor(IJavaElement element,
156                         int flags) {
157                 int adornmentFlags = computeJavaAdornmentFlags(element, flags);
158                 Point size = useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE;
159                 return new JavaElementImageDescriptor(getBaseImageDescriptor(element,
160                                 flags), adornmentFlags, size);
161         }
162
163         /**
164          * Returns an image descriptor for a IAdaptable. The descriptor includes
165          * overlays, if specified (only error ticks apply). Returns
166          * <code>null</code> if no image could be found.
167          */
168         public ImageDescriptor getWorkbenchImageDescriptor(IAdaptable adaptable,
169                         int flags) {
170                 IWorkbenchAdapter wbAdapter = (IWorkbenchAdapter) adaptable
171                                 .getAdapter(IWorkbenchAdapter.class);
172                 if (wbAdapter == null) {
173                         return null;
174                 }
175                 ImageDescriptor descriptor = wbAdapter.getImageDescriptor(adaptable);
176                 if (descriptor == null) {
177                         return null;
178                 }
179
180                 Point size = useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE;
181                 return new JavaElementImageDescriptor(descriptor, 0, size);
182         }
183
184         // ---- Computation of base image key
185         // -------------------------------------------------
186
187         /**
188          * Returns an image descriptor for a java element. This is the base image,
189          * no overlays.
190          */
191         public ImageDescriptor getBaseImageDescriptor(IJavaElement element,
192                         int renderFlags) {
193                 IType type = null;
194                 boolean isInterface = false;
195                 try {
196                         switch (element.getElementType()) {
197                         case IJavaElement.INITIALIZER:
198                                 return PHPUiImages.DESC_MISC_PRIVATE; // 23479
199                         case IJavaElement.METHOD:
200                                 IMember member = (IMember) element;
201                                 type = member.getDeclaringType();
202                                 isInterface = (type != null)
203                                                 && member.getDeclaringType().isInterface();
204                                 return getMethodImageDescriptor(isInterface, member.getFlags());
205                         case IJavaElement.FIELD:
206                                 IField field = (IField) element;
207                                 return getFieldImageDescriptor(field.getDeclaringType()
208                                                 .isInterface(), field.getFlags());
209
210                         case IJavaElement.PACKAGE_DECLARATION:
211                                 return PHPUiImages.DESC_OBJS_PACKDECL;
212
213                         case IJavaElement.IMPORT_DECLARATION:
214                                 return PHPUiImages.DESC_OBJS_IMPDECL;
215
216                         case IJavaElement.IMPORT_CONTAINER:
217                                 return PHPUiImages.DESC_OBJS_IMPCONT;
218
219                         case IJavaElement.TYPE: {
220                                 type = (IType) element;
221                                 isInterface = type.isInterface();
222
223                                 if (useLightIcons(renderFlags)) {
224                                         return isInterface ? PHPUiImages.DESC_OBJS_INTERFACEALT
225                                                         : PHPUiImages.DESC_OBJS_CLASSALT;
226                                 }
227                                 boolean isInner = type.getDeclaringType() != null;
228                                 return getTypeImageDescriptor(isInterface, isInner, type
229                                                 .getFlags());
230                         }
231
232                         case IJavaElement.PACKAGE_FRAGMENT_ROOT: {
233                                 IPackageFragmentRoot root = (IPackageFragmentRoot) element;
234                                 // if (root.isArchive()) {
235                                 // IPath attach= root.getSourceAttachmentPath();
236                                 // if (root.isExternal()) {
237                                 // if (attach == null) {
238                                 // return PHPUiImages.DESC_OBJS_EXTJAR;
239                                 // } else {
240                                 // return PHPUiImages.DESC_OBJS_EXTJAR_WSRC;
241                                 // }
242                                 // } else {
243                                 // if (attach == null) {
244                                 // return PHPUiImages.DESC_OBJS_JAR;
245                                 // } else {
246                                 // return PHPUiImages.DESC_OBJS_JAR_WSRC;
247                                 // }
248                                 // }
249                                 // } else {
250                                 return PHPUiImages.DESC_OBJS_PACKFRAG_ROOT;
251                                 // }
252                         }
253
254                         case IJavaElement.PACKAGE_FRAGMENT:
255                                 return getPackageFragmentIcon(element, renderFlags);
256
257                         case IJavaElement.COMPILATION_UNIT:
258                                 return PHPUiImages.DESC_OBJS_CUNIT;
259
260                         case IJavaElement.CLASS_FILE:
261                                 /*
262                                  * this is too expensive for large packages try { IClassFile
263                                  * cfile= (IClassFile)element; if (cfile.isClass()) return
264                                  * PHPUiImages.IMG_OBJS_CFILECLASS; return
265                                  * PHPUiImages.IMG_OBJS_CFILEINT; } catch(JavaModelException e) { //
266                                  * fall through; }
267                                  */
268                                 return PHPUiImages.DESC_OBJS_CFILE;
269
270                         case IJavaElement.JAVA_PROJECT:
271                                 IJavaProject jp = (IJavaProject) element;
272                                 if (jp.getProject().isOpen()) {
273                                         IProject project = jp.getProject();
274                                         IWorkbenchAdapter adapter = (IWorkbenchAdapter) project
275                                                         .getAdapter(IWorkbenchAdapter.class);
276                                         if (adapter != null) {
277                                                 ImageDescriptor result = adapter
278                                                                 .getImageDescriptor(project);
279                                                 if (result != null)
280                                                         return result;
281                                         }
282                                         return DESC_OBJ_PROJECT;
283                                 }
284                                 return DESC_OBJ_PROJECT_CLOSED;
285
286                         case IJavaElement.JAVA_MODEL:
287                                 return PHPUiImages.DESC_OBJS_JAVA_MODEL;
288                         }
289
290                         Assert.isTrue(false, PHPUIMessages
291                                         .getString("JavaImageLabelprovider.assert.wrongImage")); //$NON-NLS-1$
292                         return null; //$NON-NLS-1$
293
294                 } catch (JavaModelException e) {
295                         if (e.isDoesNotExist())
296                                 return PHPUiImages.DESC_OBJS_UNKNOWN;
297                         PHPeclipsePlugin.log(e);
298                         return PHPUiImages.DESC_OBJS_GHOST;
299                 }
300         }
301
302         protected ImageDescriptor getPackageFragmentIcon(IJavaElement element,
303                         int renderFlags) throws JavaModelException {
304                 // IPackageFragment fragment= (IPackageFragment)element;
305                 // boolean containsJavaElements= false;
306                 // try {
307                 // containsJavaElements= fragment.hasChildren();
308                 // } catch(JavaModelException e) {
309                 // // assuming no children;
310                 // }
311                 // if(!containsJavaElements && (fragment.getNonJavaResources().length >
312                 // 0))
313                 // return PHPUiImages.DESC_OBJS_EMPTY_PACKAGE_RESOURCES;
314                 // else if (!containsJavaElements)
315                 // return PHPUiImages.DESC_OBJS_EMPTY_PACKAGE;
316                 return PHPUiImages.DESC_OBJS_PACKAGE;
317         }
318
319         public void dispose() {
320         }
321
322         // ---- Methods to compute the adornments flags
323         // ---------------------------------
324
325         private int computeJavaAdornmentFlags(IJavaElement element, int renderFlags) {
326                 int flags = 0;
327                 if (showOverlayIcons(renderFlags) && element instanceof IMember) {
328                         try {
329                                 IMember member = (IMember) element;
330
331                                 if (element.getElementType() == IJavaElement.METHOD
332                                                 && ((IMethod) element).isConstructor())
333                                         flags |= JavaElementImageDescriptor.CONSTRUCTOR;
334
335                                 int modifiers = member.getFlags();
336                                 if (Flags.isAbstract(modifiers) && confirmAbstract(member))
337                                         flags |= JavaElementImageDescriptor.ABSTRACT;
338                                 if (Flags.isFinal(modifiers) || isInterfaceField(member))
339                                         flags |= JavaElementImageDescriptor.FINAL;
340                                 // if (Flags.isSynchronized(modifiers) &&
341                                 // confirmSynchronized(member))
342                                 // flags |= JavaElementImageDescriptor.SYNCHRONIZED;
343                                 if (Flags.isStatic(modifiers) || isInterfaceField(member))
344                                         flags |= JavaElementImageDescriptor.STATIC;
345
346                                 // if (member.getElementType() == IJavaElement.TYPE) {
347                                 // if (JavaModelUtil.hasMainMethod((IType) member)) {
348                                 // flags |= JavaElementImageDescriptor.RUNNABLE;
349                                 // }
350                                 // }
351                         } catch (JavaModelException e) {
352                                 // do nothing. Can't compute runnable adornment or get flags
353                         }
354                 }
355                 return flags;
356         }
357
358         private static boolean confirmAbstract(IMember element)
359                         throws JavaModelException {
360                 // never show the abstract symbol on interfaces or members in interfaces
361                 if (element.getElementType() == IJavaElement.TYPE) {
362                         return ((IType) element).isClass();
363                 }
364                 return element.getDeclaringType().isClass();
365         }
366
367         private static boolean isInterfaceField(IMember element)
368                         throws JavaModelException {
369                 // always show the final && static symbol on interface fields
370                 if (element.getElementType() == IJavaElement.FIELD) {
371                         return element.getDeclaringType().isInterface();
372                 }
373                 return false;
374         }
375
376         private static boolean confirmSynchronized(IJavaElement member) {
377                 // Synchronized types are allowed but meaningless.
378                 return member.getElementType() != IJavaElement.TYPE;
379         }
380
381         public static ImageDescriptor getMethodImageDescriptor(
382                         boolean isInInterface, int flags) {
383                 if (Flags.isPublic(flags) || isInInterface)
384                         return PHPUiImages.DESC_MISC_PUBLIC;
385                 if (Flags.isProtected(flags))
386                         return PHPUiImages.DESC_MISC_PROTECTED;
387                 if (Flags.isPrivate(flags))
388                         return PHPUiImages.DESC_MISC_PRIVATE;
389
390                 return PHPUiImages.DESC_MISC_DEFAULT;
391         }
392
393         public static ImageDescriptor getFieldImageDescriptor(
394                         boolean isInInterface, int flags) {
395                 if (Flags.isPublic(flags) || isInInterface)
396                         return PHPUiImages.DESC_FIELD_PUBLIC;
397                 if (Flags.isProtected(flags))
398                         return PHPUiImages.DESC_FIELD_PROTECTED;
399                 if (Flags.isPrivate(flags))
400                         return PHPUiImages.DESC_FIELD_PRIVATE;
401
402                 return PHPUiImages.DESC_FIELD_DEFAULT;
403         }
404
405         public static ImageDescriptor getTypeImageDescriptor(boolean isInterface,
406                         boolean isInner, int flags) {
407                 if (isInner) {
408                         if (isInterface) {
409                                 return getInnerInterfaceImageDescriptor(flags);
410                         } else {
411                                 return getInnerClassImageDescriptor(flags);
412                         }
413                 } else {
414                         if (isInterface) {
415                                 return getInterfaceImageDescriptor(flags);
416                         } else {
417                                 return getClassImageDescriptor(flags);
418                         }
419                 }
420         }
421
422         private static ImageDescriptor getClassImageDescriptor(int flags) {
423                 if (Flags.isPublic(flags) || Flags.isProtected(flags)
424                                 || Flags.isPrivate(flags))
425                         return PHPUiImages.DESC_OBJS_CLASS;
426                 else
427                         return PHPUiImages.DESC_OBJS_CLASS_DEFAULT;
428         }
429
430         private static ImageDescriptor getInnerClassImageDescriptor(int flags) {
431                 if (Flags.isPublic(flags))
432                         return PHPUiImages.DESC_OBJS_INNER_CLASS_PUBLIC;
433                 else if (Flags.isPrivate(flags))
434                         return PHPUiImages.DESC_OBJS_INNER_CLASS_PRIVATE;
435                 else if (Flags.isProtected(flags))
436                         return PHPUiImages.DESC_OBJS_INNER_CLASS_PROTECTED;
437                 else
438                         return PHPUiImages.DESC_OBJS_INNER_CLASS_DEFAULT;
439         }
440
441         private static ImageDescriptor getInterfaceImageDescriptor(int flags) {
442                 if (Flags.isPublic(flags) || Flags.isProtected(flags)
443                                 || Flags.isPrivate(flags))
444                         return PHPUiImages.DESC_OBJS_INTERFACE;
445                 else
446                         return PHPUiImages.DESC_OBJS_INTERFACE_DEFAULT;
447         }
448
449         private static ImageDescriptor getInnerInterfaceImageDescriptor(int flags) {
450                 if (Flags.isPublic(flags))
451                         return PHPUiImages.DESC_OBJS_INNER_INTERFACE_PUBLIC;
452                 else if (Flags.isPrivate(flags))
453                         return PHPUiImages.DESC_OBJS_INNER_INTERFACE_PRIVATE;
454                 else if (Flags.isProtected(flags))
455                         return PHPUiImages.DESC_OBJS_INNER_INTERFACE_PROTECTED;
456                 else
457                         return PHPUiImages.DESC_OBJS_INTERFACE_DEFAULT;
458         }
459 }