bndtools.editor.components.ComponentNameProposalProvider.java Source code

Java tutorial

Introduction

Here is the source code for bndtools.editor.components.ComponentNameProposalProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2010 Neil Bartlett.
 * 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:
 *     Neil Bartlett - initial API and implementation
 *******************************************************************************/
package bndtools.editor.components;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeNameRequestor;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import bndtools.Plugin;
import bndtools.javamodel.IJavaSearchContext;
import bndtools.utils.CachingContentProposalProvider;
import bndtools.utils.JavaContentProposal;

public class ComponentNameProposalProvider extends CachingContentProposalProvider {

    protected static final String XML_SUFFIX = ".xml";
    private final IJavaSearchContext searchContext;

    public ComponentNameProposalProvider(IJavaSearchContext searchContext) {
        this.searchContext = searchContext;
    }

    public ComponentNameProposalProvider(final IJavaProject javaProject) {
        this(new IJavaSearchContext() {
            public IJavaProject getJavaProject() {
                return javaProject;
            }

            public IRunnableContext getRunContext() {
                return null;
            }
        });
    }

    @Override
    protected boolean match(String contents, int position, IContentProposal proposal) {
        String lowerCasePrefix = contents.substring(0, position).toLowerCase();
        if (proposal instanceof ResourceProposal) {
            return ((ResourceProposal) proposal).getName().toLowerCase().startsWith(lowerCasePrefix);
        }
        if (proposal instanceof JavaContentProposal) {
            return ((JavaContentProposal) proposal).getTypeName().toLowerCase().startsWith(lowerCasePrefix);
        }
        return false;
    }

    @Override
    protected List<IContentProposal> doGenerateProposals(String contents, int position) {
        final String prefix = contents.substring(0, position);
        IJavaProject javaProject = searchContext.getJavaProject();
        final List<IContentProposal> result = new ArrayList<IContentProposal>(100);

        // Resource matches
        IProject project = javaProject.getProject();
        try {
            project.accept(new IResourceProxyVisitor() {
                public boolean visit(IResourceProxy proxy) throws CoreException {
                    if (proxy.getType() == IResource.FILE) {
                        if (proxy.getName().toLowerCase().startsWith(prefix)
                                && proxy.getName().toLowerCase().endsWith(XML_SUFFIX)) {
                            result.add(new ResourceProposal(proxy.requestResource()));
                        }
                        return false;
                    }
                    // Recurse into everything else
                    return true;
                }
            }, 0);
        } catch (CoreException e) {
            Plugin.log(new Status(IStatus.ERROR, Plugin.PLUGIN_ID, 0, "Error searching for resources.", e));
        }

        // Class matches
        final IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject });
        final TypeNameRequestor requestor = new TypeNameRequestor() {
            @Override
            public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName,
                    char[][] enclosingTypeNames, String path) {
                if (!Flags.isAbstract(modifiers) && (Flags.isPublic(modifiers) || Flags.isProtected(modifiers))) {
                    result.add(new JavaContentProposal(new String(packageName), new String(simpleTypeName), false));
                }
            };
        };
        final IRunnableWithProgress runnable = new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                try {
                    new SearchEngine().searchAllTypeNames(null, 0, prefix.toCharArray(),
                            SearchPattern.R_PREFIX_MATCH, IJavaSearchConstants.CLASS, scope, requestor,
                            IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH, monitor);
                } catch (JavaModelException e) {
                    throw new InvocationTargetException(e);
                }
            }
        };
        IRunnableContext runContext = searchContext.getRunContext();
        try {
            if (runContext != null) {
                runContext.run(false, false, runnable);
            } else {
                runnable.run(new NullProgressMonitor());
            }
        } catch (InvocationTargetException e) {
            Plugin.log(new Status(IStatus.ERROR, Plugin.PLUGIN_ID, 0, "Error searching for classes.",
                    e.getTargetException()));
        } catch (InterruptedException e) {
            // Reset the interruption status and continue
            Thread.currentThread().interrupt();
        }
        return result;
    }

    static ILabelProvider createLabelProvider() {
        return new ClassOrResourceLabelProvider();
    }

    private static class ResourceProposal implements IContentProposal {

        final String name;
        final String fullPath;

        public ResourceProposal(IResource resource) {
            name = resource.getName();
            fullPath = resource.getProjectRelativePath().toString();
        }

        public String getContent() {
            return fullPath;
        }

        public int getCursorPosition() {
            return name.length();
        }

        public String getDescription() {
            return null;
        }

        public String getLabel() {
            return name + " (" + fullPath + ")";
        }

        public String getName() {
            return name;
        }
    }

    private static class ClassOrResourceLabelProvider extends LabelProvider {

        private Image xmlImg = AbstractUIPlugin
                .imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/xml_file_obj.gif").createImage();
        private Image classImg = AbstractUIPlugin
                .imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/class_obj.gif").createImage();

        @Override
        public String getText(Object element) {
            return ((IContentProposal) element).getLabel();
        }

        @Override
        public Image getImage(Object element) {
            Image result = null;
            if (element instanceof ResourceProposal) {
                result = xmlImg;
            } else if (element instanceof JavaContentProposal) {
                result = classImg;
            }
            return result;
        }

        @Override
        public void dispose() {
            super.dispose();
            xmlImg.dispose();
            classImg.dispose();
        }
    }
}