Recently I have build a plugin which automatically adds links to a page based on the titles of pages in the same space. For example, if I have a page called "Dog" in a space and I make new page with text "My Dog is awesome!" it will automatically add a link to the page dog. The basic source code looks something like this without getting too deep into the details. (let me know if you want them though)
public class AnnotatedListener implements DisposableBean { private static final Logger log = LoggerFactory.getLogger(AnnotatedListener.class); protected EventPublisher eventPublisher; protected PageManager pageManager; public AnnotatedListener(EventPublisher eventPublisher, PageManager pageManager) { linkMarkupForPerfectMatch = "<ac:link><ri:page ri:content-title=\"%s\"/></ac:link>"; linkMarkupForCloseMatch = "<ac:link><ri:page ri:content-title=\"%s\"/><ac:plain-text-link-body><![CDATA[%s]]></ac:plain-text-link-body></ac:link>"; this.eventPublisher = eventPublisher; this.pageManager = pageManager; eventPublisher.register(this); } @EventListener public void pageCreateEvent(PageCreateEvent event) { processEvent(event.getPage()); } @EventListener public void pageUpdateEvent(PageUpdateEvent event) { processEvent(event.getPage()); } @EventListener public void pageViewEvent(PageViewEvent event) { processEvent(event.getPage()); } @Override public void destroy() throws Exception { eventPublisher.unregister(this); } /* * Input: a confluence page * Description: This method does the following things * 1) it finds all the pages in a space which are current * 2) it grabs all of these page titles (ignoring a few blacklisted items) * and it stores them in a list. * 3) it sorts this list in order from longest to shortest title. This * solves a problem where one title is a substring of another and the * shorter title gets linked when the larger one could have been. * 4) it creates a Regex pattern to find all text between <> and <a ... </a> * 5) it calls the parseExact and parseClose methods to add links to the body * 6) it updates the page body */ private void processEvent(Page page) { // clear variables startingBody = ""; afterExact = ""; afterClose = ""; Space space = page.getSpace(); List<Page> pages = pageManager.getPages(space, true); // boolean parameter is currentOnly ArrayList<String> pageTitles = new ArrayList<String>(); for (Page _page : pages) { String title = _page.getTitle(); if (title.startsWith("_") == false) { pageTitles.add(title); } } String currentTitle = page.getTitle(); pageTitles.remove(currentTitle); // don't link to same page Collections.sort(pageTitles, new Comparator<String>() { public int compare(String o1, String o2) { if(o1.length() > o2.length()) return -1; else if(o2.length() > o1.length()) return 1; else return 0; } }); String body = page.getBodyAsString(); String original = body; Pattern pattern = Pattern.compile("(<a\\s(.*?)</a>)|(<.+?>)"); try { startingBody = body; body = parseExact(body, pageTitles, pattern); afterExact = body; body = parseClose(body, pageTitles, pattern); afterClose = body; page.setBodyAsString(body); if (body.equals(original) == false) { log.info("INFO: Automatic Linker added links to Page:" + currentTitle + " successfully."); } } catch (Exception ex) { log.warn("WARN: Exception occureed in Automatic Linker on Page: " + currentTitle + "\r\nException: " + ex.toString() + "\r\nstartingBody: " + startingBody + "\r\nafterExact: " + afterExact + "\r\n afterClose: " + afterClose); } }
As you can see, the process is run every time a page is created, updated, or simply viewed. Now finally, to the question. This process does indeed work on PageViewEvents, but it requires the user to refresh before seeing the effect. I was wondering if there was some way I could automatically refresh the page for the user after the process is complete. Any ideas?
Thanks for the help.
Community moderators have prevented the ability to post new answers.
You can use servlets to send redirect. You can use this refresh method to do that.
public void refresh() { HttpServletRequest request = ServletActionContext.getRequest(); String requestUrl = request.getRequestURI(); String queryString = request.getQueryString(); if (queryString != null) requestUrl = requestUrl + "?" + queryString; try { ServletActionContext.getResponse().sendRedirect(requestUrl); } catch (IOException e) { log.error("Unable to redirect"); //log.error(ExceptionUtils.getFullStackTrace(e)); } }
But beware, use this refresh only when processEvent is successful. Otherwise it will go in the loop where it will refresh the page that has been refreshed and so on.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.