All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.jredmine.plugin.AbstractRedmineMojo Maven / Gradle / Ivy

There is a newer version: 1.2.2
Show newest version
/*
 * *##% 
 * JRedmine maven plugin
 * Copyright (C) 2009 CodeLutin
 *
 * 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 General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * ##%*
 */
package org.nuiton.jredmine.plugin;

import java.net.URL;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.IssueManagement;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.nuiton.io.rest.RestClientConfiguration;
import org.nuiton.plugin.AbstractPlugin;
import org.nuiton.jredmine.model.ModelHelper;
import org.nuiton.jredmine.model.Project;
import org.nuiton.jredmine.model.User;
import org.nuiton.jredmine.model.Version;
import org.nuiton.jredmine.RedmineService;
import org.nuiton.jredmine.RedmineServiceException;
import org.nuiton.jredmine.RedmineServiceImplementor;

/**
 * Abstract redmine mojo.
 * 
 * @author tchemit
 * @since 1.0.0
 * @requiresOnline true
 * @requiresProject true
 */
public abstract class AbstractRedmineMojo extends AbstractPlugin implements RestClientConfiguration {

    public static final String REDMINE_SYSTEM = "redmine";
    /**
     * Dependance du projet.
     *
     * @parameter default-value="${project}"
     * @required
     * @readonly
     * @since 1.0.0
     */
    protected MavenProject project;
    /**
     * The real basedir redmine url.
     *
     * If no url is given, will use the issue management url.
     *
     * @parameter expression="${redmine.url}"
     * @since 1.0.0
     */
    protected URL url;
    /**
     * The redmine's server login.
     *
     * @parameter expression="${redmine.username}"
     * @required
     * @since 1.0.0
     */
    protected String username;
    /**
     * The redmine's server password.
     *
     * @parameter expression="${redmine.password}"
     * @required
     * @since 1.0.0
     */
    protected String password;
    /**
     * The encoding used to read and write files.
     *
     * @parameter expression="${redmine.encoding}" default-value="${project.build.sourceEncoding}"
     * @since 1.0.0
     */
    protected String encoding;
    /**
     * Redmine project name.
     *
     * @parameter expression="${redmine.projectId}" default-value="${project.artifactId}"
     * @required
     * @since 1.0.0
     */
    protected String projectId;
    /**
     * redmine version name.
     *
     * @parameter expression="${redmine.versionId}" default-value="${project.version}"
     * @since 1.0.0
     */
    protected String versionId;
    /**
     * Un flag pour activer le mode verbeux.
     *
     * @parameter expression="${redmine.verbose}"  default-value="${maven.verbose}"
     * @since 1.0.0
     */
    protected boolean verbose;
    /**
     * Un flag pour faire échouer le build si la configuration n'est pas ok.
     *
     * @parameter expression="${redmine.safe}"  default-value="true"
     * @since 1.0.0
     */
    protected boolean safe;
    /**
     * @parameter expression="${session}"
     * @readonly
     */
    protected MavenSession session;
    /**
     * Redmine service.
     *
     * @component
     * @since 1.0.0
     */
    protected RedmineService service;
    /**
     * flag to load in init a required project using the {@link #projectId} name
     */
    private final boolean requireProject;
    /**
     * flag to load in init a required version using the {@link #versionId} name.
     */
    private final boolean requireVersion;
    /**
     * flag to load in init a required user using the user loggued to redmine server.
     */
    private final boolean requireUser;
    /**
     * the project loaded in init if {@link #requireProject} flag is on
     */
    protected Project releaseProject;
    /**
     * the version loaded in init if {@link #requireVersion} flag is on
     */
    protected Version releaseVersion;
    /**
     * the user loaded in init if {@link #requireUser} flag is on
     */
    protected User releaseUser;
    /**
     * cache of users of a given project loaded in int if {@link #requireUser} flag is on
     */
    protected User[] users;
    /**
     * the date format used to write a date
     */
    protected DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    /**
     * flag to mark if a runOnce goal was done
     */
    protected boolean runOnceDone;

    public AbstractRedmineMojo(boolean requireProject, boolean requireVersion, boolean requireUser) {
        super();
        this.requireProject = requireProject;
        this.requireVersion = requireVersion;
        this.requireUser = requireUser;
    }

    ///////////////////////////////////////////////////////////////////////////
    /// AbstractPlugin
    ///////////////////////////////////////////////////////////////////////////
    @Override
    protected boolean init() throws Exception {

        // check issue management

        IssueManagement issueManagement = project.getIssueManagement();

        if (issueManagement == null) {
            getLog().error("No Issue Management set.");

            return false;
        } else if ((issueManagement.getUrl() == null) || (issueManagement.getUrl().trim().equals(""))) {
            getLog().error("No URL set in Issue Management.");

            return false;
        } else if ((issueManagement.getSystem() != null) && !(issueManagement.getSystem().equalsIgnoreCase(AbstractRedmineMojo.REDMINE_SYSTEM))) {
            getLog().error("Redmine's Plugin only supports 'redmine' Issue Management system.");

            return false;
        }
        // prepare Redmine service configuration

        URL url = getRestUrl();

        if (url == null || url.toString().isEmpty()) {

            // no redmine url specified, guess it from issueManagement

            url = new URL(issueManagement.getUrl());

            if (verbose) {
                getLog().info("use the url from issue management : " + url);
            }
        }

        // apply configuration

        setRestUrl(url);

        if (verbose) {
            getLog().info("Redmine configuration :\n>> host     : " +
                    getRestUrl() + "\n>> username : " +
                    getRestUsername());
        }

        // init Redmine service

        try {

            ((RedmineServiceImplementor) service).init(this);

        } catch (Exception e) {
            if (verbose) {
                getLog().error("could not init Redmine service [" + getRestUrl() + "] with user '" + getRestUsername() + "'", e);
            }
            return false;
        }

        // check project exists

        if (requireProject) {
            boolean r = initReleaseProject();
            if (!r) {
                getLog().error("the project '" + projectId + "' could not be retrieve from redmine server, goal is skip");
                return false;
            }
        }

        // check user exists

        if (requireUser) {
            boolean r = initReleaseUser();
            if (!r) {
                getLog().error("the user '" + this.username + "' could not be retrieve from redmine server, goal is skip");
                return false;
            }
        }

        // check version exists

        if (requireVersion) {
            boolean r = initReleaseVersion();
            if (!r) {
                getLog().error("the version '" + versionId + "' could not be retrieve from redmine server, goal is skip");
                return false;
            }
        }

        return true;
    }

    @Override
    public final void execute() throws MojoExecutionException, MojoFailureException {

        boolean canContinue = checkPackaging();

        if (!canContinue) {
            getLog().warn("The goal is skip due to packaging '" + getProject().getPackaging() + "'");
            return;
        }

        if (isGoalSkip()) {
            getLog().warn("The goal is skip due to skipGoal flag on");
            return;
        }

        Exception error = null;
        try {

            try {

                canContinue = init();

            } catch (Exception e) {
                error = e;

                // none safe execution, just warn and not failed the build
                canContinue = false;
            }

            if (!canContinue) {


                if (isSafe()) {
                    String message;
                    if (error != null) {
                        message = "safe mode is on and could not init goal [" + getClass().getSimpleName() + "] for reason " + error.getMessage();
                    } else {
                        message = "safe mode is on and could not init goal [" + getClass().getSimpleName() + "]";
                    }
                    if (isVerbose()) {
                        if (error != null) {
                            getLog().error(message, error);
                        } else {
                            getLog().error(message);
                        }
                    }

                    if (error != null) {
                        if (error instanceof MojoExecutionException) {
                            throw (MojoExecutionException) error;
                        }
                        throw new MojoExecutionException(message, error);
                    }
                    throw new MojoExecutionException(message);
                }

                getLog().warn(skipAfterInitMessage);
                return;
            }

            try {

                doAction();

            } catch (MojoExecutionException e) {
                throw e;
            } catch (Exception e) {
                throw new MojoExecutionException("could not execute goal " + getClass().getSimpleName() + " for reason : " + e.getMessage(), e);
            }

        } finally {
            // always close service (it will release connections to redmine)
            closeService();
        }
    }

    /**
     * Re-expose the protected method for test purposes...
     *
     * @throws Exception
     * @see AbstractPlugin#doAction()
     */
    @Override
    protected abstract void doAction() throws Exception;

    protected abstract boolean isGoalSkip();

    protected abstract boolean isRunOnce();

    protected abstract boolean checkRunOnceDone();
    ///////////////////////////////////////////////////////////////////////////
    /// Plugin
    ///////////////////////////////////////////////////////////////////////////

    @Override
    public MavenProject getProject() {
        return project;
    }

    @Override
    public void setProject(MavenProject project) {
        this.project = project;
    }

    @Override
    public boolean isVerbose() {
        return verbose;
    }

    @Override
    public void setVerbose(boolean verbose) {
        this.verbose = verbose;
    }

    ///////////////////////////////////////////////////////////////////////////
    /// RestClientConfiguration
    ///////////////////////////////////////////////////////////////////////////
    @Override
    public String getRestPassword() {
        return password;
    }

    @Override
    public URL getRestUrl() {
        return url;
    }

    @Override
    public String getRestUsername() {
        return username;
    }

    @Override
    public void setRestPassword(String restPassword) {
        this.password = restPassword;
    }

    @Override
    public void setRestUrl(URL restUrl) {
        this.url = restUrl;
    }

    @Override
    public void setRestUsername(String restUsername) {
        this.username = restUsername;
    }

    @Override
    public String getEncoding() {
        return encoding;
    }

    @Override
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    ///////////////////////////////////////////////////////////////////////////
    /// Others
    ///////////////////////////////////////////////////////////////////////////
    protected boolean initReleaseProject() throws MojoExecutionException {

        if (projectId == null || projectId.trim().isEmpty()) {
            throw new MojoExecutionException("required a projectId parameter");
        }
        try {
            this.releaseProject = service.getProject(projectId);
            return releaseProject != null;
        } catch (RedmineServiceException e) {
            getLog().warn("could not retreave project '" + projectId + "', goal is skip");
            if (verbose) {
                getLog().error(e);
            }
            return false;
        }
    }

    protected boolean initReleaseVersion() throws MojoExecutionException {

        if (versionId == null || versionId.trim().isEmpty()) {
            throw new MojoExecutionException("required a versionId parameter");
        }

        try {

            Version v = service.getVersion(projectId, versionId);

            if (v == null) {

                return false;
            }

            this.releaseVersion = v;
            return true;
        } catch (RedmineServiceException e) {
            getLog().warn("could not retreave version " + versionId + ", goal is skip");
            if (verbose) {
                getLog().error(e);
            }
            return false;
        }
    }

    protected boolean initReleaseUser() {

        try {
            users = service.getUsers(projectId);

            User user = ModelHelper.byLogin(username, users);

            if (user == null) {

                return false;
            }
            this.releaseUser = user;
        } catch (RedmineServiceException e) {
            getLog().warn("could not retreave user '" + username + "', goal is skip");
            if (verbose) {
                getLog().error(e);
            }
            return false;
        }

        return true;
    }

    protected void closeService() {
        if (service != null) {
            RedmineServiceImplementor i;
            i = ((RedmineServiceImplementor) service);

            if (i.isInit()) {
                try {
                    if (verbose) {
                        getLog().info("<<< Close redmine rest client...");
                    }
                    i.destroy();
                } catch (Exception ex) {
                    getLog().error("could not close redmine client for reason " + ex.getMessage(), ex);
                }
            }
        }
    }

    public boolean isRunOnceDone() {
        return runOnceDone;
    }

    public boolean isSafe() {
        return safe;
    }

    public void setSafe(boolean safe) {
        this.safe = safe;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy