1 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 40 public BundleHyperlinkDetector(PDESourcePage page) { 41 fSourcePage = page; 42 } 43 44 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 headerName = header.getName(); 60 if (region.getOffset() <= header.getOffset() + headerName.length()) 61 return null; 62 63 String [] translatable = ICoreConstants.TRANSLATABLE_HEADERS; 64 for (int i = 0; i < translatable.length; i++) { 65 if (!headerName.equals(translatable[i])) 66 continue; 67 String 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) { String 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 value; 100 try { 101 value = doc.get(header.getOffset(), header.getLength()); 102 int offset = mainOffset - header.getOffset(); 103 if (offset >= value.length()) { 105 return null; 106 } 107 108 char c = value.charAt(offset); 110 if (!elementChar(c, true)) 111 return null; 112 113 int downOffset = offset; 115 c = value.charAt(--downOffset); 116 while (c != ',' && c != ':' && downOffset > 0) { 117 if (c == ';' || !elementChar(c, false)) 119 return null; 120 downOffset -= 1; 121 c = value.charAt(downOffset); 122 } 123 while (downOffset < offset && !elementChar(c, true)) 125 c = value.charAt(++downOffset); 126 127 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 if (c == ';' || c == ',') 139 upOffset -= 1; 140 141 String 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 |