org.sonar.ant.Launcher.java Source code

Java tutorial

Introduction

Here is the source code for org.sonar.ant.Launcher.java

Source

/*
 * Sonar Ant Task
 * Copyright (C) 2011 SonarSource
 * dev@sonar.codehaus.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
 */

package org.sonar.ant;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.commons.configuration.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.Main;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.FileResource;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.Batch;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonar.batch.bootstrapper.ProjectDefinition;
import org.sonar.batch.bootstrapper.Reactor;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;

public class Launcher {

    private SonarTask task;

    public Launcher(SonarTask task) {
        this.task = task;
    }

    /**
     * This method invoked from {@link SonarTask}.
     */
    public void execute() {
        initLogging();
        executeBatch();
    }

    ProjectDefinition defineProject() {
        Project antProject = task.getProject();
        Properties properties = new Properties();
        ProjectDefinition definition = new ProjectDefinition(task.getBaseDir(), task.getWorkDir(), properties);

        definition.addContainerExtension(antProject);

        // Properties from task attributes
        properties.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, task.getKey());
        properties.setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, task.getVersion());
        // Properties from project attributes
        if (antProject.getName() != null) {
            properties.setProperty(CoreProperties.PROJECT_NAME_PROPERTY, antProject.getName());
        }
        if (antProject.getDescription() != null) {
            properties.setProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY, antProject.getDescription());
        }
        // Properties from task
        properties.putAll(task.getProperties());
        // Properties from Ant
        properties.putAll(antProject.getProperties());
        setPathProperties(properties, antProject);

        // Source directories
        for (String dir : getPathAsList(task.createSources())) {
            definition.addSourceDir(dir);
        }
        // Test directories
        for (String dir : getPathAsList(task.createTests())) {
            definition.addTestDir(dir);
        }
        // Binary directories
        for (String dir : getPathAsList(task.createBinaries())) {
            definition.addBinaryDir(dir);
        }
        // Files with libraries
        for (String file : getPathAsList(task.createLibraries())) {
            definition.addLibrary(file);
        }

        defineModules(antProject, definition);

        return definition;
    }

    private ProjectDefinition defineProject(Project antProject) {
        File baseDir = antProject.getBaseDir();
        File workDir = new File(baseDir, ".sonar");
        Properties properties = new Properties();
        ProjectDefinition definition = new ProjectDefinition(baseDir, workDir, properties);

        definition.addContainerExtension(antProject);

        // Properties from project attributes
        if (antProject.getName() != null) {
            properties.setProperty(CoreProperties.PROJECT_NAME_PROPERTY, antProject.getName());
        }
        if (antProject.getDescription() != null) {
            properties.setProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY, antProject.getDescription());
        }
        // Properties from project
        properties.putAll(antProject.getProperties());
        setPathProperties(properties, antProject);

        defineModules(antProject, definition);

        return definition;
    }

    /**
     * @since 1.2
     */
    private void setPathProperties(Properties properties, Project antProject) {
        setPathProperty(properties, antProject, "sonar.libraries");
    }

    /**
     * @since 1.2
     */
    private void setPathProperty(Properties properties, Project antProject, String refid) {
        if (antProject.getReference(refid) == null) {
            return;
        }
        Object reference = antProject.getReference(refid);
        if (!(reference instanceof ResourceCollection)) {

        }
        properties.setProperty(refid, Utils.convertResourceCollectionToString((ResourceCollection) reference));
    }

    private void defineModules(Project antProject, ProjectDefinition definition) {
        String[] modules = StringUtils.split(definition.getProperties().getProperty("sonar.modules", ""), ',');
        for (String module : modules) {
            Project antSubProject = prepareSubProject(antProject, new File(module));
            definition.addModule(defineProject(antSubProject));
        }
    }

    private Project prepareSubProject(Project antProject, File buildFile) {
        ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(task.getClass().getClassLoader());

            Project antSubProject = antProject.createSubProject();
            ProjectHelper.configureProject(antSubProject, buildFile);
            antSubProject.init();

            if (StringUtils.isNotBlank(task.getInitTarget())) {
                // Attaches the build listeners of the current project to the new project
                Iterator iter = antProject.getBuildListeners().iterator();
                while (iter.hasNext()) {
                    antSubProject.addBuildListener((BuildListener) iter.next());
                }
                // Executes initialization target
                antSubProject.executeTarget(task.getInitTarget());
            }

            return antSubProject;

        } finally {
            Thread.currentThread().setContextClassLoader(oldContextClassLoader);
        }
    }

    private List<String> getPathAsList(Path path) {
        List<String> result = new ArrayList<String>();
        for (Iterator<?> i = path.iterator(); i.hasNext();) {
            Resource resource = (Resource) i.next();
            if (resource instanceof FileResource) {
                File fileResource = ((FileResource) resource).getFile();
                result.add(fileResource.getAbsolutePath());
            }
        }
        return result;
    }

    private void executeBatch() {
        ProjectDefinition project = defineProject();
        Reactor reactor = new Reactor(project);
        Batch batch = new Batch(getInitialConfiguration(project),
                new EnvironmentInformation("Ant", Main.getAntVersion()), reactor);
        batch.execute();
    }

    private void initLogging() {
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
        JoranConfigurator jc = new JoranConfigurator();
        jc.setContext(context);
        context.reset();
        InputStream input = Batch.class.getResourceAsStream("/org/sonar/batch/logback.xml");

        System.setProperty("ROOT_LOGGER_LEVEL", getLoggerLevel());
        try {
            jc.doConfigure(input);

        } catch (JoranException e) {
            throw new SonarException("Can not initialize logging", e);

        } finally {
            IOUtils.closeQuietly(input);
        }
    }

    private String getLoggerLevel() {
        int antLoggerLevel = Utils.getAntLoggerLever(task.getProject());
        switch (antLoggerLevel) {
        case 3:
            return "DEBUG";
        case 4:
            return "TRACE";
        default:
            return "INFO";
        }
    }

    private Configuration getInitialConfiguration(ProjectDefinition project) {
        CompositeConfiguration configuration = new CompositeConfiguration();
        configuration.addConfiguration(new SystemConfiguration());
        configuration.addConfiguration(new EnvironmentConfiguration());
        configuration.addConfiguration(new MapConfiguration(project.getProperties()));
        return configuration;
    }

}