KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > search > ClassSearchParticipant


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 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.pde.internal.ui.search;
12
13 import java.util.regex.Matcher JavaDoc;
14 import java.util.regex.Pattern JavaDoc;
15
16 import org.eclipse.core.resources.IFile;
17 import org.eclipse.core.resources.IProject;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IPath;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.jdt.core.IJavaElement;
22 import org.eclipse.jdt.core.IType;
23 import org.eclipse.jdt.ui.search.ElementQuerySpecification;
24 import org.eclipse.jdt.ui.search.IMatchPresentation;
25 import org.eclipse.jdt.ui.search.IQueryParticipant;
26 import org.eclipse.jdt.ui.search.ISearchRequestor;
27 import org.eclipse.jdt.ui.search.PatternQuerySpecification;
28 import org.eclipse.jdt.ui.search.QuerySpecification;
29 import org.eclipse.jface.text.BadLocationException;
30 import org.eclipse.jface.text.IDocument;
31 import org.eclipse.osgi.util.ManifestElement;
32 import org.eclipse.pde.core.IBaseModel;
33 import org.eclipse.pde.core.plugin.IPluginAttribute;
34 import org.eclipse.pde.core.plugin.IPluginBase;
35 import org.eclipse.pde.core.plugin.IPluginElement;
36 import org.eclipse.pde.core.plugin.IPluginExtension;
37 import org.eclipse.pde.core.plugin.IPluginModelBase;
38 import org.eclipse.pde.core.plugin.IPluginObject;
39 import org.eclipse.pde.core.plugin.IPluginParent;
40 import org.eclipse.pde.core.plugin.PluginRegistry;
41 import org.eclipse.pde.internal.core.ICoreConstants;
42 import org.eclipse.pde.internal.core.PDECore;
43 import org.eclipse.pde.internal.core.ibundle.IBundle;
44 import org.eclipse.pde.internal.core.ibundle.IBundleModel;
45 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
46 import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
47 import org.eclipse.pde.internal.core.ischema.IMetaAttribute;
48 import org.eclipse.pde.internal.core.ischema.ISchema;
49 import org.eclipse.pde.internal.core.ischema.ISchemaAttribute;
50 import org.eclipse.pde.internal.core.ischema.ISchemaElement;
51 import org.eclipse.pde.internal.core.schema.SchemaRegistry;
52 import org.eclipse.pde.internal.core.text.IDocumentAttribute;
53 import org.eclipse.pde.internal.core.text.IEditingModel;
54 import org.eclipse.pde.internal.core.util.PatternConstructor;
55 import org.eclipse.pde.internal.ui.PDEUIMessages;
56 import org.eclipse.pde.internal.ui.util.ModelModification;
57 import org.eclipse.pde.internal.ui.util.PDEModelUtility;
58 import org.eclipse.search.ui.text.Match;
59 import org.osgi.framework.BundleException;
60 import org.osgi.framework.Constants;
61
62 public class ClassSearchParticipant implements IQueryParticipant {
63
64     private static final int H_IMP = 0;
65     private static final int H_EXP = 1;
66     private static final int H_BUNACT = 2;
67     private static final int H_PLUGCLASS = 3;
68     private static final int H_TOTAL = 4;
69     private static final String JavaDoc[] SEARCH_HEADERS = new String JavaDoc[H_TOTAL];
70     static {
71         SEARCH_HEADERS[H_IMP] = Constants.IMPORT_PACKAGE;
72         SEARCH_HEADERS[H_EXP] = Constants.EXPORT_PACKAGE;
73         SEARCH_HEADERS[H_BUNACT] = Constants.BUNDLE_ACTIVATOR;
74         SEARCH_HEADERS[H_PLUGCLASS] = ICoreConstants.PLUGIN_CLASS;
75     }
76     // the following are from JavaSearchPage (radio button indexes)
77
private static final int S_LIMIT_REF = 2;
78     private static final int S_LIMIT_ALL = 3;
79     private static final int S_FOR_TYPES = 0;
80     private static final int S_FOR_PACKAGES = 2;
81     
82     private ISearchRequestor fSearchRequestor;
83     private Pattern JavaDoc fSearchPattern;
84     private int fSearchFor = -1; // set since S_FOR_TYPES = 0;
85

86     public ClassSearchParticipant() {
87     }
88     
89     public void search(ISearchRequestor requestor,
90             QuerySpecification querySpecification, IProgressMonitor monitor)
91             throws CoreException {
92         
93         if (querySpecification.getLimitTo() != S_LIMIT_REF &&
94                 querySpecification.getLimitTo() != S_LIMIT_ALL)
95             return;
96         
97         String JavaDoc search;
98         if (querySpecification instanceof ElementQuerySpecification) {
99             IJavaElement element = ((ElementQuerySpecification)querySpecification).getElement();
100             if (element instanceof IType)
101                 search = ((IType)element).getFullyQualifiedName('.');
102             else
103                 search = element.getElementName();
104             int type = element.getElementType();
105             if (type == IJavaElement.TYPE)
106                 fSearchFor = S_FOR_TYPES;
107             else if (type == IJavaElement.PACKAGE_FRAGMENT || type == IJavaElement.PACKAGE_FRAGMENT_ROOT)
108                 fSearchFor = S_FOR_PACKAGES;
109         } else {
110             fSearchFor = ((PatternQuerySpecification)querySpecification).getSearchFor();
111             search = ((PatternQuerySpecification)querySpecification).getPattern();
112         }
113         if (fSearchFor != S_FOR_TYPES && fSearchFor != S_FOR_PACKAGES)
114             return;
115         fSearchPattern = PatternConstructor.createPattern(search, true);
116         fSearchRequestor = requestor;
117         
118         IPath[] enclosingPaths = querySpecification.getScope().enclosingProjectsAndJars();
119         IPluginModelBase[] pluginModels = PluginRegistry.getWorkspaceModels();
120         monitor.beginTask(PDEUIMessages.ClassSearchParticipant_taskMessage, pluginModels.length);
121         for (int i = 0; i < pluginModels.length; i++) {
122             IProject project = pluginModels[i].getUnderlyingResource().getProject();
123             if (!monitor.isCanceled() && encloses(enclosingPaths, project.getFullPath()))
124                 searchProject(project, monitor);
125         }
126     }
127     
128     private boolean encloses(IPath[] paths, IPath path) {
129         for (int i = 0; i < paths.length; i++)
130             if (paths[i].equals(path))
131                 return true;
132         return false;
133     }
134     
135     
136     private void searchProject(IProject project, IProgressMonitor monitor) throws CoreException {
137         ModelModification mod = new ModelModification(project) {
138             protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws CoreException {
139                 if (model instanceof IBundlePluginModelBase) {
140                     IBundleModel bmodel = ((IBundlePluginModelBase)model).getBundleModel();
141                     inspectBundle(bmodel.getBundle());
142                     model = ((IBundlePluginModelBase)model).getExtensionsModel();
143                 }
144                 if (model instanceof IPluginModelBase) {
145                     IFile file = (IFile)((IPluginModelBase)model).getUnderlyingResource();
146                     SchemaRegistry registry = PDECore.getDefault().getSchemaRegistry();
147                     IPluginBase pbase = ((IPluginModelBase)model).getPluginBase();
148                     IPluginExtension[] extensions = pbase.getExtensions();
149                     for (int j = 0; j < extensions.length; j++) {
150                         ISchema schema = registry.getSchema(extensions[j].getPoint());
151                         if (schema != null && !monitor.isCanceled())
152                             inspectExtension(schema, extensions[j], file);
153                     }
154                 }
155             }
156         };
157         PDEModelUtility.modifyModel(mod, monitor);
158     }
159
160     private void inspectExtension(ISchema schema, IPluginParent parent, IFile file) {
161         IPluginObject[] children = parent.getChildren();
162         for (int i = 0; i < children.length; i++) {
163             IPluginElement child = (IPluginElement)children[i];
164             ISchemaElement schemaElement = schema.findElement(child.getName());
165             if (schemaElement != null) {
166                 IPluginAttribute[] attributes = child.getAttributes();
167                 for (int j = 0; j < attributes.length; j++) {
168                     IPluginAttribute attr = attributes[j];
169                     ISchemaAttribute attInfo = schemaElement.getAttribute(attr.getName());
170                     if (attInfo != null
171                             && attInfo.getKind() == IMetaAttribute.JAVA
172                             && attr instanceof IDocumentAttribute)
173                         checkMatch(attr, file);
174                 }
175             }
176             inspectExtension(schema, child, file);
177         }
178     }
179
180     private void checkMatch(IPluginAttribute attr, IFile file) {
181         String JavaDoc value = null;
182         Matcher JavaDoc matcher = null;
183         if (fSearchFor == S_FOR_TYPES) {
184             value = attr.getValue().replaceAll("\\$", "."); //$NON-NLS-1$ //$NON-NLS-2$
185
matcher = getMatcher(value);
186         }
187         if (value == null || (matcher != null && !matcher.matches()) ){
188             value = getProperValue(attr.getValue()).replaceAll("\\$", "."); //$NON-NLS-1$ //$NON-NLS-2$
189
matcher = getMatcher(value);
190         }
191         if (matcher.matches()) {
192             String JavaDoc group = matcher.group(0);
193             int offset = ((IDocumentAttribute)attr).getValueOffset() + value.indexOf(group);
194             int attOffset = attr.getValue().indexOf(value);
195             if (attOffset != -1)
196                 offset += attOffset;
197             int length = group.length();
198             fSearchRequestor.reportMatch(new Match(file, Match.UNIT_CHARACTER, offset, length));
199         }
200     }
201     
202     private void inspectBundle(IBundle bundle) {
203         for (int i = 0; i < H_TOTAL; i++) {
204             if (fSearchFor == S_FOR_TYPES && (i == H_IMP || i == H_EXP))
205                 continue;
206             IManifestHeader header = bundle.getManifestHeader(SEARCH_HEADERS[i]);
207             if (header != null) {
208                 try {
209                     ManifestElement[] elements = ManifestElement.parseHeader(header.getName(), header.getValue());
210                     if (elements == null) continue;
211                     for (int j = 0; j < elements.length; j++) {
212                         String JavaDoc value = null;
213                         Matcher JavaDoc matcher = null;
214                         if (fSearchFor == S_FOR_TYPES) {
215                             value = elements[j].getValue();
216                             matcher = getMatcher(value);
217                         }
218                         if (value == null || (matcher != null && !matcher.matches()) ){
219                             value = getProperValue(elements[j].getValue());
220                             matcher = getMatcher(value);
221                         }
222                         if (matcher.matches()) {
223                             String JavaDoc group = matcher.group(0);
224                             int[] offlen;
225                             try {
226                                 offlen = getOffsetOfElement(bundle, header, group);
227                             } catch (CoreException e) {
228                                 offlen = new int[]{header.getOffset(), header.getLength()};
229                             }
230                             fSearchRequestor.reportMatch(new Match(
231                                     bundle.getModel().getUnderlyingResource(),
232                                     Match.UNIT_CHARACTER, offlen[0], offlen[1]));
233                             break; // only one package will be listed per header
234
}
235                     }
236                 } catch (BundleException e) {
237                 }
238             }
239         }
240     }
241     
242     private Matcher JavaDoc getMatcher(String JavaDoc value) {
243         return fSearchPattern.matcher(value.subSequence(0, value.length()));
244     }
245     
246     private int[] getOffsetOfElement(IBundle bundle, IManifestHeader header, String JavaDoc value) throws CoreException {
247         int[] offlen = new int[] {0, 0};
248         IBundleModel model = bundle.getModel();
249         if (model instanceof IEditingModel) {
250             IDocument pDoc = ((IEditingModel)model).getDocument();
251             int headerOffset = header.getOffset() + header.getName().length();
252             try {
253                 String JavaDoc headerString = pDoc.get(headerOffset, header.getLength() - header.getName().length());
254                 int internalOffset = headerString.indexOf(value);
255                 if (internalOffset != -1)
256                     offlen[0] = headerOffset + internalOffset;
257                 else
258                     offlen[0] = headerOffset + header.getName().length() + header.getValue().indexOf(value);
259                 offlen[1] = value.length();
260             } catch (BadLocationException e) {
261             }
262         }
263         return offlen;
264     }
265     
266     private String JavaDoc getProperValue(String JavaDoc value) {
267         return fSearchFor == S_FOR_TYPES ? extractType(value) : extractPackage(value);
268     }
269     private String JavaDoc extractType(String JavaDoc value) {
270         int index = value.lastIndexOf("."); //$NON-NLS-1$
271
if (index == -1 || index == value.length() - 1) return value;
272         return value.substring(index + 1);
273     }
274     private String JavaDoc extractPackage(String JavaDoc value) {
275         int index = value.lastIndexOf("."); //$NON-NLS-1$
276
if (index == -1 || index == value.length() - 1) return value;
277         char afterPeriod = value.charAt(index + 1);
278         if (afterPeriod >= 'A' && afterPeriod <= 'Z')
279             return value.substring(0, index);
280         return value;
281     }
282     
283     public int estimateTicks(QuerySpecification specification) {
284         return 100;
285     }
286
287     public IMatchPresentation getUIParticipant() {
288         return null;
289     }
290 }
291
Popular Tags