The Atlassian Extension Spaces have been migrated to http://plugins.atlassian.com. These pages are now deprecated and will soon be deleted.

JIRA Misc Workflow Extensions

Error formatting macro: composition-setup: java.lang.NoClassDefFoundError: bucket/container/ContainerManager

cloak.toggle.type=wiki
cloak.toggle.open=>> more info
cloak.toggle.close=<< less info

Plugin download and support
For more information on this plugin, including:
  • download link
  • version history
  • JIRA version compatibility
  • support and bug reporting

please refer to the following entry in the Atlassian Plugin Exchange: https://plugins.atlassian.com/plugin/details/292

Description/Features

This plugin provides a set of workflow extensions (conditions, validators and post-functions) that you can use to customize your JIRA workflows.

Conditions

Previous Status Condition

A workflow condition that allows you to disable a particular transition (hiding it from the list of Available Workflow Actions) if the current Issue either:

  • has never been in the specified Status
  • or was not in the specified Status just before it entered the current Status (if "Most recent status only" is checked)

Separation of Duties Condition (new in 1.1)

A workflow condition that enforces separation of duties (for SAS-70 compliance), i.e. that makes sure the same user cannot trigger two incompatible transitions on the same issue.
For example, you can prevent a user who has triggered the "Resolve Issue" transition on an issue to trigger the "Close" issue.

Validators

Field has been modified Validator (new in 1.3)

A validator that forces users to modify a field during a transition.

Comment Required Validator

A validator than forces users to enter a comment during a transition. If they don't, a customized error message will be displayed.

Field has single value Validator

A workflow validator that checks that a multi-valued field does not contain more than one value during a transition. This can be useful, for example, to make sure users don't select more than one "Fix version" during the Resolve transition.

Previous Status Validator

A validator that does basically the same thing as the Previous Status Condition above.

Parent Status Validator

A workflow validator that ensures that the current issue's parent issue is in one of the specified Statuses. This is useful only for sub-tasks.

Post-functions

Assign to role member (new in 1.2)

A worfklow function that assigns the current issue to the default member of the specified project role.

Assign to last role member (new in 1.2)

A worfklow function that assigns the current issue to the latest Assignee (excluding the current one) who is a member of the specified project role.

Increase value of field Function

A workflow function that increases the value of a numerical field by one.

Set field value from User Property value Function

A workflow function that sets a field to the value of a User Property.

Copy Field Value to Parent Function (new in 1.3.2)

A worfklow function that copies the value(s) of field into the same field of the issue's parent issue.

Add Field Value to Parent Function

A worfklow function that adds the value(s) of a multi-valued field (such as Fix version(s)) into the same field of the issue's parent issue.

Set Issue Security From User's Project Role Function (new in 1.5)

A worfklow function that sets the issue security level based on the Project Role to which the current user belongs. This function can be used on the Create transition to set a different issue security level depending on whether the issue is being created by an internal user or by an external user (e.g. a customer).

Installation

Install the plugin by copying the JAR to WEB-INF/lib inside your JIRA web application and restart JIRA.

Maintenance and new features

If you encounter a problem with this plugin, or if you would like to suggest enhancements or even new workflow extensions, please submit an issue into this plugin's JIRA project. I will look into it as soon as possible.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Dec 02, 2008

    Joshua Levine says:

    Hi, I have two problems i'm trying to solve, maybe these extensions or a future ...

    Hi, I have two problems i'm trying to solve, maybe these extensions or a future extension can help me:

    1) Generate multiple subtasks based on a Multi Checkboxes or a Multi Select custom field

    2) Set fields (e.g. fix versions) from the parent on subtask creation transition

    Thanks,

    Josh

    1. Dec 03, 2008

      David Fischer says:

      Josh, if I understand correctly, you're first looking for a way to create one o...

      Josh,

      if I understand correctly, you're first looking for a way to create one or several subtask(s) during a transition, right? If so, you should look at the Create Sub-Task on transition plugin.

      However, the latter does not answer your two specific issues. Could you describe in more details what you're trying to achieve (the use case)?

      Note that if you automate the creation of subtasks during a transition, you will not give a chance to the user to alter the subtasks in any way - the subtasks can only be populated with predefined values (specified in the transition) and/or values inherited from the parent issue, with no opportunity to alter them except by editing them afterwards.

      David.

      1. Dec 03, 2008

        Joshua Levine says:

        David, Thanks for the quick reply!  I am currently using the [Crea...

        David,

        Thanks for the quick reply!  I am currently using the [Create Sub-Task on transition] plugin but it doesn't really do what I need to do.

        Here's a detailed description of how I'd like a workflow to behave:

        1. Create Issue
          1. Create issue screen: user checks one or more values from a Multi Checkbox
            1. Options: Dev, QA, Design, Product, BI, DB
            2. Selected: Dev, QA, Design
          2. Create issue post-function(s):
            1. Create subtasks based on selections in Multi Select
              1. DEV - issueSummary
                1. inherits fix version from parent
                2. inherits priority from parent
                3. assigns issue to project role "Dev"
              2. QA - issueSummary
                1. inherits fix version from parent
                2. inherits priority from parent
                3. assigns issue to project role "QA"
              3. Design - issueSummary
                1. inherits fix version from parent
                2. inherits priority from parent
                3. assigns issue to project role "Design"

        Does this make sense?

        Thanks!

        Josh

        1. Dec 05, 2008

          David Fischer says:

          Josh, it makes perfect sense (except that I don't understand why you'd want a s...

          Josh,

          it makes perfect sense (except that I don't understand why you'd want a separate QA subtask instead of a step in the workflow - unless this includes QA preparation such as test plan design). However, it doesn't look like a two-hour job, so I can't promise I will be able to do it. I usually develop plugins as part of JIRA deployment assignments, which finance the development effort.

          I'll see what I can do.

          David.

          1. Dec 09, 2008

            Joshua Levine says:

            Thanks David, I understand the resource constraints of the day so no worries th...

            Thanks David,

            I understand the resource constraints of the day so no worries there :)  I keep QA subtask separate so we can perform capacity planning based on issue type.  Heads issue moves through workflow, task traps estimate and time spent.

  2. Dec 10, 2008

    Francis Martens says:

    FYI The jar in the description above is linked to version 1.1 Modifying the link...

    FYI The jar in the description above is linked to version 1.1
    Modifying the link works: http://bamboo.community.atlassian.com/download/JMWE-TRUNK/artifacts/build-9/JAR/jira-misc-workflow-extensions-1.2.jar

    1. Dec 12, 2008

      David Fischer says:

      Ooops! You're quite right, my mistake! The correct link should appear within an...

      Ooops! You're quite right, my mistake!

      The correct link should appear within an hour.

      Thanks!

      David.

  3. Dec 11, 2008

    Marko Anić says:

    Hi, Is there any chance this plugin will work on Enterprise Edition, Version: 3...

    Hi,

    Is there any chance this plugin will work on Enterprise Edition, Version: 3.10.2-#262 ?

    Thanks,

    Marko

    1. Dec 11, 2008

      David Fischer says:

      Marko, I haven't had a chance to test it against v. 3.10.2, but I don't see why...

      Marko,

      I haven't had a chance to test it against v. 3.10.2, but I don't see why it wouldn't work.

      If you do try it out, please let me know the results so I can share the info with the community!

      David.

      1. Dec 11, 2008

        Marko Anić says:

        Hi David, sure, if i get a chance to test it on 3.10.2 I'll let you know on the...

        Hi David,

        sure, if i get a chance to test it on 3.10.2 I'll let you know on the results.

        One question, in Assign to last role member post-function, what happens when no user from specified role was ever assigned to the issue?

        Marko

        1. Dec 11, 2008

          David Fischer says:

          Marko, when no user from the specified role was ever assigned to the issue, the...

          Marko,

          when no user from the specified role was ever assigned to the issue, then no new assignment takes places. Therefore, the assignee will remain what it was before the post-function was executed.
          Therefore, if you want to specify a default assignee in case no user from the specified role was ever assigned to the issue, you can simply set the assignee to that user in a post-function placed above (before) the Assign to last role member function in the transition.

          David.

          1. Dec 11, 2008

            Marko Anić says:

            Thought that was the case, just wanded to make sure. Thank you! Cheers, Ma...

            Thought that was the case, just wanded to make sure. Thank you!

            Cheers,

            Marko

  4. Dec 16, 2008

    Michael Saupe says:

    Hello David, I use the post function "Assign to role member" of this plugin in ...

    Hello David,

    I use the post function "Assign to role member" of this plugin in the "Create" transition of an issue (use of JIRA 3.13.1).

    The assignment works fine but I have the following strange behaviour:
    If I create the issue then the following error message appears on the "Create" screen:

    Errors

    • java.lang.NullPointerException at com.atlassian.jira.issue.managers.DefaultIssueManager.notifyTrackbacks(DefaultIssueManager.java:395) at com.atlassian.jira.issue.managers.DefaultIssueManager.createIssue(DefaultIssueManager.java:379) at com.atlassian.jira.issue.managers.DefaultIssueManager.createIssue(DefaultIssueManager.java:326) at sun.reflect.GeneratedMethodAccessor598.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.atlassian.util.profiling.object.ObjectProfiler.profiledInvoke(ObjectProfiler.java:71) at com.atlassian.jira.config.component.SwitchingInvocationHandler.invoke(SwitchingInvocationHandler.java:28) at $Proxy3.createIssue(Unknown Source) at com.atlassian.jira.web.action.issue.CreateIssueDetails.createIssue(CreateIssueDetails.java:141) at com.atlassian.jira.web.action.issue.CreateIssueDetails.doExecute(CreateIssueDetails.java:110) at webwork.action.ActionSupport.execute(ActionSupport.java:153) at com.atlassian.jira.action.JiraActionSupport.execute(JiraActionSupport.java:54) at webwork.dispatcher.GenericDispatcher.executeAction(GenericDispatcher.java:132) at com.atlassian.jira.web.dispatcher.JiraServletDispatcher.service(JiraServletDispatcher.java:178) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.jira.web.filters.AccessLogFilter.doFilter(AccessLogFilter.java:73) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:119) at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:55) at com.atlassian.jira.web.filters.SitemeshExcludePathFilter.doFilter(SitemeshExcludePathFilter.java:38) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.seraph.filter.SecurityFilter.doFilter(SecurityFilter.java:192) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.seraph.filter.TrustedApplicationsFilter.doFilter(TrustedApplicationsFilter.java:120) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.seraph.filter.BaseLoginFilter.doFilter(BaseLoginFilter.java:125) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.util.profiling.filters.ProfilingFilter.doFilter(ProfilingFilter.java:132) at com.atlassian.jira.web.filters.JIRAProfilingFilter.doFilter(JIRAProfilingFilter.java:16) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.jira.web.filters.ActionCleanupDelayFilter.doFilter(ActionCleanupDelayFilter.java:43) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.jira.web.filters.RequestCleanupFilter.doFilter(RequestCleanupFilter.java:50) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.johnson.filters.AbstractJohnsonFilter.doFilter(AbstractJohnsonFilter.java:72) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:350) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.gzipfilter.GzipFilter.doFilter(GzipFilter.java:71) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.core.filters.AbstractEncodingFilter.doFilter(AbstractEncodingFilter.java:33) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.jira.appconsistency.db.DatabaseCompatibilityEnforcerFilter.doFilter(DatabaseCompatibilityEnforcerFilter.java:39) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:548) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689) at java.lang.Thread.run(Thread.java:619)
    That means the user has still the "Create Screen" after pressing the "Create" button and it seems to the the user that no issue is created.
    However, if the user browses the project then he can see that the issue is created anyway and the assignment took place.

    What can be the problem that the uncomely error appears?

    Btw: for test purposes I removed the post function from the "create" transition, then the issue is created without an error message. Therefore I think that the error message is related to the use of your plugin.

    Thank you in advance for feedback.

    Best regards,
    Michael

    1. Dec 16, 2008

      David Fischer says:

      Michael, did you make sure to move the "Assign to role member" function after "...

      Michael,

      did you make sure to move the "Assign to role member" function after "Creates the issue originally."? JIRA adds newly created functions at the head of the list, which doesn't work for the "Create" transition since the Issue must be created before you can apply a function to it...

      Let me know,

      David.

      1. Dec 17, 2008

        Michael Saupe says:

        Hello David, Thank you very much for your hint. It was my mistake that I placed...

        Hello David,

        Thank you very much for your hint.
        It was my mistake that I placed the "Assign to role member" function before "Creates the issue originally.".

        Now it works. Great!

        Best regards,
        Michael

  5. Dec 23, 2008

    Tal Abramson says:

    First Thanks for gathering all these useful actions too bad that the "Add Fiel...

    First

    Thanks for gathering all these useful actions

    too bad that the "Add Field Value to Parent Function" is not working for me , i could really use it
    it simply does not copy the value
    i tried it with 3.12 and 3.11 , and with Multi select and with single select
    There are no errors in the log

    thanks anyway
    Tal

    1. Dec 23, 2008

      Tal Abramson says:

      OK , so i found whats wrong , it is only adding the field values , if the parent...

      OK , so i found whats wrong , it is only adding the field values , if the parent already has some values
      i have changed it to make it set the parent values always:

         public void execute(Map transientVars, Map args, PropertySet ps)
                  throws WorkflowException {
              String fieldKey = (String) args.get(FIELD);
              Field field = (Field) getFieldFromKey(fieldKey);
              if (field == null) {
                  log.warn("Error while executing function : field [" + fieldKey
                          + "] not found");
                  return;
              }
      
              boolean indexingPreviouslyEnabled = false;
      
              try {
                  MutableIssue issue = getIssue(transientVars);
                  Object sourceValue = WorkflowUtils.getFieldValueFromIssue(issue,
                          field);
                  if (sourceValue != null && sourceValue instanceof Collection) {
                      // get the parent issue
                      MutableIssue parentIssue = (MutableIssue) issue.getParentObject();
                      //get parent issue's field value
                      Collection parentValue = new TreeList();
                      indexingPreviouslyEnabled = ImportUtils.isIndexIssues();
                      if (!indexingPreviouslyEnabled)
                          ImportUtils.setIndexIssues(true);
                      parentValue.addAll((Collection) sourceValue);
                      WorkflowUtils.setFieldValue(parentIssue, field, parentValue);
                      //trigger an edit on the issue
                      Map actionParams = EasyMap.build("issue", parentIssue.getGenericValue(), "issueObject", parentIssue, "remoteUser", this.getCaller(transientVars, args));
                      actionParams.put("comment", "Added " + field.getName() + " from sub-task " + issue.getKey());
                      actionParams.put("commentLevel", null);
                      ActionResult aResult = CoreFactory.getActionDispatcher().execute(ActionNames.ISSUE_UPDATE, actionParams);
                      if (aResult.getResult() != null && !aResult.getResult().equals("success"))
                          log.error(aResult.getResult());
                  }
      
              } catch (Exception e) {
                  log.warn("Error while executing function : " + e, e);
              } finally {
                  if (!indexingPreviouslyEnabled)
                      ImportUtils.setIndexIssues(false);
              }
          }
      
      1. Jan 05, 2009

        David Fischer says:

        Tal, thanks for bringing up this issue. I've created a JIRA issue in the proble...

        Tal,

        thanks for bringing up this issue. I've created a JIRA issue in the problem tracker.
        The issue is fixed in version 1.2.1, released today.

        Note that your proposed fix did not add values from the sub-task to the parent issue but instead replaced the values of the parent issue (which is not the intent of my post-function). My fix behaves therefore differently from yours.

        David.

        1. Jan 05, 2009

          Tal Abramson says:

          I know , thats what i needed

          I know , thats what i needed

  6. Jan 08, 2009

    Mike Curwen says:

    Hi, this plugin looks great.  (for David: ) can you think of a reason this ...

    Hi, this plugin looks great.  (for David: ) can you think of a reason this plugin won't work in jira 3.12.x ?

    1. Jan 08, 2009

      David Fischer says:

      Mike, I've actually tested (albeit not thoroughly) version 1.2.1 of my plugin a...

      Mike,

      I've actually tested (albeit not thoroughly) version 1.2.1 of my plugin against JIRA 3.10.2 and it seems to work. So I don't see any reason why it wouldn't work on 3.12.x.

      David.

      1. Jan 09, 2009

        Marko Anić says:

        I've tested the plugin (not every functionality) with Enterprise Edition, Versio...

        I've tested the plugin (not every functionality) with Enterprise Edition, Version: 3.10.2-#262 and it works great.

        Cheers,

        Marko

  7. Jan 27, 2009

    Ganzha Vitaliy (Ukraine) says:

    Thanks a lot! Your "Previous Status Condition" is exactly what we need!

    Thanks a lot! Your "Previous Status Condition" is exactly what we need!

    1. Jan 27, 2009

      Ganzha Vitaliy (Ukraine) says:

      Thanks again for the "Comment Required Validator"!!!!

      Thanks again for the "Comment Required Validator"!!!!

      1. Jan 27, 2009

        David Fischer says:

        You're quite welcome. Glad I could help. David.

        You're quite welcome. Glad I could help.

        David.

  8. Jan 27, 2009

  9. Jan 27, 2009

    Ganzha Vitaliy (Ukraine) says:

    I'm trying to use "Set field value from User Property value Function". I want t...

    I'm trying to use "Set field value from User Property value Function". I want to store the country from my user properties write into custom field (Text Field type). In my user propeties i set following values: myDept : TestingDept,Country : Ukraine, BigBoss : vganzha.
    I add a PostFunction on some transition (Set field value from User Property value Function), that set user value with key "Country" into custom field "Country". But when I execute this transition I get following error:
    "Error creating issue: Unable to copy value from Country to fieldcustomfield_10151".
    In JIRA log I founded following error trace:

    "2009-01-27 14:14:01,275 http-8080-Processor22 ERROR [com.innovalog.jmwe.plugins] Unable to copy value from Country to fieldcustomfield_10151
    com.opensymphony.user.EntityNotFoundException: No user Ukraine found
    at com.opensymphony.user.UserManager.getEntity(UserManager.java:302)
    at com.opensymphony.user.UserManager.getUser(UserManager.java:193)
    at com.innovalog.jmwe.plugins.functions.SetFieldFromUserPropFunction.execute(SetFieldFromUserPropFunction.java:54)" and so on.

    As I understand, this post-function trying to find user with name equal to user property value. Why? I just want to write this value into a customfield! Or I misunderstood something?
    (P.S. Sorry if I make misstakes in this text, English isn't my native language)

    1. Jan 27, 2009

      David Fischer says:

      I think there's a bug I did not notice earlier because I was using the post func...

      I think there's a bug I did not notice earlier because I was using the post function differently. I'll try to look into it tonight.

      1. Jan 27, 2009

        Ganzha Vitaliy (Ukraine) says:

        I checked the code and I found an error: Bar.java window.SyntaxHighlighter.co...

        I checked the code and I found an error:

        Bar.java
        
        User user = UserManager.getInstance().getUser(value);
        			if (user == null) {
        				log.warn(String.format("Unable to find user [%s]", value));
        				return;
        			} 
        

        in execute function of SetFieldFromUserPropFunction class. I just comment this fragment of code and it works!!!

        1. Jan 27, 2009

          Ganzha Vitaliy (Ukraine) says:

          Full code of this class: Bar.java window.SyntaxHighlighter.config.clipboardSw...

          Full code of this class:

          Bar.java
          package com.innovalog.jmwe.plugins.functions;
          
          import java.util.Map;
          
          import org.apache.log4j.Logger;
          
          import com.atlassian.jira.issue.MutableIssue;
          import com.atlassian.jira.issue.fields.Field;
          import com.atlassian.jira.workflow.function.issue.AbstractJiraFunctionProvider;
          import com.innovalog.googlecode.jsu.util.LogUtils;
          import com.innovalog.googlecode.jsu.util.WorkflowUtils;
          import com.opensymphony.module.propertyset.PropertySet;
          import com.opensymphony.user.User;
          import com.opensymphony.user.UserManager;
          import com.opensymphony.workflow.WorkflowException;
          
          /**
           * 
           */
          public class SetFieldFromUserPropFunction extends
          		AbstractJiraFunctionProvider {
          	private final Logger log = LogUtils.getGeneral();
          
          	@SuppressWarnings("unchecked")
          	public void execute(Map transientVars, Map args, PropertySet ps)
          			throws WorkflowException {
          		log.debug("");
          		String sourcePropKey = (String) args
          				.get(WorkflowSetFieldFromUserPropFunction.FUNCPARAM);
          		User curUser = this.getCaller(transientVars, args);
          		if (curUser == null)
          			return; // transition is ran anonymously
          
          		if (!curUser.getPropertySet().exists("jira.meta." + sourcePropKey)) {
          			log
          					.warn(String
          							.format(
          									"Unable to find user property [%s] on current user",
          									sourcePropKey));
          			return;
          		}
          		String value = curUser.getPropertySet().getString(
          				"jira.meta." + sourcePropKey);
          
          		String sourceFieldKey = (String) args.get(WorkflowSetFieldFromUserPropFunction.FIELD);
          		Field fieldFrom = (Field) WorkflowUtils.getFieldFromKey(sourceFieldKey);
          		if (fieldFrom == null) {
          			log.warn(String.format("Unable to find field with key [%s]", sourceFieldKey));
          			return;
          		}
          
          		try {
          			MutableIssue issue = getIssue(transientVars);
          			/*
          			User user = UserManager.getInstance().getUser(value);
          			if (user == null) {
          				log.warn(String.format("Unable to find user [%s]", value));
          				return;
          			}
          			*/
          			WorkflowUtils.setFieldValue(issue, fieldFrom, value);
          			issue.store();
          
          			if (log.isDebugEnabled()) {
          				log.debug(String.format("Set field %s to [%s]", sourceFieldKey, value));
          			}
          		} catch (Exception e) {
          			final String message = "Unable to copy value from " + sourcePropKey
          					+ " to field" + sourceFieldKey;
          
          			log.error(message, e);
          
          			throw new WorkflowException(message);
          		}
          	}
          } 
          
          
          1. Feb 01, 2009

            David Fischer says:

            I've posted a new version of the plugin that fixes this bug (JMWE-3) in a way th...

            I've posted a new version of the plugin that fixes this bug (JMWE-3) in a way that makes it work with any single-value field type (built-in or custom). Only multi-valued field types won't work (I could do it if someone needed it, I'm just being lazy )

            1. Feb 04, 2009

              Alexandre REY DURIN says:

              David, I'm facing the multi-valued field types issues : I want to copy a user p...

              David,

              I'm facing the multi-valued field types issues : I want to copy a user property storing user main group into a custom field of type 'Group Picker'.

              While one could think this single group field type as single-valued, it seems it can only be updated with a Collection :

               2009-02-04 14:25:46,964 http-8100-Processor25 ERROR [com.innovalog.jmwe.plugins] Unable to copy value from user property groupsMain to field customfield_10050
              java.lang.ClassCastException: com.opensymphony.user.Group cannot be cast to java.util.Collection
                      at com.atlassian.jira.issue.customfields.impl.AbstractMultiCFType.createValue(AbstractMultiCFType.java:122)
                      at com.atlassian.jira.issue.fields.CustomFieldImpl.createValue(CustomFieldImpl.java:575)
                      at com.atlassian.jira.issue.fields.CustomFieldImpl.updateValue(CustomFieldImpl.java:330)
                      at com.atlassian.jira.issue.fields.CustomFieldImpl.updateValue(CustomFieldImpl.java:312)
                      at com.innovalog.googlecode.jsu.util.WorkflowUtils.setFieldValue(WorkflowUtils.java:316)
                      at com.innovalog.jmwe.plugins.functions.SetFieldFromUserPropFunction.execute(SetFieldFromUserPropFunction.java:54)
                      at com.opensymphony.workflow.AbstractWorkflow.executeFunction(AbstractWorkflow.java:869)
              

              It looks like in such a case, value returned by

              value = customField.getCustomFieldType().getSingularObjectFromString((String)value);
              
              should be wrapped into a Collection. Refering to Comment of CustomFieldType interface :

              However, two special conversion methods (getSingularObjectFromString(java.lang.String) & getStringFromSingularObject(java.lang.Object)) act on the Singular Object level. Thus, even when the Transfer Object type is a Collection of Number, getSingularObjectFromString would still return a single Number object.

              I would be so glad that you find enough strength to fight your laziness and enhance this behaviour
              Alex

              1. Feb 05, 2009

                David Fischer says:

                Alex, you can try version 1.2.3 which should work for you (hopefully). David.

                Alex,
                you can try version 1.2.3 which should work for you (hopefully).

                David.

  10. Feb 03, 2009

    Gili Tzabari says:

    "Assign to role member" isn't working for me because the project name contains s...

    "Assign to role member" isn't working for me because the project name contains spaces. Any ideas on how to get this work?

    1. Feb 03, 2009

      Gili Tzabari says:

      Nevermind, it works just fine. I forgot I had a "assign to last role member" rul...

      Nevermind, it works just fine. I forgot I had a "assign to last role member" rule after "assign to role member".

  11. Mar 11, 2009

    Chris Burgener says:

    Hi, I've downloaded, installed the plug-in and restarted JIRA. However, I can't...

    Hi,

    I've downloaded, installed the plug-in and restarted JIRA. However, I can't see the plug-in in my plugin-lib nor see I the functions in the workflow (using 3.13.2-#335). Any idea what I'm doing wrong here?

    Thanks for a hint.

    Chris

    1. Mar 11, 2009

      David Fischer says:

      Chris, what do you mean when you say you don't see the plug-in in your "plugin-...

      Chris,

      what do you mean when you say you don't see the plug-in in your "plugin-lib"?
      If you're using the standalone installation of JIRA, all you have to do to install the plugin is drop the JAR file into WEB-INF/lib and restart JIRA. However, if you're using the WAR version, things are more complicated and you'll need to search JIRA documentation to find out how to install plugins in this case.

      Did you look into the JIRA log files for errors?

      David.

      1. Mar 12, 2009

        Chris Burgener says:

        Hi David, thanks for your reply. We are using the JIRA Standalone version and c...

        Hi David,

        thanks for your reply. We are using the JIRA Standalone version and copied the JAR file into the WEB-INF/lib directory. Also a restart was made. If I now go to JIRA I can't see the Plug-In in the "Installed Plugins" folder (that's what I meant with Plugin-Lib). Also no errors are listed in the log-files. No idea what we are doing wrong.

        Cheers, Chris

  12. Mar 20, 2009

    Tyler Theobald says:

    Though the plugin 1.2.3 appears to be working just fine with our 3.13 JIRA insta...

    Though the plugin 1.2.3 appears to be working just fine with our 3.13 JIRA instance, it is logging warnings at it does its post actions in the stdout_.log.  Since it is working, why are warnings showing up in the log?  Can I turn that off?  Typical examples are....

    2009-03-18 21:08:54,967 http-8080-Processor21 WARN [jmwe.plugins.functions.AssignToRoleMemberFunction] AssignToRoleMember assigning to: Bone, Richard
    2009-03-18 21:26:04,376 http-8080-Processor22 WARN [workflow.function.issue.AssignToLeadFunction] Automatically setting assignee to lead developer t99630

    1. Mar 20, 2009

      David Fischer says:

      Although I take full responsibility for the first example of warning (my mistake...

      Although I take full responsibility for the first example of warning (my mistake, it should be an INFO log) and I will fix that in the next version, I cannot do much about the second type of warning (workflow.function.issue.AssignToLeadFunction) because it is part of JIRA itself. You should log a bug with Atlassian.

      In the meantime, you may want to customize error reporting to omit WARN messages from these two classes (edit WEB-INF/classes/log4j.properties).

      David.

  13. Apr 20, 2009

    David Williams says:

    Hey guys, Great plugin.  One addition that would really help me out is to ...

    Hey guys,

    Great plugin.  One addition that would really help me out is to expand the Assign to Last Role Member post function to also check the status as well.  For example, I would like to be able to auto assign an issue to the last user in a certain role, when the issue was in a certain status.  Thanks again for the plugin.

    David

    1. Apr 20, 2009

      David Fischer says:

      David, Glad that you find this plugin useful. I'm not sure I understand what y...

      David,
      Glad that you find this plugin useful.

      I'm not sure I understand what you need. What is usually useful is to be able to assign an issue back to the owner of the issue in a previous state. But you seem to require that this previous Owner be also of a specific project role, right? This only makes sense if the issue can go several times through the same status, but with different owners. Is this your case?
      Otherwise, you should simply remember the assignee in that status (in a custom field) and restore that owner later on.

      Let me know,

      David

      1. Apr 20, 2009

        David Williams says:

        David, Thanks for your quick response!!  We have a process where i...

        David,

        Thanks for your quick response!!  We have a process where in status A developers code an issue, in status B, dev leads review an issue and in status C, QA reviews the fix.  The issue can be returned to various status at any point.  Using your Assign to Last Role Member post function works good except in the case were a dev lead is also the developer.  That is why I asked if it was possible to add the status to the condition.  This seems to be the most full proof approach.

        I thought about capturing the assignee in a custom field but the only way I know to do that is with a post function which I saw issues with.  Is there another way to store that information?

        Thanks,

        David

        1. Apr 24, 2009

          David Fischer says:

          David, I understand your need. When confronted with it, I usually use the Trans...

          David,

          I understand your need. When confronted with it, I usually use the Transition Search plugin to create a field to hold the assignee I want to be able to reassign the issue to. This plugin does have its limitations, but I can usually live with them. And if I were to create a plugin which did what you suggested, the same limitations would apply (it would not correctly handle issues that have been moved between projects that have different workflows).
          Alternatively, you can copy the Assignee field into a custom field yourself in a transition post function (using JIRA Suite Utilities). Only problem with this approach is that it will not reconstruct the past, i.e. it won't work with issues that have already gone through the transitions you want to track before setting up the post function.

          Let me know if any of these suggestions work for you. If not, please create a request for a new feature in my JIRA project and I'll try to implement something for you.

          David.