1 11 package org.eclipse.pde.internal.ui.search; 12 13 import java.util.regex.Matcher ; 14 import java.util.regex.Pattern ; 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 [] SEARCH_HEADERS = new String [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 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 fSearchPattern; 84 private int fSearchFor = -1; 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 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 value = null; 182 Matcher matcher = null; 183 if (fSearchFor == S_FOR_TYPES) { 184 value = attr.getValue().replaceAll("\\$", "."); matcher = getMatcher(value); 186 } 187 if (value == null || (matcher != null && !matcher.matches()) ){ 188 value = getProperValue(attr.getValue()).replaceAll("\\$", "."); matcher = getMatcher(value); 190 } 191 if (matcher.matches()) { 192 String 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 value = null; 213 Matcher 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 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; } 235 } 236 } catch (BundleException e) { 237 } 238 } 239 } 240 } 241 242 private Matcher getMatcher(String value) { 243 return fSearchPattern.matcher(value.subSequence(0, value.length())); 244 } 245 246 private int[] getOffsetOfElement(IBundle bundle, IManifestHeader header, String 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 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 getProperValue(String value) { 267 return fSearchFor == S_FOR_TYPES ? extractType(value) : extractPackage(value); 268 } 269 private String extractType(String value) { 270 int index = value.lastIndexOf("."); if (index == -1 || index == value.length() - 1) return value; 272 return value.substring(index + 1); 273 } 274 private String extractPackage(String value) { 275 int index = value.lastIndexOf("."); 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 |