com.siteview.mde.internal.ui.search.ClassSearchParticipant.java Source code

Java tutorial

Introduction

Here is the source code for com.siteview.mde.internal.ui.search.ClassSearchParticipant.java

Source

/*******************************************************************************
 * Copyright (c) 2005, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Benjamin Cabe <benjamin.cabe@anyware-technologies.com> - bug 261404, 262353, 264176
 *******************************************************************************/
package com.siteview.mde.internal.ui.search;

import com.siteview.mde.internal.core.text.monitor.MonitorElementNode;

import com.siteview.mde.core.monitor.*;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.ui.search.*;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.osgi.util.ManifestElement;
import com.siteview.mde.core.IBaseModel;
import com.siteview.mde.internal.core.ICoreConstants;
import com.siteview.mde.internal.core.MDECore;
import com.siteview.mde.internal.core.ibundle.*;
import com.siteview.mde.internal.core.ischema.*;
import com.siteview.mde.internal.core.schema.SchemaRegistry;
import com.siteview.mde.internal.core.text.IDocumentAttributeNode;
import com.siteview.mde.internal.core.text.IEditingModel;
import com.siteview.mde.internal.core.util.PatternConstructor;
import com.siteview.mde.internal.ui.MDEUIMessages;
import com.siteview.mde.internal.ui.util.ModelModification;
import com.siteview.mde.internal.ui.util.PDEModelUtility;
import org.eclipse.search.ui.text.Match;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;

public class ClassSearchParticipant implements IQueryParticipant {

    private static final int H_IMP = 0;
    private static final int H_EXP = 1;
    private static final int H_BUNACT = 2;
    private static final int H_PLUGCLASS = 3;
    private static final int H_TOTAL = 4;
    private static final String[] SEARCH_HEADERS = new String[H_TOTAL];
    static {
        SEARCH_HEADERS[H_IMP] = Constants.IMPORT_PACKAGE;
        SEARCH_HEADERS[H_EXP] = Constants.EXPORT_PACKAGE;
        SEARCH_HEADERS[H_BUNACT] = Constants.BUNDLE_ACTIVATOR;
        SEARCH_HEADERS[H_PLUGCLASS] = ICoreConstants.PLUGIN_CLASS;
    }
    // the following are from JavaSearchPage (radio button indexes)
    private static final int S_LIMIT_REF = 2;
    private static final int S_LIMIT_ALL = 3;
    private static final int S_FOR_TYPES = 0;
    private static final int S_FOR_PACKAGES = 2;

    private ISearchRequestor fSearchRequestor;
    private Pattern fSearchPattern;
    private int fSearchFor = -1; // set since S_FOR_TYPES = 0;

    public ClassSearchParticipant() {
    }

    public void search(ISearchRequestor requestor, QuerySpecification querySpecification, IProgressMonitor monitor)
            throws CoreException {

        if (querySpecification.getLimitTo() != S_LIMIT_REF && querySpecification.getLimitTo() != S_LIMIT_ALL)
            return;

        String search;
        if (querySpecification instanceof ElementQuerySpecification) {
            IJavaElement element = ((ElementQuerySpecification) querySpecification).getElement();
            if (element instanceof IType)
                search = ((IType) element).getFullyQualifiedName('.');
            else
                search = element.getElementName();
            int type = element.getElementType();
            if (type == IJavaElement.TYPE)
                fSearchFor = S_FOR_TYPES;
            else if (type == IJavaElement.PACKAGE_FRAGMENT || type == IJavaElement.PACKAGE_FRAGMENT_ROOT)
                fSearchFor = S_FOR_PACKAGES;
        } else {
            fSearchFor = ((PatternQuerySpecification) querySpecification).getSearchFor();
            search = ((PatternQuerySpecification) querySpecification).getPattern();
        }
        if (fSearchFor != S_FOR_TYPES && fSearchFor != S_FOR_PACKAGES)
            return;
        fSearchPattern = PatternConstructor.createPattern(search, true);
        fSearchRequestor = requestor;

        IPath[] enclosingPaths = querySpecification.getScope().enclosingProjectsAndJars();
        IMonitorModelBase[] pluginModels = MonitorRegistry.getWorkspaceModels();
        monitor.beginTask(MDEUIMessages.ClassSearchParticipant_taskMessage, pluginModels.length);
        for (int i = 0; i < pluginModels.length; i++) {
            IProject project = pluginModels[i].getUnderlyingResource().getProject();
            if (!monitor.isCanceled() && encloses(enclosingPaths, project.getFullPath()))
                searchProject(project, monitor);
        }
    }

    private boolean encloses(IPath[] paths, IPath path) {
        for (int i = 0; i < paths.length; i++)
            if (paths[i].equals(path))
                return true;
        return false;
    }

    private void searchProject(IProject project, IProgressMonitor monitor) throws CoreException {
        ModelModification mod = new ModelModification(project) {
            protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws CoreException {
                if (model instanceof IBundlePluginModelBase) {
                    IBundleModel bmodel = ((IBundlePluginModelBase) model).getBundleModel();
                    inspectBundle(bmodel.getBundle());
                    model = ((IBundlePluginModelBase) model).getExtensionsModel();
                }
                if (model instanceof IMonitorModelBase) {
                    IFile file = (IFile) ((IMonitorModelBase) model).getUnderlyingResource();
                    SchemaRegistry registry = MDECore.getDefault().getSchemaRegistry();
                    IMonitorBase pbase = ((IMonitorModelBase) model).getMonitorBase();
                    IMonitorExtension[] extensions = pbase.getExtensions();
                    for (int j = 0; j < extensions.length; j++) {
                        ISchema schema = registry.getSchema(extensions[j].getPoint());
                        if (schema != null && !monitor.isCanceled())
                            inspectExtension(schema, extensions[j], file);
                    }
                }
            }
        };
        PDEModelUtility.modifyModel(mod, monitor);
    }

    private void inspectExtension(ISchema schema, IMonitorParent parent, IFile file) {
        IMonitorObject[] children = parent.getChildren();

        if (parent instanceof MonitorElementNode && parent != null
                && parent.getParent() instanceof MonitorElementNode) {
            // check if this node corresponds to a Java type attribute which would have been defined has an element
            MonitorElementNode node = (MonitorElementNode) parent;
            MonitorElementNode parentNode = (MonitorElementNode) parent.getParent();
            ISchemaElement schemaElement = schema.findElement(parentNode.getName());
            if (schemaElement != null) {
                ISchemaAttribute attInfo = schemaElement.getAttribute(node.getName());
                if (attInfo != null && attInfo.getKind() == IMetaAttribute.JAVA)
                    checkMatch(node.getAttribute("class"), file); //$NON-NLS-1$
            }
        }

        for (int i = 0; i < children.length; i++) {
            IMonitorElement child = (IMonitorElement) children[i];
            ISchemaElement schemaElement = schema.findElement(child.getName());
            if (schemaElement != null) {
                IMonitorAttribute[] attributes = child.getAttributes();
                for (int j = 0; j < attributes.length; j++) {
                    IMonitorAttribute attr = attributes[j];
                    ISchemaAttribute attInfo = schemaElement.getAttribute(attr.getName());
                    if (attInfo != null && attInfo.getKind() == IMetaAttribute.JAVA
                            && attr instanceof IDocumentAttributeNode)
                        checkMatch(attr, file);
                }
            }
            inspectExtension(schema, child, file);
        }
    }

    private void checkMatch(IMonitorAttribute attr, IFile file) {
        String value = null;
        Matcher matcher = null;
        if (fSearchFor == S_FOR_TYPES) {
            value = removeInitializationData(attr.getValue()).replaceAll("\\$", "."); //$NON-NLS-1$ //$NON-NLS-2$
            matcher = getMatcher(value);
        }
        if (value == null || (matcher != null && !matcher.matches())) {
            value = removeInitializationData(getProperValue(attr.getValue())).replaceAll("\\$", "."); //$NON-NLS-1$ //$NON-NLS-2$
            matcher = getMatcher(value);
        }
        if (matcher.matches()) {
            String group = matcher.group(0);
            int offset = ((IDocumentAttributeNode) attr).getValueOffset() + value.indexOf(group);
            int attOffset = attr.getValue().indexOf(value);
            if (attOffset != -1)
                offset += attOffset;
            int length = group.length();
            fSearchRequestor.reportMatch(new Match(file, Match.UNIT_CHARACTER, offset, length));
        }
    }

    private String removeInitializationData(String attrValue) {
        int i = attrValue.indexOf(':');
        if (i != -1)
            return attrValue.substring(0, i).trim();
        return attrValue;
    }

    private void inspectBundle(IBundle bundle) {
        for (int i = 0; i < H_TOTAL; i++) {
            if (fSearchFor == S_FOR_TYPES && (i == H_IMP || i == H_EXP))
                continue;
            IManifestHeader header = bundle.getManifestHeader(SEARCH_HEADERS[i]);
            if (header != null) {
                try {
                    ManifestElement[] elements = ManifestElement.parseHeader(header.getName(), header.getValue());
                    if (elements == null)
                        continue;
                    for (int j = 0; j < elements.length; j++) {
                        String value = null;
                        Matcher matcher = null;
                        if (fSearchFor == S_FOR_TYPES) {
                            value = elements[j].getValue();
                            matcher = getMatcher(value);
                        }
                        if (value == null || (matcher != null && !matcher.matches())) {
                            value = getProperValue(elements[j].getValue());
                            matcher = getMatcher(value);
                        }
                        if (matcher.matches()) {
                            String group = matcher.group(0);
                            int[] offlen;
                            try {
                                offlen = getOffsetOfElement(bundle, header, group);
                            } catch (CoreException e) {
                                offlen = new int[] { header.getOffset(), header.getLength() };
                            }
                            fSearchRequestor.reportMatch(new Match(bundle.getModel().getUnderlyingResource(),
                                    Match.UNIT_CHARACTER, offlen[0], offlen[1]));
                            break; // only one package will be listed per header
                        }
                    }
                } catch (BundleException e) {
                }
            }
        }
    }

    private Matcher getMatcher(String value) {
        return fSearchPattern.matcher(value.subSequence(0, value.length()));
    }

    private int[] getOffsetOfElement(IBundle bundle, IManifestHeader header, String value) throws CoreException {
        int[] offlen = new int[] { 0, 0 };
        IBundleModel model = bundle.getModel();
        if (model instanceof IEditingModel) {
            IDocument pDoc = ((IEditingModel) model).getDocument();
            int headerOffset = header.getOffset() + header.getName().length();
            try {
                String headerString = pDoc.get(headerOffset, header.getLength() - header.getName().length());
                int internalOffset = headerString.indexOf(value);
                if (internalOffset != -1)
                    offlen[0] = headerOffset + internalOffset;
                else
                    offlen[0] = headerOffset + header.getName().length() + header.getValue().indexOf(value);
                offlen[1] = value.length();
            } catch (BadLocationException e) {
            }
        }
        return offlen;
    }

    private String getProperValue(String value) {
        return fSearchFor == S_FOR_TYPES ? extractType(value) : extractPackage(value);
    }

    private String extractType(String value) {
        int index = value.lastIndexOf("."); //$NON-NLS-1$
        if (index == -1 || index == value.length() - 1)
            return value;
        return value.substring(index + 1);
    }

    private String extractPackage(String value) {
        int index = value.lastIndexOf("."); //$NON-NLS-1$
        if (index == -1 || index == value.length() - 1)
            return value;
        char afterPeriod = value.charAt(index + 1);
        if (afterPeriod >= 'A' && afterPeriod <= 'Z')
            return value.substring(0, index);
        return value;
    }

    public int estimateTicks(QuerySpecification specification) {
        return 100;
    }

    public IMatchPresentation getUIParticipant() {
        return null;
    }
}