com.vmware.vfabric.ide.eclipse.tcserver.insight.internal.ui.link.JavaElementLocationHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.vfabric.ide.eclipse.tcserver.insight.internal.ui.link.JavaElementLocationHandler.java

Source

/*******************************************************************************
 * Copyright (c) 2012 Pivotal Software, Inc.
 * 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
 * https://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Pivotal Software, Inc. - initial API and implementation
 *******************************************************************************/
package com.vmware.vfabric.ide.eclipse.tcserver.insight.internal.ui.link;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IProject;
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.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.ServerUtil;
import org.eclipse.wst.server.core.model.IURLProvider;
import org.springsource.ide.eclipse.commons.core.JdtUtils;
import org.springsource.ide.eclipse.commons.ui.SpringUIUtils;

import com.vmware.vfabric.ide.eclipse.tcserver.insight.internal.ui.Activator;
import com.vmware.vfabric.ide.eclipse.tcserver.insight.internal.ui.ILocationHandler;

/**
 * {@link ILocationHandler} that opens {@link IJavaElement}s based on the given
 * string in the link parameter.
 * @author Christian Dupuis
 * @author Steffen Pingel
 * @since 2.2.0
 */
public class JavaElementLocationHandler implements ILocationHandler {

    private static final Pattern PATTERN = Pattern.compile("(.*),(.*)/(.*)/(.*)");

    /**
     * {@inheritDoc}
     */
    public void handleLocation(String serverUrl, String parameter) {

        Matcher matcher = PATTERN.matcher(parameter);
        if (matcher.matches()) {
            final String contextRoot = serverUrl + matcher.group(1) + "/";
            final String className = matcher.group(2);
            // final String methodName = matcher.group(3);
            final String lineNumber = matcher.group(4);

            UIJob job = new UIJob("Go to Source") { //$NON-NLS-1$
                @Override
                public IStatus runInUIThread(IProgressMonitor monitor) {
                    try {

                        IProject[] projects = findProjects(contextRoot);

                        String cleanClassName = cleanClassName(className);

                        IType type = null;
                        for (IProject project : projects) {
                            type = JdtUtils.getJavaType(project, cleanClassName);
                            if (type != null) {
                                break;
                            }
                        }
                        if (type == null) {
                            type = findTypeInWorkspace(cleanClassName);
                        }

                        if (type == null) {
                            MessageDialog.openInformation(Display.getDefault().getActiveShell(), "Type not found",
                                    "Could not find type '" + className + "' in workspace");
                        } else {
                            IEditorPart editorPart = SpringUIUtils.openInEditor(type);
                            int ln = Integer.valueOf(lineNumber);
                            if (editorPart instanceof ITextEditor && ln >= 0) {
                                ITextEditor textEditor = (ITextEditor) editorPart;
                                IDocumentProvider provider = textEditor.getDocumentProvider();
                                provider.connect(editorPart.getEditorInput());
                                IDocument document = provider.getDocument(editorPart.getEditorInput());
                                try {
                                    IRegion line = document.getLineInformation(ln - 1);
                                    textEditor.selectAndReveal(line.getOffset(), line.getLength());
                                } catch (BadLocationException e) {
                                }
                                provider.disconnect(editorPart.getEditorInput());
                            }
                        }
                    } catch (CoreException e) {
                        return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error finding class", e);
                    }
                    return Status.OK_STATUS;
                }

            };
            job.setSystem(true);
            job.schedule();
        }
    }

    private static String cleanClassName(final String className) {
        String cleanClassName = className;
        int ix = className.indexOf('$');
        if (ix > 0) {
            cleanClassName = className.substring(0, ix);
        }
        return cleanClassName;
    }

    private static IProject[] findProjects(final String contextRoot) {
        Set<IProject> projects = new HashSet<IProject>();
        IModule[] modules = ServerUtil.getModules("jst.web");
        for (IModule module : modules) {
            IServer[] servers = ServerUtil.getServersByModule(module, new NullProgressMonitor());
            for (IServer server : servers) {
                if (server.getServerState() == IServer.STATE_STARTED) {
                    IURLProvider urlProvider = (IURLProvider) server.loadAdapter(IURLProvider.class,
                            new NullProgressMonitor());
                    if (urlProvider != null) {
                        URL url = urlProvider.getModuleRootURL(module);
                        if (url.toString().equals(contextRoot)) {
                            projects.add(module.getProject());
                        }
                    }
                }
            }
        }
        return projects.toArray(new IProject[projects.size()]);
    }

    public static IType findTypeInWorkspace(String typeName) throws CoreException {
        IType[] types = findTypes(typeName, null);
        if (types.length > 0) {
            return types[0];
        }
        return null;
    }

    private static IType[] findTypes(String typeName, IProgressMonitor monitor) throws CoreException {

        final List<IType> results = new ArrayList<IType>();

        SearchRequestor collector = new SearchRequestor() {
            @Override
            public void acceptSearchMatch(SearchMatch match) throws CoreException {
                Object element = match.getElement();
                if (element instanceof IType) {
                    results.add((IType) element);
                }
            }
        };

        SearchEngine engine = new SearchEngine();
        SearchPattern pattern = SearchPattern.createPattern(typeName, IJavaSearchConstants.TYPE,
                IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH);
        engine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() },
                SearchEngine.createWorkspaceScope(), collector, monitor);

        return results.toArray(new IType[results.size()]);
    }
}