KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > javadoc > HTMLTagCompletionProposalComputer


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.jdt.internal.ui.text.javadoc;
12
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Collections JavaDoc;
16 import java.util.List JavaDoc;
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 /**
43  * @since 3.2 (renamed from JavaDocCompletionEvaluator which got introduced in 2.0)
44  */

45 public class HTMLTagCompletionProposalComputer implements IJavaCompletionProposalComputer {
46
47     private static final String JavaDoc[] fgHTMLProposals= new String JavaDoc[IHtmlTagConstants.HTML_GENERAL_TAGS.length * 2];
48     {
49         String JavaDoc 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 JavaDoc fErrorMessage;
67     private List JavaDoc 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                 // ignore
88
}
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 JavaDoc newText, String JavaDoc 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             // for html, search the tag end character
114
return findClosingCharacter(doc, pos, end, '>');
115         } catch (BadLocationException e) {
116             // ignore
117
}
118         return pos;
119     }
120     
121     /*
122      * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer#computeCompletionProposals(org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
123      * @since 3.2
124      */

125     public List JavaDoc 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 JavaDoc(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 JavaDoc 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             // TODO really show all tags when there is no prefix?
176
// TODO find any unclosed open tag and offer the corresponding close tag
177
String JavaDoc prefix= fDocument.get(word1Begin + 1, fCurrentPos - word1Begin - 1);
178             addAllTags(prefix);
179         } catch (BadLocationException e) {
180             // ignore
181
}
182     }
183
184     private boolean prefixMatches(String JavaDoc prefix, String JavaDoc 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 JavaDoc prefix) {
194         String JavaDoc htmlPrefix= "<" + prefix; //$NON-NLS-1$
195
for (int i= 0; i < fgHTMLProposals.length; i++) {
196             String JavaDoc 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 JavaDoc prefix, String JavaDoc[] choices, String JavaDoc imageName) {
204         for (int i= 0; i < choices.length; i++) {
205             String JavaDoc 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 JavaDoc newText, String JavaDoc oldText, String JavaDoc 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         // bump opening over closing tags
219
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     /*
227      * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer#computeContextInformation(org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
228      * @since 3.2
229      */

230     public List JavaDoc computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) {
231         return Collections.EMPTY_LIST;
232     }
233
234     /*
235      * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer#getErrorMessage()
236      * @since 3.2
237      */

238     public String JavaDoc getErrorMessage() {
239         return fErrorMessage;
240     }
241
242     /*
243      * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer#sessionEnded()
244      * @since 3.2
245      */

246     public void sessionEnded() {
247         fErrorMessage= null;
248     }
249
250     /*
251      * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer#sessionStarted()
252      * @since 3.2
253      */

254     public void sessionStarted() {
255         fErrorMessage= null;
256     }
257 }
258
Popular Tags