001: /*******************************************************************************
002: * Copyright (c) 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor.build;
011:
012: import org.eclipse.core.resources.IResource;
013: import org.eclipse.jface.text.BadLocationException;
014: import org.eclipse.jface.text.IDocument;
015: import org.eclipse.jface.text.IRegion;
016: import org.eclipse.jface.text.ITextViewer;
017: import org.eclipse.jface.text.Region;
018: import org.eclipse.jface.text.hyperlink.IHyperlink;
019: import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
020: import org.eclipse.pde.core.build.IBuildEntry;
021: import org.eclipse.pde.internal.core.text.IDocumentRange;
022: import org.eclipse.pde.internal.core.text.IEditingModel;
023: import org.eclipse.pde.internal.core.text.build.BuildEntry;
024: import org.eclipse.pde.internal.ui.editor.PDESourcePage;
025: import org.eclipse.pde.internal.ui.editor.text.ResourceHyperlink;
026:
027: public class BuildHyperlinkDetector implements IHyperlinkDetector {
028:
029: private PDESourcePage fSourcePage;
030:
031: /**
032: * @param editor the editor in which to detect the hyperlink
033: */
034: public BuildHyperlinkDetector(PDESourcePage page) {
035: fSourcePage = page;
036: }
037:
038: /*
039: * @see org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion, boolean)
040: */
041: public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
042: IRegion region, boolean canShowMultipleHyperlinks) {
043: if (region == null || canShowMultipleHyperlinks)
044: return null;
045:
046: IDocumentRange element = fSourcePage.getRangeElement(region
047: .getOffset(), true);
048: if (!(element instanceof BuildEntry))
049: return null;
050:
051: BuildEntry entry = (BuildEntry) element;
052: if (!entry.getModel().isEditable()
053: || !(entry.getModel() instanceof IEditingModel))
054: return null;
055:
056: String name = entry.getName();
057: // as of now only scanning bin.includes, src.includes and source.* entries
058: if (!name.equals(IBuildEntry.BIN_INCLUDES)
059: && !name.equals(IBuildEntry.SRC_INCLUDES)
060: && !name.startsWith(IBuildEntry.JAR_PREFIX))
061: return null;
062:
063: if (region.getOffset() <= entry.getOffset()
064: + entry.getName().length())
065: return null;
066:
067: return matchLinkFor(entry, region.getOffset());
068: }
069:
070: private IHyperlink[] matchLinkFor(BuildEntry header, int mainOffset) {
071: try {
072: IDocument doc = ((IEditingModel) header.getModel())
073: .getDocument();
074: String value = doc.get(header.getOffset(), header
075: .getLength());
076: int offset = mainOffset - header.getOffset();
077: if (skipChar(value.charAt(offset)))
078: return null;
079:
080: // all chars up to the offset
081: String pre = value.substring(0, offset);
082: char[] preChars = pre.toCharArray();
083: int start = pre.lastIndexOf(',');
084: if (start == -1)
085: // we are looking at 1st entry, skip to ':'
086: if ((start = value.indexOf('=')) == 0)
087: return null;
088:
089: // skip to 1st non whitespace char
090: while (++start < preChars.length)
091: if (!skipChar(preChars[start]))
092: break;
093:
094: // all chars past to ofset
095: String post = value.substring(offset);
096: char[] postChars = post.toCharArray();
097: int end = post.indexOf(',');
098: if (end == -1)
099: // we are looking at last entry, skip to end
100: end = post.length();
101:
102: // move back to 1st non whitespace char
103: while (--end < postChars.length)
104: if (!skipChar(postChars[end]))
105: break;
106: end += 1;
107:
108: String match = value
109: .substring(start, preChars.length + end);
110: if (match.length() == 0 || match.indexOf('*') != -1)
111: return null;
112:
113: IResource res = header.getModel().getUnderlyingResource();
114: if (res == null)
115: return null;
116: res = res.getProject().findMember(match);
117: return new IHyperlink[] { new ResourceHyperlink(new Region(
118: header.getOffset() + start, match.length()), match,
119: res) };
120:
121: } catch (BadLocationException e) {
122: }
123: return null;
124: }
125:
126: private boolean skipChar(char c) {
127: return Character.isWhitespace(c) || c == '\\' || c == ',';
128: }
129:
130: }
|