Injected task in confluence page doesn't work
Asked by Christof Hurst:

Hi,

my scenario is to provide a button in a confluence page via an user macro in a confluence plugin.

When clicking the button, an action is called which grabs the page, removes the macro and inserts a task assigned to the user.

This code actually works but the task is not really assigned to the user. It is not mentioned in the tasklist of the user. After opening and saving the page it is there.

Thanks for your help.

```
package de.scandio.confluence.plugins.....

import com.atlassian.confluence.core.ConfluenceActionSupport;
import com.atlassian.confluence.core.ContentEntityObject;
import com.atlassian.confluence.core.DefaultSaveContext;
import com.atlassian.confluence.event.events.content.page.PageCreateEvent;
import com.atlassian.confluence.event.events.content.page.PageUpdateEvent;
import com.atlassian.confluence.pages.AbstractPage;
import com.atlassian.confluence.pages.Page;
import com.atlassian.confluence.pages.PageManager;
import com.atlassian.confluence.pages.PageUpdateTrigger;
import com.atlassian.confluence.pages.actions.PageAware;
import com.atlassian.confluence.plugins.tasklist.Task;
import com.atlassian.confluence.plugins.tasklist.service.InlineTaskService;
import com.atlassian.confluence.user.AuthenticatedUserThreadLocal;
import com.atlassian.confluence.user.ConfluenceUser;
import com.atlassian.event.api.EventPublisher;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class AddAssignedTaskForButton extends ConfluenceActionSupport implements PageAware {

 private static final Logger log = LoggerFactory.getLogger(AddAssignedTaskForButton.class);
 private AbstractPage page;
 private PageManager pageManager;
 private InlineTaskService inlineTaskService;
 private EventPublisher eventPublisher;
 private String taskId;
 private String taskDate;
 private String taskText;
 private String taskUserkey;
 private String taskSnippetBody = "%s&nbsp;<time datetime=\"%s\" /><ac:link><ri:user ri:userkey=\"%s\" /></ac:link>&nbsp;<ac:link />";
 private String taskSnippet = "<ac:task-list>\n" +
 " <ac:task>\n" +
 " <ac:task-id>%s</ac:task-id>\n" +
 " <ac:task-status>incomplete</ac:task-status>\n" +
 " <ac:task-body>%s</ac:task-body>\n"+
 " </ac:task>\n" +
 "</ac:task-list>";

 public String execute() throws ParseException {

 Page oldVersionPage = (Page) page.clone();
 String pageTitle = page.getTitle();
 long contentID = page.getContentId().asLong();
 String pageContentOld = page.getBodyContent().getContent().getBodyAsString();
 taskUserkey = AuthenticatedUserThreadLocal.get().getKey().getStringValue();
 String userName = AuthenticatedUserThreadLocal.get().getName();

 log.info("Substituting macro button with task in page: " + pageTitle);
 log.debug("Old page content" + pageContentOld);

 Document pageContent = Jsoup.parse(pageContentOld, "", Parser.xmlParser());
 if (pageContent != null) {
 log.debug("Page content converted to XML");
 Elements existingMacros = pageContent.getElementsByAttributeValue("ac:name", "dihk-taskassign-macro");

 log.debug("Macro found");
 if (existingMacros != null) {
 Element myButtonMacro = existingMacros.first();

 // extract macro parameters to local variables
 retrieveMacroInfos(myButtonMacro);
 log.debug("Params Set");
 String newTaskBody = String.format(taskSnippetBody, taskText, taskDate, taskUserkey);

 Task dummyTask = inlineTaskService.find(contentID, Long.valueOf(taskId));
 Task task = inlineTaskService.create(new Task.Builder()
 .withContentId(dummyTask.getContentId())
 .withGlobalId(dummyTask.getGlobalId())
 .withId(dummyTask.getId())
 .withDueDate(new SimpleDateFormat("yyyy-MM-dd").parse(taskDate))
 .withAssignee(userName)
 .withBody(newTaskBody)
 .withCreator(userName)
 .withCreateDate(new Date())
 .withUpdateDate(new Date())
 .build());
 Task newtask = inlineTaskService.update(task, userName, false, true);
 Task testTask = inlineTaskService.find(contentID, Long.valueOf(taskId));

 // remove macro from document, append task to previous sibling
 Element previousElem = myButtonMacro.previousElementSibling();
 myButtonMacro.remove();
 previousElem.after(String.format(taskSnippet, taskId, newTaskBody));
 }
 }
 // Add new content to page and replace newlines in task-id
 page.setBodyAsString(pageContent.toString().replaceAll("<ac:task-id>\\s*(\\d+)\\s*</ac:task-id>", "<ac:task-id>$1</ac:task-id>"));
 page.setLastModificationDate(new Date());
 pageManager.saveContentEntity(page, oldVersionPage,new DefaultSaveContext.Builder()
 .updateLastModifier(true)
 .suppressAutowatch(true)
 .suppressEvents(false)
 .suppressNotifications(true)
 .build());
 eventPublisher.publish(new PageUpdateEvent(oldVersionPage, (Page) page, oldVersionPage, true, PageUpdateTrigger.EDIT_PAGE));
 return "success";
 }

 private void retrieveMacroInfos(Element node) {
 Elements macroTags = node.getAllElements();
 log.debug("MacroParamsSize: " + macroTags.size());
 for (Element macroTag : macroTags) {
 String tagName = macroTag.tagName();
 String attribute = macroTag.attr("ac:name");
 if (attribute.equals("taskDate")) {
 log.debug("Found Date");
 taskDate = macroTag.ownText();
 } else if (attribute.equals("taskText")) {
 log.debug("Found Text");
 taskText = macroTag.ownText();
 } else if (tagName.equals("ac:task-id")) {
 taskId = macroTag.ownText();
 }
 }
 }

 @Override
 public AbstractPage getPage() {
 return page;
 }

 @Override
 public void setPage(AbstractPage abstractPage) {
 this.page = abstractPage;
 }

 @Override
 public boolean isPageRequired() {
 return true;
 }

 @Override
 public boolean isLatestVersionRequired() {
 return true;
 }

 @Override
 public boolean isViewPermissionRequired() {
 return true;
 }

 @Override
 public boolean isEditPermissionRequired() {
 return true;
 }

 public void setPageManager(PageManager pageManager) {
 this.pageManager = pageManager;
 }

 public void setInlineTaskService(InlineTaskService inlineTaskService) {
 this.inlineTaskService = inlineTaskService;
 }

 public void setEventPublisher(EventPublisher eventPublisher) {
 this.eventPublisher = eventPublisher;
 }
}
```


Answers:
author: Bill Bailey
body: Could you post your code?

comments: author: Christof Hurst
body: I used only XML/HTML manipulation and this is oviously the wrong way. For this I think my code is not useful.

Perhaps someone has a snippet how to insert a task programmatically with Task class or InlineTaskService class.


author: Christof Hurst
body: Hi Bill,

I posted a nearly working code.


Tags: confluence-server

server