1 11 package org.eclipse.jdt.internal.ui.text.javadoc; 12 13 14 import java.util.ArrayList ; 15 import java.util.Collections ; 16 import java.util.List ; 17 18 import org.eclipse.core.runtime.IProgressMonitor; 19 20 import org.eclipse.core.resources.IFile; 21 22 import org.eclipse.swt.graphics.Image; 23 24 import org.eclipse.jface.text.BadLocationException; 25 import org.eclipse.jface.text.IDocument; 26 import org.eclipse.jface.text.IRegion; 27 28 import org.eclipse.ui.IEditorInput; 29 import org.eclipse.ui.part.FileEditorInput; 30 31 import org.eclipse.jdt.core.ICompilationUnit; 32 import org.eclipse.jdt.core.JavaModelException; 33 34 import org.eclipse.jdt.ui.JavaUI; 35 import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; 36 import org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer; 37 import org.eclipse.jdt.ui.text.java.IJavadocCompletionProcessor; 38 39 import org.eclipse.jdt.internal.ui.JavaPluginImages; 40 import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposal; 41 42 45 public class HTMLTagCompletionProposalComputer implements IJavaCompletionProposalComputer { 46 47 private static final String [] fgHTMLProposals= new String [IHtmlTagConstants.HTML_GENERAL_TAGS.length * 2]; 48 { 49 String tag= null; 50 51 int index= 0; 52 int offset= 0; 53 54 while (index < fgHTMLProposals.length) { 55 56 tag= IHtmlTagConstants.HTML_GENERAL_TAGS[offset]; 57 fgHTMLProposals[index++]= IHtmlTagConstants.HTML_TAG_PREFIX + tag + IHtmlTagConstants.HTML_TAG_POSTFIX; 58 fgHTMLProposals[index++]= IHtmlTagConstants.HTML_CLOSE_PREFIX + tag + IHtmlTagConstants.HTML_TAG_POSTFIX; 59 offset++; 60 } 61 } 62 63 private IDocument fDocument; 64 private int fCurrentPos; 65 private int fCurrentLength; 66 private String fErrorMessage; 67 private List fResult; 68 69 private boolean fRestrictToMatchingCase; 70 71 public HTMLTagCompletionProposalComputer() { 72 } 73 74 private static boolean isWordPart(char ch) { 75 return Character.isJavaIdentifierPart(ch) || (ch == '#') || (ch == '.') || (ch == '/'); 76 } 77 78 private static int findCharBeforeWord(IDocument doc, int lineBeginPos, int pos) { 79 int currPos= pos - 1; 80 if (currPos > lineBeginPos) { 81 try { 82 while (currPos > lineBeginPos && isWordPart(doc.getChar(currPos))) { 83 currPos--; 84 } 85 return currPos; 86 } catch (BadLocationException e) { 87 } 89 } 90 return pos; 91 } 92 93 private static int findClosingCharacter(IDocument doc, int pos, int end, char endChar) throws BadLocationException { 94 int curr= pos; 95 while (curr < end && (doc.getChar(curr) != endChar)) { 96 curr++; 97 } 98 if (curr < end) { 99 return curr + 1; 100 } 101 return pos; 102 } 103 104 private static int findReplaceEndPos(IDocument doc, String newText, String oldText, int pos) { 105 if (oldText.length() == 0 || oldText.equals(newText)) { 106 return pos; 107 } 108 109 try { 110 IRegion lineInfo= doc.getLineInformationOfOffset(pos); 111 int end= lineInfo.getOffset() + lineInfo.getLength(); 112 113 return findClosingCharacter(doc, pos, end, '>'); 115 } catch (BadLocationException e) { 116 } 118 return pos; 119 } 120 121 125 public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) { 126 if (!(context instanceof JavadocContentAssistInvocationContext)) 127 return Collections.EMPTY_LIST; 128 129 JavadocContentAssistInvocationContext docContext= (JavadocContentAssistInvocationContext) context; 130 int flags= docContext.getFlags(); 131 fCurrentPos= docContext.getInvocationOffset(); 132 fCurrentLength= docContext.getSelectionLength(); 133 fRestrictToMatchingCase= (flags & IJavadocCompletionProcessor.RESTRICT_TO_MATCHING_CASE) != 0; 134 135 ICompilationUnit cu= docContext.getCompilationUnit(); 136 if (cu == null) 137 return Collections.EMPTY_LIST; 138 IEditorInput editorInput= new FileEditorInput((IFile) cu.getResource()); 139 fDocument= JavaUI.getDocumentProvider().getDocument(editorInput); 140 if (fDocument == null) { 141 return null; 142 } 143 144 try { 145 fResult= new ArrayList (100); 146 evalProposals(); 147 return fResult; 148 } catch (JavaModelException e) { 149 fErrorMessage= e.getLocalizedMessage(); 150 } finally { 151 fResult= null; 152 } 153 return null; 154 } 155 156 private void evalProposals() throws JavaModelException { 157 try { 158 159 IRegion info= fDocument.getLineInformationOfOffset(fCurrentPos); 160 int lineBeginPos= info.getOffset(); 161 162 int word1Begin= findCharBeforeWord(fDocument, lineBeginPos, fCurrentPos); 163 if (word1Begin == fCurrentPos) 164 return; 165 166 char firstChar= fDocument.getChar(word1Begin); 167 if (firstChar == '<') { 168 String prefix= fDocument.get(word1Begin, fCurrentPos - word1Begin); 169 addProposals(prefix, fgHTMLProposals, JavaPluginImages.IMG_OBJS_HTMLTAG); 170 return; 171 } else if (!Character.isWhitespace(firstChar)) { 172 return; 173 } 174 175 String prefix= fDocument.get(word1Begin + 1, fCurrentPos - word1Begin - 1); 178 addAllTags(prefix); 179 } catch (BadLocationException e) { 180 } 182 } 183 184 private boolean prefixMatches(String prefix, String proposal) { 185 if (fRestrictToMatchingCase) { 186 return proposal.startsWith(prefix); 187 } else if (proposal.length() >= prefix.length()) { 188 return prefix.equalsIgnoreCase(proposal.substring(0, prefix.length())); 189 } 190 return false; 191 } 192 193 private void addAllTags(String prefix) { 194 String htmlPrefix= "<" + prefix; for (int i= 0; i < fgHTMLProposals.length; i++) { 196 String curr= fgHTMLProposals[i]; 197 if (prefixMatches(htmlPrefix, curr)) { 198 fResult.add(createCompletion(curr, prefix, curr, JavaPluginImages.get(JavaPluginImages.IMG_OBJS_HTMLTAG), 0)); 199 } 200 } 201 } 202 203 private void addProposals(String prefix, String [] choices, String imageName) { 204 for (int i= 0; i < choices.length; i++) { 205 String curr= choices[i]; 206 if (prefixMatches(prefix, curr)) { 207 fResult.add(createCompletion(curr, prefix, curr, JavaPluginImages.get(imageName), 0)); 208 } 209 } 210 } 211 212 private JavaCompletionProposal createCompletion(String newText, String oldText, String labelText, Image image, int severity) { 213 int offset= fCurrentPos - oldText.length(); 214 int length= fCurrentLength + oldText.length(); 215 if (fCurrentLength == 0) 216 length= findReplaceEndPos(fDocument, newText, oldText, fCurrentPos) - offset; 217 218 if (!newText.startsWith(IHtmlTagConstants.HTML_CLOSE_PREFIX)) 220 severity++; 221 JavaCompletionProposal proposal= new JavaCompletionProposal(newText, offset, length, image, labelText, severity, true); 222 proposal.setTriggerCharacters( new char[] { '>' }); 223 return proposal; 224 } 225 226 230 public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { 231 return Collections.EMPTY_LIST; 232 } 233 234 238 public String getErrorMessage() { 239 return fErrorMessage; 240 } 241 242 246 public void sessionEnded() { 247 fErrorMessage= null; 248 } 249 250 254 public void sessionStarted() { 255 fErrorMessage= null; 256 } 257 } 258 | Popular Tags |