### Eclipse Workspace Patch 1.0 #P org.eclipse.mylyn.tasks.tests Index: src/org/eclipse/mylyn/tasks/tests/ui/editor/TaskUrlHyperlinkDetectorTest.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/ui/editor/TaskUrlHyperlinkDetectorTest.java,v retrieving revision 1.5 diff -u -r1.5 TaskUrlHyperlinkDetectorTest.java --- src/org/eclipse/mylyn/tasks/tests/ui/editor/TaskUrlHyperlinkDetectorTest.java 8 Feb 2010 00:38:50 -0000 1.5 +++ src/org/eclipse/mylyn/tasks/tests/ui/editor/TaskUrlHyperlinkDetectorTest.java 22 Feb 2010 15:45:55 -0000 @@ -93,6 +93,28 @@ assertEquals("http://foo", ((TaskUrlHyperlink) links[0]).getURLString()); } + public void testClosingParenthesis() { + IHyperlink[] links = detect("http://foo?(bar)", 0, 0); + assertNotNull(links); + assertEquals(1, links.length); + assertEquals("http://foo?(bar)", ((TaskUrlHyperlink) links[0]).getURLString()); + + links = detect("(http://foo?(bar))", 0, 18); + assertNotNull(links); + assertEquals(1, links.length); + assertEquals("http://foo?(bar)", ((TaskUrlHyperlink) links[0]).getURLString()); + + links = detect("http://foo?((((bar).", 0, 0); + assertNotNull(links); + assertEquals(1, links.length); + assertEquals("http://foo?((((bar)", ((TaskUrlHyperlink) links[0]).getURLString()); + + links = detect("http://foo?(bar))))))))", 0, 0); + assertNotNull(links); + assertEquals(1, links.length); + assertEquals("http://foo?(bar)", ((TaskUrlHyperlink) links[0]).getURLString()); + } + public void testDetectionUsingExtent() { IHyperlink[] hyperlinks = detect("aa http://www.eclipse.org test", 0, 30); assertNotNull(hyperlinks); @@ -118,6 +140,16 @@ assertEquals(new Region(51, 22), hyperlinks[2].getHyperlinkRegion()); } + public void testDetectionMultiplelinesClosingParenthesis() { + String text = "aa http://www.eclipse.org?foo((bar)\n\n)(http://www.eclipse.org)\nhttp://www.eclipse.org()"; + IHyperlink[] hyperlinks = detect(text, 0, text.length()); + assertNotNull(hyperlinks); + assertEquals(3, hyperlinks.length); + assertEquals(new Region(3, 32), hyperlinks[0].getHyperlinkRegion()); + assertEquals(new Region(39, 22), hyperlinks[1].getHyperlinkRegion()); + assertEquals(new Region(63, 24), hyperlinks[2].getHyperlinkRegion()); + } + public void testDetectionMultiplelines() { String text = "aa http://www.eclipse.org\n\nhttp://www.eclipse.org.\nhttp://www.eclipse.org,"; IHyperlink[] hyperlinks = detect(text, 0, text.length()); #P org.eclipse.mylyn.tasks.ui Index: src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskUrlHyperlinkDetector.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskUrlHyperlinkDetector.java,v retrieving revision 1.12 diff -u -r1.12 TaskUrlHyperlinkDetector.java --- src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskUrlHyperlinkDetector.java 8 Feb 2010 00:38:49 -0000 1.12 +++ src/org/eclipse/mylyn/internal/tasks/ui/editors/TaskUrlHyperlinkDetector.java 22 Feb 2010 15:45:57 -0000 @@ -8,6 +8,7 @@ * Contributors: * Tasktop Technologies - initial API and implementation * David Green - fix for bug 266693 + * Abner Ballardo - fix for bug 288427 *******************************************************************************/ package org.eclipse.mylyn.internal.tasks.ui.editors; @@ -19,7 +20,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.hyperlink.IHyperlink; @@ -39,6 +39,12 @@ // so we do the same here private static final Pattern URL_PATTERN = Pattern.compile("([a-zA-Z][a-zA-Z+.-]{0,10}://[a-zA-Z0-9%._~!$&?#'()*+,;:@/=-]*[a-zA-Z0-9%_~!$&?#'(*+;:@/=-])"); //$NON-NLS-1$ + private static final String CLOSED_PARENTHESIS_PATTERN = "[^)]"; //$NON-NLS-1$ + + private static final String OPEN_PARENTHESIS_PATTERN = "[^(]"; //$NON-NLS-1$ + + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + public TaskUrlHyperlinkDetector() { } @@ -49,19 +55,19 @@ Matcher m = URL_PATTERN.matcher(content); while (m.find()) { if (isInRegion(indexInContent, m)) { - String urlString = m.group(1); + String urlString = getUrlString(content, m); TaskUrlHyperlink link = null; if (getAdapter(TaskRepository.class) != null) { try { new URL(urlString); - link = new TaskUrlHyperlink(determineRegion(contentOffset, m), urlString); + link = createTaskUrlHyperlink(contentOffset, m, urlString); } catch (MalformedURLException e) { // ignore } } else { if (TasksUiInternal.isTaskUrl(urlString)) { - link = new TaskUrlHyperlink(determineRegion(contentOffset, m), urlString); + link = createTaskUrlHyperlink(contentOffset, m, urlString); } } @@ -76,12 +82,28 @@ return links; } + private String getUrlString(String content, Matcher m) { + String urlString = m.group(1); + int parenthesisDiff = urlString.replaceAll(OPEN_PARENTHESIS_PATTERN, EMPTY_STRING).length() + - urlString.replaceAll(CLOSED_PARENTHESIS_PATTERN, EMPTY_STRING).length(); + + if (parenthesisDiff > 0) { + for (int i = m.end(); i - m.end() < parenthesisDiff; i++) { + if (i >= content.length() || content.charAt(i) != ')') { + break; + } + urlString += ')'; + } + } + return urlString; + } + private static boolean isInRegion(int offsetInText, Matcher m) { return (offsetInText == -1) || (offsetInText >= m.start() && offsetInText <= m.end()); } - private static IRegion determineRegion(int textOffset, Matcher m) { - return new Region(textOffset + m.start(), m.end() - m.start()); + private static TaskUrlHyperlink createTaskUrlHyperlink(int textOffset, Matcher m, String urlString) { + return new TaskUrlHyperlink(new Region(textOffset + m.start(), urlString.length()), urlString); } }