Skip to content

Commit

Permalink
Fix JENKINS-26478
Browse files Browse the repository at this point in the history
Added new TEMPLATE content token that can be used to pull in email
content from a file.
  • Loading branch information
slide committed Feb 22, 2015
1 parent 7ab3d59 commit 9b00d78
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 189 deletions.
1 change: 0 additions & 1 deletion src/main/java/hudson/plugins/emailext/AttachmentUtils.java
Expand Up @@ -20,7 +20,6 @@
import java.util.List;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.activation.MimetypesFileTypeMap;
import javax.mail.MessagingException;
import javax.mail.Multipart;
Expand Down
Expand Up @@ -4,7 +4,6 @@
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.TaskListener;
import hudson.plugins.emailext.ExtendedEmailPublisher;
import hudson.plugins.emailext.ExtendedEmailPublisherContext;
import hudson.tasks.Publisher;
Expand Down
@@ -0,0 +1,143 @@
/*
* The MIT License
*
* Copyright 2015 acearl.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.emailext.plugins.content;

import hudson.Plugin;
import hudson.model.AbstractBuild;
import hudson.model.TaskListener;
import hudson.plugins.emailext.ExtendedEmailPublisherDescriptor;
import hudson.tasks.Mailer;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import jenkins.model.Jenkins;
import org.jenkinsci.lib.configprovider.ConfigProvider;
import org.jenkinsci.lib.configprovider.model.Config;
import org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro;
import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;

/**
*
* @author acearl
*/
public abstract class AbstractEvalContent extends DataBoundTokenMacro {

protected static Object configProvider;
protected static final String EMAIL_TEMPLATES_DIRECTORY = "email-templates";
protected final String macroName;

public AbstractEvalContent(String macroName) {
this.macroName = macroName;
}

@Override
public abstract String evaluate(AbstractBuild<?, ?> ab, TaskListener tl, String string) throws MacroEvaluationException, IOException, InterruptedException;

@Override
public boolean acceptsMacroName(String macroName) {
return macroName.equals(this.macroName);
}

public static File scriptsFolder() {
return new File(Jenkins.getInstance().getRootDir(), EMAIL_TEMPLATES_DIRECTORY);
}

protected abstract ConfigProvider getConfigProvider();

@Override
public boolean hasNestedContent() {
return false;
}

protected InputStream getFileInputStream(String fileName, String extension)
throws FileNotFoundException {

InputStream inputStream;
if(fileName.startsWith("managed:")) {
String managedFileName = fileName.substring(8);
try {
inputStream = getManagedFile(managedFileName);
} catch(NoClassDefFoundError e) {
inputStream = null;
}

if(inputStream == null) {
throw new FileNotFoundException(String.format("Managed file '%s' not found", managedFileName));
}
return inputStream;
}

// add .jelly if needed
if (!fileName.endsWith(extension)) {
fileName += extension;
}

inputStream = getClass().getClassLoader().getResourceAsStream(
"hudson/plugins/emailext/templates/" + fileName);

if (inputStream == null) {
final File templateFile = new File(scriptsFolder(), fileName);
inputStream = new FileInputStream(templateFile);
}

return inputStream;
}

private InputStream getManagedFile(String fileName) {
Plugin plugin = Jenkins.getInstance().getPlugin("config-file-provider");
InputStream stream = null;
if(plugin != null) {
Config config = null;
ConfigProvider provider = getConfigProvider();
for(Config c : provider.getAllConfigs()) {
if(c.name.equalsIgnoreCase(fileName) && provider.isResponsibleFor(c.id)) {
config = c;
break;
}
}

if(config != null) {
stream = new ByteArrayInputStream(config.content.getBytes());
}
}
return stream;
}

protected String generateMissingFile(String type, String fileName) {
return type + " file [" + fileName + "] was not found in $JENKINS_HOME/" + EMAIL_TEMPLATES_DIRECTORY + ".";
}

protected String getCharset(AbstractBuild<?, ?> build) {
String charset = Mailer.descriptor().getCharset();
ExtendedEmailPublisherDescriptor descriptor = Jenkins.getInstance().getDescriptorByType(ExtendedEmailPublisherDescriptor.class);
String overrideCharset = descriptor.getCharset();
if (overrideCharset != null) {
charset = overrideCharset;
}
return charset;
}
}
@@ -1,18 +1,12 @@
package hudson.plugins.emailext.plugins.content;

import hudson.ExtensionList;
import hudson.Plugin;
import hudson.model.AbstractBuild;
import hudson.model.Hudson;
import hudson.model.TaskListener;
import hudson.plugins.emailext.plugins.EmailToken;
import hudson.plugins.emailext.ExtendedEmailPublisherDescriptor;
import hudson.plugins.emailext.JellyTemplateConfig.JellyTemplateConfigProvider;
import hudson.tasks.Mailer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
Expand All @@ -24,116 +18,45 @@
import org.apache.commons.jelly.Script;
import org.apache.commons.jelly.XMLOutput;
import org.jenkinsci.lib.configprovider.ConfigProvider;
import org.jenkinsci.lib.configprovider.model.Config;
import org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro;
import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;
import org.xml.sax.InputSource;

@EmailToken
public class JellyScriptContent extends DataBoundTokenMacro {
public class JellyScriptContent extends AbstractEvalContent {

public static final String MACRO_NAME = "JELLY_SCRIPT";
private static final String DEFAULT_HTML_TEMPLATE_NAME = "html";
private static final String DEFAULT_TEXT_TEMPLATE_NAME = "text";
private static final String DEFAULT_TEMPLATE_NAME = DEFAULT_HTML_TEMPLATE_NAME;
private static final String EMAIL_TEMPLATES_DIRECTORY = "email-templates";

private static Object configProvider;
private static final String JELLY_EXTENSION = ".jelly";

@Parameter
public String template = DEFAULT_TEMPLATE_NAME;

@Override
public boolean acceptsMacroName(String macroName) {
return macroName.equals(MACRO_NAME);
public JellyScriptContent() {
super(MACRO_NAME);
}

@Override
public String evaluate(AbstractBuild<?, ?> build, TaskListener listener, String macroName)
throws MacroEvaluationException, IOException, InterruptedException {
InputStream inputStream = null;

try {
inputStream = getTemplateInputStream(template);
inputStream = getFileInputStream(template, JELLY_EXTENSION);
return renderContent(build, inputStream, listener);
} catch (JellyException e) {
return "JellyException: " + e.getMessage();
} catch (FileNotFoundException e) {
String missingTemplateError = generateMissingTemplate(template);
String missingTemplateError = generateMissingFile("Jelly", template);
return missingTemplateError;
} finally {
IOUtils.closeQuietly(inputStream);
}
}

private String generateMissingTemplate(String template) {
return "Jelly script [" + template + "] was not found in $JENKINS_HOME/" + EMAIL_TEMPLATES_DIRECTORY + ".";
}

/**
* Try to get the template from the classpath first before trying the file
* system.
*
* @param templateName
* @return
* @throws java.io.FileNotFoundException
*/
private InputStream getTemplateInputStream(String templateName)
throws FileNotFoundException {

InputStream inputStream;
if(templateName.startsWith("managed:")) {
String managedTemplateName = templateName.substring(8);
try {
inputStream = getManagedTemplate(managedTemplateName);
} catch(NoClassDefFoundError e) {
inputStream = null;
}

if(inputStream == null) {
throw new FileNotFoundException(String.format("Managed template '%s' not found", managedTemplateName));
}
return inputStream;
}

// add .jelly if needed
if (!templateName.endsWith(".jelly")) {
templateName += ".jelly";
}

inputStream = getClass().getClassLoader().getResourceAsStream(
"hudson/plugins/emailext/templates/" + templateName);

if (inputStream == null) {
final File templatesFolder = new File(Hudson.getInstance().getRootDir(), EMAIL_TEMPLATES_DIRECTORY);
final File templateFile = new File(templatesFolder, templateName);
inputStream = new FileInputStream(templateFile);
}
}

return inputStream;
}

private InputStream getManagedTemplate(String templateName) {
Plugin plugin = Jenkins.getInstance().getPlugin("config-file-provider");
InputStream stream = null;
if(plugin != null) {
Config config = null;
ConfigProvider provider = getTemplateConfigProvider();
for(Config c : provider.getAllConfigs()) {
if(c.name.equalsIgnoreCase(templateName) && provider.isResponsibleFor(c.id)) {
config = c;
break;
}
}

if(config != null) {
stream = new ByteArrayInputStream(config.content.getBytes());
}
}
return stream;
}

private static ConfigProvider getTemplateConfigProvider() {
@Override
protected ConfigProvider getConfigProvider() {
if(configProvider == null) {
ExtensionList<ConfigProvider> providers = ConfigProvider.all();
configProvider = providers.get(JellyTemplateConfigProvider.class);
Expand Down Expand Up @@ -172,14 +95,4 @@ private JellyContext createContext(Object it, AbstractBuild<?, ?> build, TaskLis
context.setVariable("rooturl", descriptor.getHudsonUrl());
return context;
}

private String getCharset(AbstractBuild<?, ?> build) {
String charset = Mailer.descriptor().getCharset();
ExtendedEmailPublisherDescriptor descriptor = Jenkins.getInstance().getDescriptorByType(ExtendedEmailPublisherDescriptor.class);
String overrideCharset = descriptor.getCharset();
if (overrideCharset != null) {
charset = overrideCharset;
}
return charset;
}
}

0 comments on commit 9b00d78

Please sign in to comment.