org.nuiton.jredmine.plugin.announcement.AbstractAnnouncementMojo 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.announcement;
import java.io.File;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.changes.ChangesXML;
import org.apache.maven.plugins.changes.model.Release;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.velocity.VelocityComponent;
import org.nuiton.jredmine.plugin.AbstractRedmineMojo;
import org.nuiton.plugin.PluginHelper;
/**
*
* @author chemit
* @requiresOnline true
*/
public abstract class AbstractAnnouncementMojo extends AbstractRedmineMojo {
/**
* Directory where the template file will be generated.
*
* @parameter expression="${redmine.templateOutputDirectory}" default-value="${project.build.directory}/generated-sources/announcement"
* @required
* @since 1.0.0
*/
private File templateOutputDirectory;
/**
* The path of the changes.xml file.
*
* @parameter expression="${redmine.xmlPath}" default-value="${basedir}/src/changes/changes.xml"
* @required
* @since 1.0.0
*/
private File xmlPath;
/**
* Directory that contains the template.
*
* Note: This directory must be a subdirectory of
* /src/main/resources/ or current project base directory
.
*
*
* @parameter expression="${redmine.templateDirectory}" default-value="org/nuiton/jredmine/plugin/announcement"
* @required
* @since 1.0.0
*/
private String templateDirectory;
/**
* The template encoding.
*
* @parameter expression="${redmine.templateEncoding}" default-value="${project.build.sourceEncoding}"
* @since 1.0.0
*/
private String templateEncoding;
/**
* Map which will be pass to the velocity context
* @parameter
* @since 1.0.0
*/
private Map announceParameters;
// /**
// * Template strings per system that is used to discover the URL to use to display an attchment. Each key in this
// * map denotes the (case-sensitive) identifier of the issue tracking system and its value gives the URL template.
// *
// * There are 2 template tokens you can use. %URL%
: this is computed by getting the
// * <issueManagement>/<url>
value from the POM, and removing the last '/'
// * and everything that comes after it. %FILE%
: this is the issue number.
// *
// *
// * @parameter expression="${redmine.attachmentLinkTemplate}"
// * @since 1.0.0
// */
// protected String attachmentLinkTemplate;
/**
* @parameter expression="${project.groupId}"
* @readonly
* @since 1.0.0
*/
private String groupId;
/**
* @parameter expression="${project.artifactId}"
* @readonly
* @since 1.0.0
*/
private String artifactId;
/**
* Distribution url of the artifact.
*
* @parameter expression="${redmine.projectUrl}" default-value="${project.url}"
* @required
* @since 1.0.0
*/
private String projectUrl;
/**
* Packaging structure for the artifact.
*
* @parameter expression="${project.packaging}"
* @readonly
* @since 1.0.0
*/
private String packaging;
/**
* The name of the artifact to be used in the announcement.
*
* @parameter expression="${redmine.finalName}" default-value="${project.build.finalName}"
* @required
* @since 1.0.0
*/
private String finalName;
/**
* The current project base directory.
*
* @parameter expression="${basedir}"
* @required
* @since 1.0.0
*/
private String basedir;
/**
* URL where the artifact can be downloaded. If not specified,
* no URL is used.
*
* @parameter
* @since 1.0.0
*/
private String urlDownload;
/**
* Name of the team that develops the artifact.
*
* @parameter expression="${redmine.developmentTeam}" default-value="${project.name} team"
* @required
* @since 1.0.0
*/
private String developmentTeam;
/**
* Short description or introduction of the released artifact.
*
* @parameter expression="${redmine.introduction}" default-value="${project.description}"
* @since 1.0.0
*/
private String introduction;
/**
* A flag to restirct only one run in a build (for multi-module context).
*
* @parameter expression="${redmine.runOnce}" default-value="true"
* @since 1.0.0
*/
private boolean runOnce;
/**
* Velocity Component.
*
* @component roleHint="maven-helper-plugin"
*/
private VelocityComponent velocity;
protected abstract String getAnnouncementTemplate();
protected AbstractAnnouncementMojo() {
super(true, false, true);
}
@Override
protected boolean isRunOnce() {
return runOnce;
}
/**
*
* @return {@code true} if the goal was already invoked
*/
@Override
protected boolean checkRunOnceDone() {
String template = getAnnouncementTemplate();
File out = new File(templateOutputDirectory, template);
Date buildStartTime = session == null ? null : session.getStartTime();
Date newStartTime = out.exists() ? new Date(out.lastModified()) : null;
boolean checkRunOnceDone = checkRunOnceDone(runOnce, true, buildStartTime, newStartTime);
return checkRunOnceDone;
}
@Override
protected boolean init() throws Exception {
versionId = PluginHelper.removeSnapshotSuffix(versionId);
runOnceDone = false;
if (isRunOnce()) {
runOnceDone = checkRunOnceDone();
if (runOnceDone) {
return true;
}
}
if (!super.init()) {
return false;
}
if (!xmlPath.exists()) {
getLog().warn("can not find redmine-template at " + xmlPath + ", goal is skip");
return false;
}
if (StringUtils.isEmpty(templateEncoding)) {
templateEncoding = ReaderFactory.FILE_ENCODING;
getLog().warn(
"File encoding has not been set, using platform encoding " + templateEncoding + ", i.e. build is platform dependent!");
}
if (introduction == null || introduction.trim().isEmpty()) {
introduction = project.getUrl();
}
return true;
}
@Override
protected void doAction() throws Exception {
if (isRunOnceDone()) {
getLog().info("skip goal, runOnce flag is on, and was already executed.");
return;
}
ChangesXML changesXml = new ChangesXML(xmlPath, getLog());
List> releases = changesXml.getReleaseList();
//TODO-TC-20091209 must obtain back the full name of dev from the project team on each action
String template = getAnnouncementTemplate();
File out = new File(templateOutputDirectory, template);
if (verbose) {
getLog().info("destination file " + out);
}
getLog().info("Creating announcement [" + template + "] from " + xmlPath);
VelocityEngine engine = velocity.getEngine();
engine.setApplicationAttribute("baseDirectory", basedir);
AnnouncementGenerator generator = new AnnouncementGenerator(getLog(), projectUrl, "");
// AnnouncementGenerator generator = new AnnouncementGenerator(getLog(), url, attachmentLinkTemplate);
Context context = createVelocityContext(generator, releases);
// generate redmine announcement file
generator.doGenerate(engine, context, out, templateDirectory + "/" + template, templateEncoding);
getLog().info("Created announcement [" + template + "] in " + out);
}
public Context createVelocityContext(AnnouncementGenerator generator, List> releases) throws MojoExecutionException {
// prepare velocity context
Context context = new VelocityContext();
context.put("releases", releases);
context.put("groupId", groupId);
context.put("artifactId", artifactId);
context.put("version", versionId);
// context.put("version", releaseVersion.getName());
context.put("packaging", packaging);
context.put("url", projectUrl);
Release release = generator.getLatestRelease(releases, versionId);
// Release release = generator.getLatestRelease(releases, releaseVersion.getName());
context.put("release", release);
context.put("introduction", introduction);
context.put("developmentTeam", developmentTeam);
context.put("finalName", finalName);
context.put("urlDownload", urlDownload);
context.put("project", project);
//
// if (downloads != null && downloads.length > 0) {
// Map attachmentsUrls = generator.getAttachmentsUrls(downloads);
// Object urls;
// if (attachmentsUrls == null || attachmentsUrls.isEmpty()) {
// urls = Collections.EMPTY_MAP;
// } else {
// urls = attachmentsUrls;
// }
//
// if (verbose) {
// getLog().info("nb attachments : " + ((Map, ?>) urls).size());
// }
//
// if (getLog().isDebugEnabled()) {
// getLog().debug("attachmentsUrls :\n" + urls);
// }
// context.put("attachmentsUrls", urls);
// }
if (announceParameters == null) {
// empty Map to prevent NPE in velocity execution
context.put("announceParameters", Collections.EMPTY_MAP);
} else {
context.put("announceParameters", announceParameters);
}
return context;
}
}