org.eclipse.modisco.java.discoverer.AbstractDiscoverJavaModelFromProject.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.modisco.java.discoverer.AbstractDiscoverJavaModelFromProject.java

Source

/*******************************************************************************
 * Copyright (c) 2009 Mia-Software.
 * 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:
 *    Sebastien Minguet (Mia-Software) - initial API and implementation
 *    Frederic Madiot (Mia-Software) - initial API and implementation
 *    Fabien Giquel (Mia-Software) - initial API and implementation
 *    Gabriel Barbier (Mia-Software) - initial API and implementation
 *    Erwan Breton (Sodifrance) - initial API and implementation
 *    Romain Dervaux (Mia-Software) - initial API and implementation
 *    Nicolas Bros (Mia-Software) - Bug 335003 - [Discoverer] : Existing Discoverers Refactoring based on new framework
 *******************************************************************************/

package org.eclipse.modisco.java.discoverer;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.gmt.modisco.infra.common.core.logging.MoDiscoLogger;
import org.eclipse.gmt.modisco.java.Model;
import org.eclipse.gmt.modisco.java.emf.JavaFactory;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.modisco.infra.discovery.core.annotations.Parameter;
import org.eclipse.modisco.java.discoverer.internal.IModelReader;
import org.eclipse.modisco.java.discoverer.internal.JavaActivator;
import org.eclipse.modisco.java.discoverer.internal.Messages;
import org.eclipse.modisco.java.discoverer.internal.io.java.JavaReader;
import org.eclipse.modisco.java.discoverer.internal.io.java.binding.BindingManager;
import org.eclipse.modisco.java.discoverer.internal.io.library.LibraryReader;
import org.eclipse.modisco.kdm.source.extension.discovery.AbstractRegionDiscoverer2;

/**
 * Abstract class to discover a Java model from a project and optionally its
 * libraries.
 */
public abstract class AbstractDiscoverJavaModelFromProject<T> extends AbstractRegionDiscoverer2<T> {

    private ElementsToAnalyze fElementsToAnalyze;

    @Parameter(name = "ELEMENTS_TO_ANALYZE", description = "The Java projects or packages that will be analyzed. ")
    public void setElementsToAnalyze(final ElementsToAnalyze elementsToAnalyze) {
        this.fElementsToAnalyze = elementsToAnalyze;
    }

    protected ElementsToAnalyze getElementsToAnalyze() {
        return this.fElementsToAnalyze;
    }

    /**
     * A parameter key for indicating to log warnings from java analysis.
     *
     * For instance, sometimes java bindings (reference to a Java type, method,
     * ...) cannot be completed. Such java binding problems occurs typically
     * when there are some missing libraries in the Java project classpath. Such
     * java bindings problems will result in missing information in the
     * resulting Java model (occurrences of
     * {@link org.eclipse.gmt.modisco.java.UnresolvedItem})
     */
    private boolean fLogJavaAnalysisWarnings = false;

    @Parameter(name = "LOG_JAVA_ANALYSIS_WARNINGS", description = "Whether to log warnings from java analysis.")
    public void setLogJavaAnalysisWarnings(final boolean logJavaAnalysisWarnings) {
        this.fLogJavaAnalysisWarnings = logJavaAnalysisWarnings;
    }

    protected boolean isLogJavaAnalysisWarnings() {
        return this.fLogJavaAnalysisWarnings;
    }

    private boolean fDeepAnalysis = true;

    @Parameter(name = "DEEP_ANALYSIS", description = "If true, analyze method bodies. If false, only analyze fields and method signatures.")
    public void setDeepAnalysis(final boolean deepAnalysis) {
        this.fDeepAnalysis = deepAnalysis;
    }

    protected boolean isDeepAnalysis() {
        return this.fDeepAnalysis;
    }

    private boolean fIncrementalMode;

    @Parameter(name = "INCREMENTAL_MODE", description = "Optimize memory use by analyzing incrementally (more time expensive).")
    public void setIncrementalMode(final boolean incrementalMode) {
        this.fIncrementalMode = incrementalMode;
    }

    protected boolean isIncrementalMode() {
        return this.fIncrementalMode;
    }

    private String includedElementsRegEx;

    @Parameter(name = "INCLUDED_ELEMENTS_REGEX", description = "A regular expression on qualified names for elements (types & packages) to be included during analysis")
    public void setIncludedElementsRegEx(final String includedElementsRegEx) {
        this.includedElementsRegEx = includedElementsRegEx;
    }

    protected String getIncludedElementsRegEx() {
        return this.includedElementsRegEx;
    }

    private String excludedElementsRegEx;

    @Parameter(name = "EXCLUDED_ELEMENTS_REGEX", description = "A regular expression on qualified names for elements (types & packages) to be excluded during analysis")
    public void setExcludedElementsRegEx(final String excludedElementsRegEx) {
        this.excludedElementsRegEx = excludedElementsRegEx;
    }

    protected String getExcludedElementsRegEx() {
        return this.excludedElementsRegEx;
    }

    @SuppressWarnings("static-method") /* designed for overridability */
    public JavaFactory getEFactory() {
        return org.eclipse.gmt.modisco.java.emf.JavaFactory.eINSTANCE;
    }

    protected void analyzeJavaProject(final IJavaProject source, final IProgressMonitor monitor) {
        if (source == null) {
            throw new IllegalArgumentException("source is null"); //$NON-NLS-1$
        }
        IProject project = source.getProject();

        setDefaultTargetURI(URI.createPlatformResourceURI(project.getFullPath().append(project.getName()).toString()
                .concat(JavaDiscoveryConstants.JAVA_MODEL_FILE_SUFFIX), true));

        if (this.fElementsToAnalyze == null) {
            this.fElementsToAnalyze = new ElementsToAnalyze(source);
        }

        ElementsToAnalyze elementsToDiscover = computeElementsToDiscover(this.fElementsToAnalyze);

        createTargetModel();
        Model model = getEFactory().createModel();
        BindingManager globalBindings = getBindingManager();
        getTargetModel().getContents().add(model);

        IModelReader reader = null;
        for (Entry<IModelReader, Object> readerEntry : getReaders(elementsToDiscover).entrySet()) {
            if (monitor.isCanceled()) {
                return;
            }
            reader = readerEntry.getKey();
            Object element = readerEntry.getValue();
            reader.readModel(element, model, globalBindings, monitor);
        }
        if (reader != null) {
            reader.terminate(monitor);
        }
        model.setName(project.getName());
        endAnalyzeJavaProject(model);
    }

    protected void endAnalyzeJavaProject(final Model model) {
        //
    }

    /*
     * This method makes sure that one ElementsToAnalyze instance is still coherent
     * to one Java project (jars and dependencies may have changed), and update it if needed.
     */
    public static ElementsToAnalyze computeElementsToDiscover(final ElementsToAnalyze userElementsToAnalyze) {
        try {
            IJavaProject javaProject = userElementsToAnalyze.getJavaProject();
            if (javaProject == null) {
                return userElementsToAnalyze.clone();
            }
            List<Object> discoverableElements = computeDiscoverableElements(userElementsToAnalyze.getJavaProject());
            ElementsToAnalyze elementsToAnalyze = userElementsToAnalyze.clone();

            // make sure the source java project is selected
            elementsToAnalyze.addElementToDiscover(javaProject);

            // remove any project/library that is not on the project classpath
            List<Object> elementsToRemove = new ArrayList<Object>();
            for (Object oldParameter : elementsToAnalyze.getElementsToDiscover()) {
                if (!oldParameter.equals(javaProject) && !discoverableElements.contains(oldParameter)) {
                    elementsToRemove.add(oldParameter);
                }
            }
            for (Object oldParameterToRemove : elementsToRemove) {
                elementsToAnalyze.removeElementToDiscover(oldParameterToRemove);
            }
            return elementsToAnalyze;
        } catch (CloneNotSupportedException e) {
            MoDiscoLogger.logError(e, JavaActivator.getDefault());
            return null;
        }
    }

    public static List<Object> computeDiscoverableElements(final IJavaProject javaProject) {
        // retrieve required projects and libraries
        Set<IJavaProject> projects = null;
        Set<IPackageFragmentRoot> libraries = null;
        final List<Object> discoverableElements = new ArrayList<Object>();
        try {
            projects = computeRequiredProjects(javaProject);
            libraries = computeRequiredLibraries(projects);
        } catch (JavaModelException e) {
            MoDiscoLogger.logError(e, JavaActivator.getDefault());
            return discoverableElements;
        }

        discoverableElements.addAll(projects);
        discoverableElements.addAll(libraries);

        return discoverableElements;
    }

    @Override
    public String toString() {
        return Messages.DiscoverJavaModelFromJavaProject_title;
    }

    public static Set<IJavaProject> computeRequiredProjects(final IJavaProject project) throws JavaModelException {
        Set<IJavaProject> projects = new LinkedHashSet<IJavaProject>();
        if (project == null) {
            return projects;
        }
        // we keep package fragments which are binaries
        projects.add(project);
        for (String projectName : project.getRequiredProjectNames()) {
            IJavaProject requiredProject = project.getJavaModel().getJavaProject(projectName);
            if (requiredProject.getProject().isAccessible()) {
                projects.add(requiredProject);
            }
        }
        return projects;
    }

    protected static Set<IPackageFragmentRoot> computeRequiredLibraries(final Collection<IJavaProject> projects)
            throws JavaModelException {
        Set<IPackageFragmentRoot> libraries = new LinkedHashSet<IPackageFragmentRoot>();
        // we keep package fragments which are binaries
        for (IJavaProject project : projects) {
            libraries.addAll(computeRequiredLibraries(project));
        }
        return libraries;
    }

    public static Set<IPackageFragmentRoot> computeRequiredLibraries(final IJavaProject project)
            throws JavaModelException {
        Set<IPackageFragmentRoot> libraries = new LinkedHashSet<IPackageFragmentRoot>();
        // we keep package fragments which are binaries
        for (IPackageFragmentRoot lib : project.getPackageFragmentRoots()) {
            if (lib.exists() && lib.getKind() == IPackageFragmentRoot.K_BINARY) {
                libraries.add(lib);
            }
        }
        return libraries;
    }

    protected Map<IModelReader, Object> getReaders(final ElementsToAnalyze elementsToDiscover) {
        Map<IModelReader, Object> readers = new HashMap<IModelReader, Object>();

        for (Object element : elementsToDiscover.getElementsToDiscover()) {
            Map<String, Object> elementOptions = elementsToDiscover.getDiscoveryOptions(element);
            if (element instanceof IJavaProject) {
                JavaReader javaReader = getJavaReader(elementOptions);
                javaReader.setIncremental(isIncrementalMode());
                javaReader.setDeepAnalysis(isDeepAnalysis());
                javaReader.setIncludedElementsRegEx(getIncludedElementsRegEx());
                javaReader.setExcludedElementsRegEx(getExcludedElementsRegEx());

                readers.put(javaReader, element);
            } else if (element instanceof IPackageFragmentRoot) {
                LibraryReader libraryReader = getLibraryReader(elementOptions);
                readers.put(libraryReader, element);
            }
        }
        return readers;
    }

    protected LibraryReader getLibraryReader(final Map<String, Object> elementOptions) {
        return new LibraryReader(getEFactory(), elementOptions);
    }

    protected JavaReader getJavaReader(final Map<String, Object> elementOptions) {
        return new JavaReader(getEFactory(), elementOptions, this);
    }

    protected BindingManager getBindingManager() {
        return new BindingManager(getEFactory());
    }
}