Wojciech Seliga avatar Wojciech Seliga committed 7837959

initial commit

Comments (0)

Files changed (8)

+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.atlassian.jira.plugins</groupId>
+	<artifactId>mail-handler-demo</artifactId>
+	<version>1.0-SNAPSHOT</version>
+
+	<organization>
+		<name>Example Company</name>
+		<url>http://www.example.com/</url>
+	</organization>
+
+	<name>mail-handler-demo</name>
+	<description>This is the com.atlassian.jira.plugins:mail-handler-demo plugin for Atlassian JIRA.</description>
+	<packaging>atlassian-plugin</packaging>
+
+	<dependencies>
+		<dependency>
+			<groupId>com.atlassian.jira</groupId>
+			<artifactId>jira-api</artifactId>
+			<version>${jira.version}</version>
+			<scope>provided</scope>
+		</dependency>
+		<!-- Add dependency on jira-core if you want access to JIRA implementation classes as well as the sanctioned API. -->
+		<!-- This is not normally recommended, but may be required eg when migrating a plugin originally developed against JIRA 4.x -->
+		<!--
+				<dependency>
+					<groupId>com.atlassian.jira</groupId>
+					<artifactId>jira-core</artifactId>
+					<version>${jira.version}</version>
+					<scope>provided</scope>
+				</dependency>
+				-->
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.8.1</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.atlassian.jira</groupId>
+			<artifactId>jira-tests</artifactId>
+			<version>${jira.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.atlassian.jira</groupId>
+			<artifactId>jira-func-tests</artifactId>
+			<version>${jira.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.atlassian.jira</groupId>
+			<artifactId>jira-mail-plugin</artifactId>
+			<version>5.0-SNAPSHOT</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.atlassian.mail</groupId>
+			<artifactId>atlassian-mail</artifactId>
+			<version>2.1</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.mail</groupId>
+			<artifactId>mail</artifactId>
+			<version>1.4.4</version>
+			<scope>provided</scope>
+		</dependency>
+	</dependencies>
+
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>com.atlassian.maven.plugins</groupId>
+				<artifactId>maven-jira-plugin</artifactId>
+				<version>3.7</version>
+				<extensions>true</extensions>
+				<configuration>
+					<productVersion>${jira.version}</productVersion>
+					<productDataVersion>${jira.version}</productDataVersion>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<properties>
+		<!-- TODO: Update to 5.0 after release of 5.0 final -->
+		<jira.version>5.0-SNAPSHOT</jira.version>
+		<amps.version>3.7</amps.version>
+	</properties>
+
+</project>

src/main/java/com/atlassian/jira/plugins/mailhandlerdemo/DemoHandler.java

+package com.atlassian.jira.plugins.mailhandlerdemo;
+
+import com.atlassian.crowd.embedded.api.User;
+import com.atlassian.jira.component.ComponentAccessor;
+import com.atlassian.jira.issue.Issue;
+import com.atlassian.jira.issue.MutableIssue;
+import com.atlassian.jira.mail.MailLoggingManager;
+import com.atlassian.jira.service.util.handler.*;
+import com.atlassian.mail.MailUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.ofbiz.core.util.StringUtil;
+
+import javax.mail.Message;
+import javax.mail.MessagingException;
+
+import java.util.Map;
+
+public class DemoHandler implements MessageHandler {
+	private final Logger logger;
+	private String issueKey;
+	private final IssueKeyValidator issueKeyValidator;
+	private final MessageUserProcessor messageUserProcessor;
+	public static final String KEY_ISSUE_KEY = "issueKey";
+
+	public DemoHandler(MailLoggingManager mailLoggingManager, MessageUserProcessor messageUserProcessor, IssueKeyValidator issueKeyValidator) {
+		this.messageUserProcessor = messageUserProcessor;
+		this.issueKeyValidator = issueKeyValidator;
+		logger = mailLoggingManager.getIncomingMailChildLogger(DemoHandler.class.getSimpleName());
+	}
+
+//	/**
+//	 * Constructor used in production env - unfortunately handlers are instantiated
+//	 * without dependency injection - a parameterless constructor is needed
+//	 */
+//	public DemoHandler() {
+//		this(ComponentAccessor.getOSGiComponentInstanceOfType(MailLoggingManager.class),
+//				ComponentAccessor.getComponent(MessageUserProcessor.class),
+//				ComponentAccessor.getOSGiComponentInstanceOfType(IssueKeyValidator.class));
+//	}
+
+	@Override
+	public void init(Map<String, String> params, MessageHandlerErrorCollector monitor) {
+		issueKey = params.get(KEY_ISSUE_KEY);
+		if (StringUtils.isBlank(issueKey)) {
+			monitor.error("Issue key has not been specified ('" + KEY_ISSUE_KEY + "' parameter). This handler will not work correctly.");
+		}
+		issueKeyValidator.validateIssue(issueKey, monitor);
+	}
+
+	@Override
+	public boolean handleMessage(Message message, MessageHandlerContext context) throws MessagingException {
+		logger.debug("handling my wonderful message");
+
+		final Issue issue = issueKeyValidator.validateIssue(issueKey, context.getMonitor());
+		final User sender = messageUserProcessor.getAuthorFromSender(message);
+		if (sender == null) {
+			context.getMonitor().error("Message sender(s) '" + StringUtils.join(MailUtils.getSenders(message), ",")
+					+ "' do not have corresponding users in JIRA. Message will be ignored");
+			return false;
+		}
+		final String body = MailUtils.getBody(message);
+		final StringBuilder commentBody = new StringBuilder(message.getSubject());
+		if (body != null) {
+			commentBody.append("\n").append(StringUtils.abbreviate(body, 100000)); // let trim too long bodies
+		}
+		context.createComment(issue, sender, commentBody.toString(), false);
+		return true;
+	}
+
+
+
+}

src/main/java/com/atlassian/jira/plugins/mailhandlerdemo/EditDemoHandlerDetailsWebAction.java

+package com.atlassian.jira.plugins.mailhandlerdemo;
+
+import com.atlassian.configurable.ObjectConfigurationException;
+import com.atlassian.jira.plugins.mail.webwork.AbstractEditHandlerDetailsWebAction;
+import com.atlassian.jira.service.JiraServiceContainer;
+import com.atlassian.jira.service.services.file.AbstractMessageHandlingService;
+import com.atlassian.jira.service.util.ServiceUtils;
+import com.atlassian.jira.util.collect.MapBuilder;
+import com.atlassian.plugin.PluginAccessor;
+
+import java.util.Map;
+
+/**
+ * TODO: Document this class / interface here
+ *
+ * @since v5.0
+ */
+public class EditDemoHandlerDetailsWebAction extends AbstractEditHandlerDetailsWebAction {
+	private final IssueKeyValidator issueKeyValidator;
+
+	public EditDemoHandlerDetailsWebAction(PluginAccessor pluginAccessor, IssueKeyValidator issueKeyValidator) {
+		super(pluginAccessor);
+		this.issueKeyValidator = issueKeyValidator;
+	}
+
+	private String issueKey;
+
+	public String getIssueKey() {
+		return issueKey;
+	}
+
+	@Override
+	protected void copyServiceSettings(JiraServiceContainer jiraServiceContainer) throws ObjectConfigurationException {
+		final String params = jiraServiceContainer.getProperty(AbstractMessageHandlingService.KEY_HANDLER_PARAMS);
+		final Map<String, String> parameterMap = ServiceUtils.getParameterMap(params);
+		issueKey = parameterMap.get(DemoHandler.KEY_ISSUE_KEY);
+	}
+
+
+	@Override
+	protected Map<String, String> getHandlerParams() {
+		return MapBuilder.build(DemoHandler.KEY_ISSUE_KEY, issueKey);
+	}
+
+
+	@Override
+	protected void doValidation() {
+		if (configuration == null) {
+			return; // short-circuit in case we lost session, goes directly to doExecute which redirects user
+		}
+		super.doValidation();
+		issueKeyValidator.validateIssue(issueKey, new WebWorkErrorCollector());
+	}
+
+	@Override
+	public String doDefault() throws Exception
+	{
+		String result = super.doDefault();
+
+
+		if (configuration == null || descriptor == null) {
+			return returnCompleteWithInlineRedirect("EditServerDetails!default.jspa");
+		}
+
+		if (configuration.getServiceId() != null) {
+			JiraServiceContainer serviceContainer = getService(configuration.getServiceId());
+			if (serviceContainer != null) {
+				copyServiceSettings(serviceContainer);
+			} else {
+				return returnCompleteWithInlineRedirect("IncomingMailServers.jspa");
+			}
+		}
+
+		return result;
+	}
+
+	public void setIssueKey(String issueKey) {
+		this.issueKey = issueKey;
+	}
+}

src/main/java/com/atlassian/jira/plugins/mailhandlerdemo/IssueKeyValidator.java

+package com.atlassian.jira.plugins.mailhandlerdemo;
+
+import com.atlassian.jira.issue.Issue;
+import com.atlassian.jira.service.util.handler.MessageHandlerErrorCollector;
+
+/**
+ * TODO: Document this class / interface here
+ *
+ * @since v5.0
+ */
+public interface IssueKeyValidator {
+	Issue validateIssue(String issueKey, MessageHandlerErrorCollector collector);
+}

src/main/java/com/atlassian/jira/plugins/mailhandlerdemo/IssueKeyValidatorImpl.java

+package com.atlassian.jira.plugins.mailhandlerdemo;
+
+import com.atlassian.jira.issue.Issue;
+import com.atlassian.jira.issue.IssueManager;
+import com.atlassian.jira.issue.MutableIssue;
+import com.atlassian.jira.service.util.handler.MessageHandlerErrorCollector;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * TODO: Document this class / interface here
+ *
+ * @since v5.0
+ */
+public class IssueKeyValidatorImpl implements IssueKeyValidator {
+	private final IssueManager issueManager;
+
+	public IssueKeyValidatorImpl(IssueManager issueManager) {
+		this.issueManager = issueManager;
+	}
+
+	@Override
+	public Issue validateIssue(String issueKey, MessageHandlerErrorCollector collector) {
+		if (StringUtils.isBlank(issueKey)) {
+			collector.error("Issue key cannot be undefined.");
+			return null;
+		}
+
+		final MutableIssue issue = issueManager.getIssueObject(issueKey);
+		if (issue == null) {
+			collector.error("Cannot add a comment from mail to issue '" + issueKey + "'. The issue does not exist.");
+			return null;
+		}
+		if (!issueManager.isEditable(issue)) {
+			collector.error("Cannot add a comment from mail to issue '" + issueKey + "'. The issue is not editable.");
+			return null;
+		}
+		return issue;
+	}
+
+}

src/main/resources/atlassian-plugin.xml

+<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.name}" plugins-version="2">
+    <plugin-info>
+        <description>${project.description}</description>
+        <version>${project.version}</version>
+        <vendor name="${project.organization.name}" url="${project.organization.url}"/>
+    </plugin-info>
+    <resource type="i18n" name="i18n" location="com.atlassian.jira.plugins.mailhandlerdemo.messages"/>
+    <component key="issue-key-validator" class="com.atlassian.jira.plugins.mailhandlerdemo.IssueKeyValidatorImpl" public="true">
+            <interface>com.atlassian.jira.plugins.mailhandlerdemo.IssueKeyValidator</interface>
+    </component>
+
+    <message-handler i18n-name-key="demohandler.name"
+                  key="demoHandler" class="com.atlassian.jira.plugins.mailhandlerdemo.DemoHandler"
+            add-edit-url="/secure/admin/EditHandlerDetailsUsingParams!default.jspa"
+                  weight="0"/>
+
+    <webwork1 key="actions" name="Actions" class="java.lang.Object">
+        <actions>
+            <action name="com.atlassian.jira.plugins.mailhandlerdemo.EditDemoHandlerDetailsWebAction"
+                    alias="EditDemoHandlerDetails"
+                    roles-required="admin">
+                <view name="input">/view/editDemoHandlerDetails.vm</view>
+                <view name="securitybreach">/secure/views/securitybreach.jsp</view>
+            </action>
+        </actions>
+    </webwork1>
+</atlassian-plugin>

src/main/resources/com/atlassian/jira/plugins/mailhandlerdemo/messages.properties

+demohandler.name=My Demo Mail Handler

src/main/resources/view/editDemoHandlerDetails.vm

+#* @vtlvariable name="action" type="com.atlassian.jira.plugins.mailhandlerdemo.EditDemoHandlerDetailsWebAction" *#
+#set ($modifierKey = $action.browserUtils.getModifierKey())
+#set ($submitAccessKey = $i18n.getText('AUI.form.submit.button.accesskey'))
+#set ($submitTitle = $i18n.getText('AUI.form.submit.button.tooltip', [$submitAccessKey, $modifierKey]))
+
+#set ($cancelAccessKey = $i18n.getText('AUI.form.cancel.link.accesskey'))
+#set ($cancelTitle = $i18n.getText('AUI.form.cancel.link.tooltip', [$cancelAccessKey, $modifierKey]))
+<html>
+<head>
+    <title>$action.handlerName</title>
+    $webResourceManager.requireResource("com.atlassian.jira.jira-mail-plugin:edit-handler-details-page")
+</head>
+<body>
+    <form class="aui" action="EditDemoHandlerDetails.jspa" method="POST" name="mailHandlerForm" id="mailHandlerForm">
+        <div class="form-body">
+            <h2>$action.handlerName</h2>
+           <span class="global-errors-location">
+                #if ($action.getHasErrorMessages())
+                    #foreach ($error in $action.getFlushedErrorMessages())
+                        #AUImessage("error" "" $textutils.htmlEncode(${error}) "" "" "" "false")
+                        #end
+                #end
+            </span>
+            <input type="hidden" name="atl_token" value="$atl_token">
+            <label for="issue-key">Issue Key</label>
+            <input type="text" class="text" id="issue-key" name="issueKey" value="$!textutils.htmlEncode($issueKey)">
+
+
+        <div class="buttons-container form-footer">
+            <div class="buttons">
+                <div class="test-placeholder"></div>
+                <span class="icon throbber"></span>
+                <input id="testButton" type="submit" disabled class="button" value="$i18n.getText('admin.common.words.test')">
+                #if ($action.editing)
+                    #set ($addButtonLabel = $i18n.getText('common.words.save'))
+                #else
+                    #set ($addButtonLabel = $i18n.getText('common.forms.add'))
+                #end
+                <input id="addButton" type="submit" class="button" value="$!addButtonLabel" accesskey="$submitAccessKey" title="$submitTitle">
+                <a href="IncomingMailServers.jspa" class="cancel" accesskey="$cancelAccessKey" title="$cancelTitle">$i18n.getText("AUI.form.cancel.link.text")</a>
+            </div>
+
+        </div>
+    </form>
+</body>
+</html>
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.