KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > html > HTMLCompletionProvider


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.editor.html;
21
22 import java.util.List JavaDoc;
23 import javax.swing.text.Document JavaDoc;
24 import javax.swing.text.JTextComponent JavaDoc;
25 import org.netbeans.api.editor.completion.Completion;
26 import org.netbeans.api.html.lexer.HTMLTokenId;
27 import org.netbeans.api.lexer.Token;
28 import org.netbeans.api.lexer.TokenHierarchy;
29 import org.netbeans.api.lexer.TokenSequence;
30 import org.netbeans.editor.BaseDocument;
31 import org.netbeans.editor.Utilities;
32 import org.netbeans.editor.ext.CompletionQuery;
33 import org.netbeans.editor.ext.CompletionQuery.ResultItem;
34 import org.netbeans.editor.ext.ExtSyntaxSupport;
35 import org.netbeans.editor.ext.html.HTMLCompletionQuery;
36 import org.netbeans.editor.ext.html.HTMLCompletionQuery.HTMLResultItem;
37 import org.netbeans.editor.ext.html.HTMLSyntaxSupport;
38 import org.netbeans.spi.editor.completion.CompletionResultSet;
39 import org.netbeans.spi.editor.completion.CompletionProvider;
40 import org.netbeans.spi.editor.completion.CompletionTask;
41 import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery;
42 import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
43
44
45 /**
46  * Implementation of {@link CompletionProvider} for HTML documents.
47  *
48  * @author Marek Fukala
49  */

50 public class HTMLCompletionProvider implements CompletionProvider {
51     
52     /** Creates a new instance of JavaDocCompletionProvider */
53     public HTMLCompletionProvider() {
54     }
55     
56     public int getAutoQueryTypes(JTextComponent JavaDoc component, String JavaDoc typedText) {
57         int type = ((HTMLSyntaxSupport)Utilities.getDocument(component).getSyntaxSupport()).checkCompletion(component, typedText, false);
58         return type == ExtSyntaxSupport.COMPLETION_POPUP ? COMPLETION_QUERY_TYPE + DOCUMENTATION_QUERY_TYPE : 0;
59     }
60     
61     public CompletionTask createTask(int queryType, JTextComponent JavaDoc component) {
62         AsyncCompletionTask task = null;
63         if ((queryType & COMPLETION_QUERY_TYPE & COMPLETION_ALL_QUERY_TYPE) != 0) {
64             task = new AsyncCompletionTask(new Query(), component);
65         } else if (queryType == DOCUMENTATION_QUERY_TYPE) {
66             task = new AsyncCompletionTask(new DocQuery(null), component);
67         }
68         return task;
69     }
70     
71     static class Query extends AbstractQuery {
72         
73         private JTextComponent JavaDoc component;
74         
75         protected void prepareQuery(JTextComponent JavaDoc component) {
76             this.component = component;
77         }
78         
79         protected void doQuery(CompletionResultSet resultSet, Document JavaDoc doc, int caretOffset) {
80             HTMLCompletionQuery.HTMLCompletionResult res = (HTMLCompletionQuery.HTMLCompletionResult)queryImpl(component, caretOffset);
81             if(res == null) {
82                 return ;
83             }
84             
85             List JavaDoc/*<CompletionItem>*/ results = res.getData();
86             assert (results != null);
87             resultSet.addAllItems(results);
88             resultSet.setTitle(res.getTitle());
89             resultSet.setAnchorOffset(res.getSubstituteOffset());
90         }
91     }
92     
93     static class DocQuery extends AbstractQuery {
94         
95         private JTextComponent JavaDoc component;
96         private ResultItem item;
97         
98         DocQuery(HTMLResultItem item) {
99             this.item = item;
100         }
101         
102         protected void prepareQuery(JTextComponent JavaDoc component) {
103             this.component = component;
104         }
105         
106         protected void doQuery(CompletionResultSet resultSet, Document JavaDoc doc, int caretOffset) {
107             CompletionQuery.Result res = null;
108             if(item == null) {
109                 res = queryImpl(component, caretOffset);
110                 if(res != null) {
111                     List JavaDoc result = res.getData();
112                     if(result != null && result.size() > 0) {
113                         Object JavaDoc resultObj = result.get(0);
114                         if(resultObj instanceof ResultItem)
115                             item = (ResultItem)resultObj;
116                     }
117                 }
118             }
119             HTMLResultItem htmlItem = (HTMLResultItem)item;
120             if(htmlItem != null && htmlItem.getHelpID() != null) {
121                 resultSet.setDocumentation(new HTMLCompletionQuery.DocItem(htmlItem));
122                 if(res != null) {
123                     resultSet.setTitle(res.getTitle());
124                     resultSet.setAnchorOffset(((HTMLCompletionQuery.HTMLCompletionResult)res).getSubstituteOffset());
125                 }
126             }
127         }
128     }
129     
130     private static CompletionQuery.Result queryImpl(JTextComponent JavaDoc component, int offset) {
131         Class JavaDoc kitClass = Utilities.getKitClass(component);
132         if (kitClass != null) {
133             HTMLSyntaxSupport support = (HTMLSyntaxSupport)Utilities.getSyntaxSupport(component);
134             return HTMLCompletionQuery.getDefault().query(component, offset, support);
135         } else {
136             return null;
137         }
138     }
139     
140     private static abstract class AbstractQuery extends AsyncCompletionQuery {
141         
142         protected void preQueryUpdate(JTextComponent JavaDoc component) {
143             int caretOffset = component.getCaretPosition();
144             Document JavaDoc doc = component.getDocument();
145             checkHideCompletion((BaseDocument)doc, caretOffset);
146         }
147         
148         protected void query(CompletionResultSet resultSet, Document JavaDoc doc, int caretOffset) {
149             checkHideCompletion((BaseDocument)doc, caretOffset);
150             doQuery(resultSet, doc, caretOffset);
151             resultSet.finish();
152         }
153         
154         abstract void doQuery(CompletionResultSet resultSet, Document JavaDoc doc, int caretOffset);
155         
156     }
157     
158     private static void checkHideCompletion(BaseDocument doc, int caretOffset) {
159         //test whether we are just in text and eventually close the opened completion
160
//this is handy after end tag autocompletion when user doesn't complete the
161
//end tag and just types a text
162
//test whether the user typed an ending quotation in the attribute value
163
doc.readLock();
164         try {
165             TokenHierarchy tokenHierarchy = TokenHierarchy.get(doc);
166             TokenSequence tokenSequence = tokenHierarchy.tokenSequence();
167             
168             tokenSequence.move(caretOffset == 0 ? 0 : caretOffset - 1);
169             if (!tokenSequence.moveNext())
170                 return;
171             
172             Token tokenItem = tokenSequence.token();
173             if(tokenItem.id() == HTMLTokenId.TEXT && !tokenItem.text().toString().startsWith("<") && !tokenItem.text().toString().startsWith("&")) {
174                 hideCompletion();
175             }
176             
177         }finally {
178             doc.readUnlock();
179         }
180     }
181     
182     private static void hideCompletion() {
183         Completion.get().hideCompletion();
184         Completion.get().hideDocumentation();
185     }
186 }
187
Popular Tags