There are so many user stories for this one! How do you override some of the JIRA built in actions? How do you do some additional stuff in the JIRA built in action? Like doing some crazy things immediately after creation before the page return to the user? Or doing some innovative validations on some of those actions? Or do what is asked in this thread ?
Here is the simple answer to all those questions. Extends the JIRA actions using the webwork plugin module. There could be some alternatives in few cases (like handling it in a listener) but not always. Webwork plugin module is designed to add more actions on to JIRA as well as to extend or override the existing actions. So how does all this work? Let us quickly have a look at the actions.xml under WEB-INF/classes in your JIRA installation directory. This is where all of the JIRA's actions are defined. Here is the snippet that defines the CreateIssue action.
<action name="issue.CreateIssueDetails" alias="CreateIssueDetails"> <view name="error">/secure/views/createissue-details.jsp</view> <view name="input">/secure/views/createissue-details.jsp</view> </action>
Note: JIRA has both CreateIssue and CreateIssueDetails action. It is the latter which actually creates the Issue. The former is to select the the project and issutype and to proceeed to the issue creation form.
So we have the CreateIssueDetails action which uses the CreateIssueDetails class and the associated jsps. What we will do here is just override this action with our custom action class. We will provide an additional validation and also print some statements after the issue creation. Printing statements is ofcourse not a helpful exmaple but that is just a placeholder where you can do whatever you want to! Here is how the atlassian-plugin.xml looks like when we override the JIRA action.
<webwork1 key="jtricks-create-issue-details" name="JTricks Create Issue Details" > <actions> <action name="com.jtricks.MyCreateIssueDetails" alias="CreateIssueDetails"> <view name="error">/secure/views/createissue-details.jsp</view> <view name="input">/secure/views/createissue-details.jsp</view> </action> </actions> </webwork1>
As usual you need a unique key here. Note that we haven't changed the jsps. But if you want to, you can do that as well! It comes with the extra cost of re-building the war file with the jsp in the edit-webapp (for production instances) and maintaing the version for future upgrades.
Coming back to our example, I have given a custom action class here com.jtricks.MyCreateIssueDetails. As I am not giving a full action class implementation here, I would start with extending the action.
public class MyCreateIssueDetails extends CreateIssueDetails{
It will ask you to add the constructor and so on. Now we override the methods you want. Let us see an example for validation:
@Override protected void doValidation() { //My custom validation here String assignee = getSingleValueFromParameters("assignee"); if (assignee == null || !assignee.equals(getRemoteUser().getName())){ addErrorMessage("Assignee is not the current user, got U!"); } super.doValidation(); }
Here we add an error to the error collection if the assignee is not the current user. Just for the sake of an example! Now let us look at how to do the post creation steps.
@Override protected String doExecute() throws Exception { String ret_val = super.doExecute(); if (!ret_val.equals(Action.ERROR)){ postCreationTasks(); } return ret_val; }
All I am doing is to call the actual Create issue Details's doExecute method and do additional stuff if the retunr value is not error. In the postCreationTasks method, do you stuff like printing something as I do in the example code attached below.
Hopefully that gives an overview of overriding actions in JIRA. The full source for the example can be downloaded below. Feel free to add any suggestions or feedbacks. Have a blast!
103 Comments
J-Tricks
10/6/2010 06:15:16 am
Yes, I have. In fact I faced the same issue in my 'Copy To Subtask' plugin! But this is only post 4.x. I have seen in the forums a workaround for this by overriding the getText() method. Yet to test it :)
Reply
csytsma
10/19/2010 04:25:23 am
If you only wanted to add functionality on the Create Action for specific projects, how would you go about it? Would you use this same method, or use a Listener instead?
Reply
J-Tricks
10/19/2010 04:45:20 am
It will depend on the functionality! In most cases , I will choose a listener because you can have as many listeners as you want on the same event. But you can't have 2 plugins extending the same action!
Reply
Christina
2/24/2011 09:33:49 am
How did you get the parameter fields though (the "assignee")? I'm trying to extend the native Jira link issue action to validate if certain types of issues can have a certain link. But in my code, I seem to be able to get the other parameter names right (comment and linkDesc(link type) and linkKey(child issue)) but I just can't get the current issue that called the link action!
Reply
J-Tricks
2/24/2011 09:48:20 am
Just call getIssue() or getIssueObject() within your validate method. That should give you the original issue GenericValue or MutableIssue object respectively.
Reply
Christina
2/28/2011 12:56:10 pm
So now I'm stuck on another part of the plugin. I have a properties file that I put into the src/main/resources folder, and so it's in the jar file that I put into the Jira installed-plugins folder. However, I'm not sure what its absolute path is that I should put into the code.
Reply
J-Tricks
2/28/2011 06:18:03 pm
Christina,
Reply
Christina
3/4/2011 03:32:26 pm
That is exactly what I have currently. I put it into src/main/resources and it is in the root level of the jar. I've tried:
Reply
J-Tricks
3/4/2011 07:22:05 pm
Did you add it as a downloadbale resource in the atlassian-plugin.xml?
Reply
J-Tricks
3/4/2011 07:24:25 pm
Another useful link for internationalization : http://www.opensymphony.com/webwork/wikidocs/Internationalization.html
Reply
Christina
3/7/2011 10:53:42 am
Thanks it works now! The only thing is that the catalina.out file gives me this error message:
Reply
orchest
6/19/2011 11:30:15 pm
hi
Reply
J-Tricks
6/20/2011 09:14:57 pm
@orchest IssueService is not available in 3.13.1. What are you trying to do using IssueService? You will have to use IssueManager (http://docs.atlassian.com/jira/3.13.1/com/atlassian/jira/issue/IssueManager.html) in 3.13.1 for most operations.
Reply
orchest
6/21/2011 01:03:17 am
i want to create a plugin that can make a search in emails and retrieve an email issue and when i get this issue i would like to create a subtask for it
Reply
J-Tricks
6/22/2011 03:19:54 am
orchest, you will have to write a custom mail handler for it and then process the mail you receive!
Reply
orchest
6/22/2011 04:16:53 am
thank you for answering , now i would like to make to get all my project and i would like to select one of them and then i would like to see all issues of this project and to move this issue to a subtask .
Reply
jiraMan
6/23/2011 04:26:54 am
hi ,
Reply
J-Tricks
6/23/2011 07:18:22 am
@jiraMan Check it out in the following link:
Reply
jiraMan
6/27/2011 04:29:50 am
"jiraMan" is only a desire and not an affermation coz i need to study so much to be a jira man , i'm here again to say that i did not know how to replace "targetIssueType" in the plugin "create and link" "https://plugins.atlassian.com/plugin/details/4964" with issueSummary of the selected project ...
Reply
J-Tricks
6/27/2011 08:19:57 am
@jiraMan Frankly, I haven't used the plugin before. I can answer generic questions but in this case I would approach Matt who is the plugin author!
Reply
Joe Caputo
7/14/2011 06:40:05 pm
Hi there,
Reply
J-Tricks
7/14/2011 07:17:58 pm
@Joe Thanks :)
Reply
Joe Caputo
7/15/2011 09:40:52 am
Hi there.
Reply
J-Tricks
7/18/2011 01:09:10 am
Joe,
Reply
Joe Caputo
7/18/2011 05:25:23 am
Hi there! Thank you very much for getting back to me so quickly. Sorry I'm being such a pain!
Reply
J-Tricks
7/18/2011 06:08:27 am
Joe, No problem!
Reply
7/18/2011 06:15:29 am
That does make sense, but I'm not exactly sure how to do that. I think that's my problem.
Reply
J-Tricks
7/18/2011 06:31:45 am
Checkout the edit template of your customfield and there must be a grouppicker macro used. Inside that macro, you will see the old action invoked. You will have to create a new macro that invokes the new action and use that macro in the customfield edit template!
Reply
7/18/2011 06:28:06 pm
Just wanted to thank you for all your help. With your help, I've successfully created a plugin that does what I want it to do.
Reply
J-Tricks
7/18/2011 10:35:21 pm
@Joe That's awesome :)
Reply
Joe Caputo
11/15/2011 08:11:27 am
Hi there,
Reply
J-Tricks
11/15/2011 10:10:53 am
@Joe, Yes, you can certainly do it. Following is what i would do.
Reply
11/16/2011 03:16:28 am
OK, I think that makes sense. :)
Reply
11/16/2011 03:49:24 am
It seems a bit tricky as I'm not sure how to get an instance of IssueEvent in my class?
Reply
J-Tricks
11/16/2011 05:52:05 am
Yes. the templates will be available once you add it.
Reply
11/16/2011 07:04:29 am
Hmm, ok - trying using that Event Dispatcher. It seems to call it and I get no errors back in the log, but i never get an email. 10000 is my new event i created called "Watcher Added". here is the code:
Reply
J-Tricks
11/16/2011 07:11:09 am
You don't need a Map here. Use http://docs.atlassian.com/jira/latest/com/atlassian/jira/event/issue/IssueEventManager.html#dispatchEvent(java.lang.Long,%20com.atlassian.jira.issue.Issue,%20com.atlassian.crowd.embedded.api.User,%20boolean)
Reply
11/16/2011 07:14:55 am
OK, I'll try that one. Does it hurt to use the map version?
Reply
J-Tricks
11/16/2011 07:17:27 am
That should definitely work!
Reply
11/16/2011 07:26:46 am
Hmmm - yeah, it doesn't seem to be working. When I add the watcher, I get no errors whatsoever. They get added, but nothing else happens. What could it be?
Reply
11/16/2011 07:36:03 am
Here is the full method body:
Reply
J-Tricks
11/16/2011 10:54:12 am
Is this line printed?
Reply
11/17/2011 06:08:01 am
Hey there,
Reply
Joe Caputo
11/17/2011 06:10:04 am
I have another version working but I'm not sure if this is a correct way to do things. But it seems to do what I want. If possible, I think I like your solution better and would like that to work instead. :)
Reply
J-Tricks
11/17/2011 12:32:38 pm
Ok, I get it now. If you want only the watchers who are newly added to be notified, your code looks fine to me.
Reply
11/18/2011 05:58:29 am
I really appreciate your help with all of this. Without you, I don't think I could get very far with some of these things. You are always pointing me in the right direction. :)
Reply
11/18/2011 06:13:43 am
Oh, and just for your information, I'm using a UserMailQueueItem in this case because an issue doesn't exist at this point (therefore I can't use IssueMailQueueItem).
Reply
11/18/2011 07:55:29 am
I'm wondering if i need to add something to the map in order to gain access to those velocity variables?
Reply
11/21/2011 03:37:19 pm
I figured it out sir. All good. :) Thanks very much for your time yet again!
Reply
12/5/2011 08:18:53 am
Hi there!
Reply
J-Tricks
12/6/2011 03:00:41 am
@Joe Do you mean only the developer role shows up? The list is indeed coming from a VM. The original VM is WEB-INF/classes/templates/jira/issue/field/comment-edit.vm.
Reply
12/7/2011 07:14:30 am
Here's an interesting one. This is in regards to the the watcher stuff you helped me out with a little while back.
Reply
12/7/2011 09:44:33 am
Actually, it looks like it doesn't recognize that variable at all. This is what I get in the email. :(
Reply
12/7/2011 10:00:23 am
I'm not sure what I'm doing wrong, but for reference, here is part of the java code that then fires off the mailqueueitem.
Reply
J-Tricks
12/7/2011 11:04:27 pm
@Joe The code looks okay. So the current user email is getting printed correctly in the System.out?
Reply
12/8/2011 04:28:42 am
Hi there,
Reply
12/8/2011 04:35:49 am
To clarify, when I use the #authorlink2 macro, in the mail sent by JIRA, i get:
Reply
J-Tricks
12/8/2011 04:46:54 am
Strange! Can you just try $remoteUser.name and see how it goes?
Reply
12/8/2011 04:55:40 am
I have tried that as well. :)
Reply
J-Tricks
12/10/2011 02:28:48 am
@Joe Maybe it is the behavior of MailQueueItem. I am guessing it takes the recipient name as current user!
Reply
mizan
12/19/2011 04:20:24 pm
Hi,
Reply
J-Tricks
12/19/2011 11:52:37 pm
@mizan Can you please attach your atlassian-plugin.xml contents here?
Reply
mizan
12/20/2011 05:17:21 pm
Hi,
Reply
mizan
12/20/2011 05:24:48 pm
Hi,
Reply
J-Tricks
12/21/2011 12:40:28 am
@mizan You should be getting the issue key in the class right? Use IssueManager to get the issue Object using the key!
Reply
mizan
12/21/2011 03:46:34 pm
i was using " MutableIssue issue = ComponentManager.getInstance().getIssueFactory().getIssue(); " to get the issue instance when i replaced this by " MutableIssue issue1=getIssueObject(); " the plugin works.
Reply
J-Tricks
12/22/2011 03:13:58 am
Awesome :) 3/4/2012 10:28:27 am
Hi
Reply
J-Tricks
3/4/2012 02:51:18 pm
Lars, Are you using the Quick Create form on the right hand top to create the issue? if so, it doesn't fire the CreateIssueDetails action. Instead it fires QuickCreateIssue.jspa. In fact, in JIRA5, it looks like all the Create options fire the above action.
Reply
3/5/2012 10:00:48 am
Sorry to be a pain but I cant get it to work. Yes I am using the quick create option on the upper right corner of the form, and scanning through the jsp files in the secure views folder I dont find a match of the QuickCreate jsp? , the only files that I could see applicable for the webaction is createissue start jsp or the createissue details, but none of them fires the webaction while doing a quick create
Reply
J-Tricks
3/5/2012 02:19:55 pm
Lars,
Reply
Lars Broden
3/5/2012 06:39:59 pm
Ok, that explains why..
J-Tricks
3/6/2012 12:31:22 am
@Lars I see. You can do that with simple Javascript as explained in http://www.j-tricks.com/1/post/2012/02/some-ajs-tricks.html. It shows how to populate description and you can omit the other things like checking for user/groups.
Reply
Lars Broden
3/6/2012 08:44:33 am
Well... even if the script does the trick I am wondering if this might be the right architected solution for my purpose? I was thinking more along the lines of a pluign with a associated UI where you can choose (Wiki rendered free text fields only) which field(s) you want to pre-populate with what and for which projects/forms it should have an impact so that when you choose "quick create" later regardless on which project youre in it would do the correct pre-population based on your earlier settings. The override function for createissue-details.jsp seemed promising, is there a similiar substitute in JIRA 5, that could be used instead?,
Reply
J-Tricks
3/6/2012 09:46:06 am
Unfortunately, I haven't seen a better way to do that in JIRA5. Atlassian themselves uses Javascript and there is no other means to override it!
Adam
3/26/2012 10:49:30 am
Hi,
Reply
Fidel
12/4/2012 10:03:54 pm
I'm getting the same error. Any clue about what's happening?
Reply
J-Tricks
12/5/2012 04:11:53 am
Looks like ClassCastException at ViewIssue.doExecute(ViewIssue.java:149)? What is in there?
Fidel
1/10/2013 10:44:07 pm
Problem solved!!! I was injecting a "WebResourceManager" in "ViewIssue" constructor, according to the declaration of this interface. Nevertheless, implementation of method doExecute() requires a "JiraWebResourceManager", which is a subinterface of "WebResourceManager".
Nikita
5/21/2014 09:18:12 pm
How did you migrate you plugin to jira 6.2? Extending of ViewIssue is not possible now : (
Reply
J-Tricks
5/22/2014 01:28:40 am
Nikita,
Ana
5/25/2012 01:43:17 am
Hello! I have read the comments on this page and I find it very useful!! I'm new at using Jira and I don't know if there is a possibility of associate a list of objets of a certain type to an issue. For example, I could have a list of "Implementation" objects associated to an issue. Each object could have a Date, State and Client name attributes (we can have the same issue for various customers). The type of the fields Jira offers is a simple data-type (like date, text...) but I need a type kind of "Object". Do I need to develop a plugin? Is it possible to make this with Jira?
Reply
Tom
2/27/2013 01:03:33 pm
Hi JTricks. Awesome stuff.
Reply
J-Tricks
2/27/2013 03:08:32 pm
In your case, extending actions will not help. You will have write a listener that captures the new issues and progress them in the workflow based on assignee.
Reply
Sathish
9/5/2013 08:20:31 pm
Hi,
Reply
Fhatu
3/3/2014 07:43:32 pm
Hi,
Reply
J-Tricks
3/6/2014 03:34:50 pm
You can get the value of the text field in the action class by declaring a private variable of the same name and then by defining setter methods for it. Is that what you are looking for?
Reply
Fhatu
3/6/2014 05:50:14 pm
I extended jirawebsupport from another class and it worked 5/14/2014 12:47:49 pm
Hi my friend! I want to say that this post is awesome, good written and incorporate almost all significant infos. I’d like to see more posts like this .
Reply
J-Tricks
5/22/2014 01:26:36 am
Glad you liked it :)
Reply
Kapil Bolli
8/11/2014 03:05:48 am
Hi JTricks,
Reply
J-Tricks
8/11/2014 12:42:31 pm
The view issue page is now broken down into different templates in the jira-view-issue-plugi. Take a look at http://www.j-tricks.com/1/post/2012/05/modifying-atlassian-bundled-plugins.html for example.
Reply
Gustavo
9/23/2014 03:06:14 am
Hello!
Reply
J-Tricks
9/23/2014 04:05:58 am
Nope, JSPs cannot be added in the plugin. They have to be dropped in the webapp.
Reply
Gustavo
9/23/2014 05:11:37 am
Ok. So on every upgrade I will install the plugin and then move the file to jira folder? Is there a good way to do that or just strictly manual?
J-Tricks
9/23/2014 05:46:32 am
Unfortunately, that is the only option now. Manual, unless you have something like chef or puppet to do that for you.
Hello
Reply
J-Tricks
10/24/2014 01:39:57 pm
Take a look at https://developer.atlassian.com/display/JIRADEV/Displaying+Content+in+a+Dialog+in+JIRA. That seems to be the best fit for your need!
Reply
When calling a action method using alias e.g. /secure/upraise/objectives/ObjectiveAction!ListAll.jspa there is no need of part of the uri "/upraise/objectives/", with or without this it works. But if I want to add such a namespace is is possible? otherwise if some other plugin defines "ObjectiveAction", this one gets overridden.
Reply
J-Tricks
4/2/2016 07:58:31 am
Yes, the alias has to be unique.
Reply
Your comment will be posted after it is approved.
Leave a Reply. |
AuthorJobin Kuruvilla - Works in Adaptavist as Head of DevOps Professional Services. Categories
All
Archives
October 2016
|