KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > editor > plugin > BundleHyperlinkDetector


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.pde.internal.ui.editor.plugin;
12
13 import org.eclipse.jface.text.BadLocationException;
14 import org.eclipse.jface.text.IDocument;
15 import org.eclipse.jface.text.IRegion;
16 import org.eclipse.jface.text.ITextViewer;
17 import org.eclipse.jface.text.Region;
18 import org.eclipse.jface.text.hyperlink.IHyperlink;
19 import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
20 import org.eclipse.pde.internal.core.ICoreConstants;
21 import org.eclipse.pde.internal.core.text.IDocumentRange;
22 import org.eclipse.pde.internal.core.text.IEditingModel;
23 import org.eclipse.pde.internal.core.text.bundle.BasePackageHeader;
24 import org.eclipse.pde.internal.core.text.bundle.BundleActivatorHeader;
25 import org.eclipse.pde.internal.core.text.bundle.ManifestHeader;
26 import org.eclipse.pde.internal.core.text.bundle.RequireBundleHeader;
27 import org.eclipse.pde.internal.ui.editor.PDESourcePage;
28 import org.eclipse.pde.internal.ui.editor.text.BundleHyperlink;
29 import org.eclipse.pde.internal.ui.editor.text.JavaHyperlink;
30 import org.eclipse.pde.internal.ui.editor.text.PackageHyperlink;
31 import org.eclipse.pde.internal.ui.editor.text.TranslationHyperlink;
32
33 public class BundleHyperlinkDetector implements IHyperlinkDetector {
34
35     private PDESourcePage fSourcePage;
36     
37     /**
38      * @param editor the editor in which to detect the hyperlink
39      */

40     public BundleHyperlinkDetector(PDESourcePage page) {
41         fSourcePage = page;
42     }
43
44     /*
45      * @see org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion, boolean)
46      */

47     public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
48         if (region == null || canShowMultipleHyperlinks)
49             return null;
50
51         IDocumentRange element = fSourcePage.getRangeElement(region.getOffset(), false);
52         if (!(element instanceof ManifestHeader))
53             return null;
54         
55         ManifestHeader header = (ManifestHeader)element;
56         if (!header.getModel().isEditable())
57             return null;
58         
59         String JavaDoc headerName = header.getName();
60         if (region.getOffset() <= header.getOffset() + headerName.length())
61             return null;
62         
63         String JavaDoc[] translatable = ICoreConstants.TRANSLATABLE_HEADERS;
64         for (int i = 0; i < translatable.length; i++) {
65             if (!headerName.equals(translatable[i]))
66                 continue;
67             String JavaDoc value = header.getValue();
68             if (value == null || value.length() == 0 || value.charAt(0) != '%')
69                 break;
70             
71             IDocumentRange range = BundleSourcePage.getSpecificRange(header.getModel(), header, value);
72             return new IHyperlink[] {
73                     new TranslationHyperlink(
74                             new Region(range.getOffset(), range.getLength()),
75                             value,
76                             header.getModel())};
77         }
78         
79         if (header instanceof BundleActivatorHeader) { // add else if statments for other headers
80
String JavaDoc target = ((BundleActivatorHeader)element).getClassName();
81             if (target == null || target.length() == 0)
82                 return null;
83             IDocumentRange range = BundleSourcePage.getSpecificRange(header.getModel(), header, target);
84             if (range == null)
85                 return null;
86             return new IHyperlink[] {
87                     new JavaHyperlink(
88                             new Region(range.getOffset(), range.getLength()),
89                             target,
90                             header.getModel().getUnderlyingResource())};
91         } else if (header instanceof BasePackageHeader || header instanceof RequireBundleHeader) {
92             return matchLinkFor(header, region.getOffset());
93         }
94         return null;
95     }
96
97     private IHyperlink[] matchLinkFor(ManifestHeader header, int mainOffset) {
98         IDocument doc = ((IEditingModel)header.getModel()).getDocument();
99         String JavaDoc value;
100         try {
101             value = doc.get(header.getOffset(), header.getLength());
102             int offset = mainOffset - header.getOffset();
103             // Our offset falls outside the value range
104
if (offset >= value.length()) {
105                 return null;
106             }
107             
108             // ensure we are over a letter or period
109
char c = value.charAt(offset);
110             if (!elementChar(c, true))
111                 return null;
112             
113             // scan backwards to find the start of the word
114
int downOffset = offset;
115             c = value.charAt(--downOffset);
116             while (c != ',' && c != ':' && downOffset > 0) {
117                 // c == ';' means we are at a directive / attribute name (NOT value)
118
if (c == ';' || !elementChar(c, false))
119                     return null;
120                 downOffset -= 1;
121                 c = value.charAt(downOffset);
122             }
123             // backtrack forwards to remove whitespace etc.
124
while (downOffset < offset && !elementChar(c, true))
125                 c = value.charAt(++downOffset);
126             
127             // scan forwards to find the end of the word
128
int upOffset = offset;
129             c = value.charAt(upOffset);
130             int length = value.length();
131             while (c != ';' && c != ',' && upOffset < length - 1) {
132                 if (!elementChar(c, false))
133                     return null;
134                 upOffset += 1;
135                 c = value.charAt(upOffset);
136             }
137             // backtrack to remove extra chars
138
if (c == ';' || c == ',')
139                 upOffset -= 1;
140             
141             String JavaDoc match = value.substring(downOffset, upOffset + 1);
142             if (match.length() > 0) {
143                 IRegion region = new Region(mainOffset - (offset - downOffset), match.length());
144                 if (header instanceof BasePackageHeader)
145                     return new IHyperlink[] { new PackageHyperlink(region, match, (BasePackageHeader)header)};
146                 if (header instanceof RequireBundleHeader)
147                     return new IHyperlink[] { new BundleHyperlink(region, match)};
148             }
149         } catch (BadLocationException e) {
150         }
151         return null;
152     }
153     
154     private boolean elementChar(char c, boolean noWhitespace) {
155         if (noWhitespace && Character.isWhitespace(c))
156             return false;
157         return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '.' || Character.isWhitespace(c);
158     }
159     
160 }
161
Popular Tags