fix #774 infinite loop in net.sourceforge.phpeclipse.builder.IdentifierIndexManager...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / filters / FilterDescriptor.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 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.filters;
12
13 import java.text.Collator;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Set;
19
20 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
21
22 import org.eclipse.core.runtime.IConfigurationElement;
23 import org.eclipse.core.runtime.IExtensionRegistry;
24 import org.eclipse.core.runtime.ISafeRunnable;
25 import org.eclipse.core.runtime.Platform;
26 import org.eclipse.jface.util.Assert;
27 import org.eclipse.jface.util.SafeRunnable;
28 import org.eclipse.jface.viewers.ViewerFilter;
29 import org.eclipse.ui.IPluginContribution;
30 import org.eclipse.ui.activities.WorkbenchActivityHelper;
31
32 /**
33  * Represents a custom filter which is provided by the
34  * "net.sourceforge.phpdt.ui.javaElementFilters" extension point.
35  * 
36  * since 2.0
37  */
38 public class FilterDescriptor implements Comparable, IPluginContribution {
39
40         private static String PATTERN_FILTER_ID_PREFIX = "_patternFilterId_"; //$NON-NLS-1$
41
42         private static final String EXTENSION_POINT_NAME = "phpElementFilters"; //$NON-NLS-1$
43
44         private static final String FILTER_TAG = "filter"; //$NON-NLS-1$
45
46         private static final String PATTERN_ATTRIBUTE = "pattern"; //$NON-NLS-1$        
47
48         private static final String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
49
50         /**
51          * @deprecated as of 3.0 use {@link FilterDescriptor#TARGET_ID_ATTRIBUTE}
52          */
53         private static final String VIEW_ID_ATTRIBUTE = "viewId"; //$NON-NLS-1$
54
55         private static final String TARGET_ID_ATTRIBUTE = "targetId"; //$NON-NLS-1$
56
57         private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
58
59         private static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$
60
61         private static final String ENABLED_ATTRIBUTE = "enabled"; //$NON-NLS-1$
62
63         private static final String DESCRIPTION_ATTRIBUTE = "description"; //$NON-NLS-1$        
64
65         /**
66          * @deprecated use "enabled" instead
67          */
68         private static final String SELECTED_ATTRIBUTE = "selected"; //$NON-NLS-1$
69
70         private static FilterDescriptor[] fgFilterDescriptors;
71
72         private IConfigurationElement fElement;
73
74         /**
75          * Returns all contributed Java element filters.
76          */
77         public static FilterDescriptor[] getFilterDescriptors() {
78                 if (fgFilterDescriptors == null) {
79                         IExtensionRegistry registry = Platform.getExtensionRegistry();
80                         IConfigurationElement[] elements = registry
81                                         .getConfigurationElementsFor(PHPeclipsePlugin.PLUGIN_ID,
82                                                         EXTENSION_POINT_NAME);
83                         fgFilterDescriptors = createFilterDescriptors(elements);
84                 }
85                 return fgFilterDescriptors;
86         }
87
88         /**
89          * Returns all Java element filters which are contributed to the given view.
90          */
91         public static FilterDescriptor[] getFilterDescriptors(String targetId) {
92                 FilterDescriptor[] filterDescs = FilterDescriptor
93                                 .getFilterDescriptors();
94                 List result = new ArrayList(filterDescs.length);
95                 for (int i = 0; i < filterDescs.length; i++) {
96                         String tid = filterDescs[i].getTargetId();
97                         if (WorkbenchActivityHelper.filterItem(filterDescs[i]))
98                                 continue;
99                         if (tid == null || tid.equals(targetId))
100                                 result.add(filterDescs[i]);
101                 }
102                 return (FilterDescriptor[]) result.toArray(new FilterDescriptor[result
103                                 .size()]);
104         }
105
106         /**
107          * Creates a new filter descriptor for the given configuration element.
108          */
109         private FilterDescriptor(IConfigurationElement element) {
110                 fElement = element;
111                 // it is either a pattern filter or a custom filter
112                 Assert
113                                 .isTrue(
114                                                 isPatternFilter() ^ isCustomFilter(),
115                                                 "An extension for extension-point net.sourceforge.phpdt.ui.javaElementFilters does not specify a correct filter"); //$NON-NLS-1$
116                 Assert
117                                 .isNotNull(
118                                                 getId(),
119                                                 "An extension for extension-point net.sourceforge.phpdt.ui.javaElementFilters does not provide a valid ID"); //$NON-NLS-1$
120                 Assert
121                                 .isNotNull(
122                                                 getName(),
123                                                 "An extension for extension-point net.sourceforge.phpdt.ui.javaElementFilters does not provide a valid name"); //$NON-NLS-1$
124         }
125
126         /**
127          * Creates a new <code>ViewerFilter</code>. This method is only valid for
128          * viewer filters.
129          */
130         public ViewerFilter createViewerFilter() {
131                 if (!isCustomFilter())
132                         return null;
133
134                 final ViewerFilter[] result = new ViewerFilter[1];
135                 String message = FilterMessages.getFormattedString(
136                                 "FilterDescriptor.filterCreationError.message", getId()); //$NON-NLS-1$
137                 ISafeRunnable code = new SafeRunnable(message) {
138                         /*
139                          * @see org.eclipse.core.runtime.ISafeRunnable#run()
140                          */
141                         public void run() throws Exception {
142                                 result[0] = (ViewerFilter) fElement
143                                                 .createExecutableExtension(CLASS_ATTRIBUTE);
144                         }
145
146                 };
147                 Platform.run(code);
148                 return result[0];
149         }
150
151         // ---- XML Attribute accessors
152         // ---------------------------------------------
153
154         /**
155          * Returns the filter's id.
156          * <p>
157          * This attribute is mandatory for custom filters. The ID for pattern
158          * filters is PATTERN_FILTER_ID_PREFIX plus the pattern itself.
159          * </p>
160          */
161         public String getId() {
162                 if (isPatternFilter()) {
163                         String targetId = getTargetId();
164                         if (targetId == null)
165                                 return PATTERN_FILTER_ID_PREFIX + getPattern();
166                         else
167                                 return targetId + PATTERN_FILTER_ID_PREFIX + getPattern();
168                 } else
169                         return fElement.getAttribute(ID_ATTRIBUTE);
170         }
171
172         /**
173          * Returns the filter's name.
174          * <p>
175          * If the name of a pattern filter is missing then the pattern is used as
176          * its name.
177          * </p>
178          */
179         public String getName() {
180                 String name = fElement.getAttribute(NAME_ATTRIBUTE);
181                 if (name == null && isPatternFilter())
182                         name = getPattern();
183                 return name;
184         }
185
186         /**
187          * Returns the filter's pattern.
188          * 
189          * @return the pattern string or <code>null</code> if it's not a pattern
190          *         filter
191          */
192         public String getPattern() {
193                 return fElement.getAttribute(PATTERN_ATTRIBUTE);
194         }
195
196         /**
197          * Returns the filter's viewId.
198          * 
199          * @return the view ID or <code>null</code> if the filter is for all views
200          * @since 3.0
201          */
202         public String getTargetId() {
203                 String tid = fElement.getAttribute(TARGET_ID_ATTRIBUTE);
204
205                 if (tid != null)
206                         return tid;
207
208                 // Backwards compatibility code
209                 return fElement.getAttribute(VIEW_ID_ATTRIBUTE);
210
211         }
212
213         /**
214          * Returns the filter's description.
215          * 
216          * @return the description or <code>null</code> if no description is
217          *         provided
218          */
219         public String getDescription() {
220                 String description = fElement.getAttribute(DESCRIPTION_ATTRIBUTE);
221                 if (description == null)
222                         description = ""; //$NON-NLS-1$
223                 return description;
224         }
225
226         /**
227          * @return <code>true</code> if this filter is a custom filter.
228          */
229         public boolean isPatternFilter() {
230                 return getPattern() != null;
231         }
232
233         /**
234          * @return <code>true</code> if this filter is a pattern filter.
235          */
236         public boolean isCustomFilter() {
237                 return fElement.getAttribute(CLASS_ATTRIBUTE) != null;
238         }
239
240         /**
241          * Returns <code>true</code> if the filter is initially enabled.
242          * 
243          * This attribute is optional and defaults to <code>true</code>.
244          */
245         public boolean isEnabled() {
246                 String strVal = fElement.getAttribute(ENABLED_ATTRIBUTE);
247                 if (strVal == null)
248                         // backward compatibility
249                         strVal = fElement.getAttribute(SELECTED_ATTRIBUTE);
250                 return strVal == null || Boolean.valueOf(strVal).booleanValue();
251         }
252
253         /*
254          * Implements a method from IComparable
255          */
256         public int compareTo(Object o) {
257                 if (o instanceof FilterDescriptor)
258                         return Collator.getInstance().compare(getName(),
259                                         ((FilterDescriptor) o).getName());
260                 else
261                         return Integer.MIN_VALUE;
262         }
263
264         // ---- initialization ---------------------------------------------------
265
266         /**
267          * Creates the filter descriptors.
268          */
269         private static FilterDescriptor[] createFilterDescriptors(
270                         IConfigurationElement[] elements) {
271                 List result = new ArrayList(5);
272                 Set descIds = new HashSet(5);
273                 for (int i = 0; i < elements.length; i++) {
274                         final IConfigurationElement element = elements[i];
275                         if (FILTER_TAG.equals(element.getName())) {
276
277                                 final FilterDescriptor[] desc = new FilterDescriptor[1];
278                                 Platform
279                                                 .run(new SafeRunnable(
280                                                                 FilterMessages
281                                                                                 .getString("FilterDescriptor.filterDescriptionCreationError.message")) { //$NON-NLS-1$
282                                                         public void run() throws Exception {
283                                                                 desc[0] = new FilterDescriptor(element);
284                                                         }
285                                                 });
286
287                                 if (desc[0] != null && !descIds.contains(desc[0].getId())) {
288                                         result.add(desc[0]);
289                                         descIds.add(desc[0].getId());
290                                 }
291                         }
292                 }
293                 Collections.sort(result);
294                 return (FilterDescriptor[]) result.toArray(new FilterDescriptor[result
295                                 .size()]);
296         }
297
298         public String getLocalId() {
299                 return fElement.getAttribute(ID_ATTRIBUTE);
300         }
301
302         public String getPluginId() {
303                 return fElement.getDeclaringExtension().getNamespace();
304         }
305
306 }