org.nuiton.jredmine.plugin.AbstractRedmineMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of maven-jredmine-plugin Show documentation
Show all versions of maven-jredmine-plugin Show documentation
JRedmine maven plugin to interacts with Redmine's server
/*
* *##%
* 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;
}
}