/******************************************************************************* * Copyright (C) 2011 Robert Munteanu <robert.munteanu@gmail.com> * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package com.itsolut.mantis.ui.internal; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.mylyn.tasks.ui.TaskHyperlink; import com.google.inject.Inject; import com.itsolut.mantis.core.MantisCommentMapper; import com.itsolut.mantis.core.MantisCommentMapper.CommentMapping; /** * The <tt>MantisHyperlinkFinder</tt> detects links to tasks and task comments in text * * @author Robert Munteanu * */ public class MantisHyperlinkFinder { private static final Pattern HYPERLINK_PATTERN = Pattern.compile("(bug|issue|task) #?(\\d+)", Pattern.CASE_INSENSITIVE); private static final Pattern COMMENT_PATTERN = Pattern.compile("~(\\d+)", Pattern.CASE_INSENSITIVE); private MantisCommentMapper commentMapper; @Inject public MantisHyperlinkFinder(MantisCommentMapper commentMapper) { this.commentMapper = commentMapper; } public IHyperlink[] findHyperlinks(TaskRepository repository, ITask task, String text, int lineOffset, int regionOffset) { Matcher matcher = HYPERLINK_PATTERN.matcher(text); List<IHyperlink> links = null; while (matcher.find()) { if (!isInRegion(lineOffset, matcher)) continue; if (links == null) links = new ArrayList<IHyperlink>(1); String id = matcher.group(2); links.add(new TaskHyperlink(determineRegion(regionOffset, matcher), repository, id)); } matcher = COMMENT_PATTERN.matcher(text); while ( matcher.find() ) { if (!isInRegion(lineOffset, matcher)) continue; String commentId = matcher.group(1); CommentMapping commentMapping = commentMapper.getCommentMapping(Integer.parseInt(commentId)); if ( commentMapping == null ) continue; if (links == null) links = new ArrayList<IHyperlink>(1); TaskHyperlink link = new TaskHyperlink(determineRegion(regionOffset, matcher), repository, String.valueOf(commentMapping.getTaskId())); link.setSelection(TaskAttribute.PREFIX_COMMENT + commentMapping.getCommentNumber()); links.add(link); } return links == null ? null : links.toArray(new IHyperlink[links.size()]); } private boolean isInRegion(int lineOffset, Matcher m) { if ( lineOffset == -1 ) return true; return (lineOffset >= m.start() && lineOffset <= m.end()); } private IRegion determineRegion(int regionOffset, Matcher m) { return new Region(regionOffset + m.start(), m.end() - m.start()); } }