KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > editor > codetemplates > CodeTemplateCompletionProvider


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.lib.editor.codetemplates;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import javax.swing.event.ChangeEvent JavaDoc;
27 import javax.swing.event.ChangeListener JavaDoc;
28 import javax.swing.text.AbstractDocument JavaDoc;
29 import javax.swing.text.BadLocationException JavaDoc;
30 import javax.swing.text.Document JavaDoc;
31 import javax.swing.text.JTextComponent JavaDoc;
32 import org.netbeans.editor.BaseDocument;
33 import org.netbeans.editor.SettingsUtil;
34 import org.netbeans.editor.Utilities;
35 import org.netbeans.editor.ext.ExtSettingsDefaults;
36 import org.netbeans.editor.ext.ExtSettingsNames;
37 import org.netbeans.lib.editor.codetemplates.api.CodeTemplate;
38 import org.netbeans.lib.editor.codetemplates.spi.CodeTemplateFilter;
39 import org.netbeans.spi.editor.completion.CompletionProvider;
40 import org.netbeans.spi.editor.completion.CompletionResultSet;
41 import org.netbeans.spi.editor.completion.CompletionTask;
42 import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery;
43 import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
44
45 /**
46  * Implemenation of the code template description.
47  *
48  * @author Miloslav Metelka
49  */

50 public final class CodeTemplateCompletionProvider implements CompletionProvider {
51
52     public CompletionTask createTask(int type, JTextComponent JavaDoc component) {
53         return type != COMPLETION_QUERY_TYPE || isAbbrevDisabled(component) ? null : new AsyncCompletionTask(new Query(), component);
54     }
55
56     public int getAutoQueryTypes(JTextComponent JavaDoc component, String JavaDoc typedText) {
57         return 0;
58     }
59
60     private static boolean isAbbrevDisabled(JTextComponent JavaDoc component) {
61         return org.netbeans.editor.Abbrev.isAbbrevDisabled(component);
62     }
63     
64     private static final class Query extends AsyncCompletionQuery
65     implements ChangeListener JavaDoc {
66
67         private JTextComponent JavaDoc component;
68         
69         private int queryCaretOffset;
70         private int queryAnchorOffset;
71         private List JavaDoc queryResult;
72         
73         private String JavaDoc filterPrefix;
74         
75         protected void prepareQuery(JTextComponent JavaDoc component) {
76             this.component = component;
77         }
78         
79         protected boolean canFilter(JTextComponent JavaDoc component) {
80             int caretOffset = component.getSelectionStart();
81             Document JavaDoc doc = component.getDocument();
82             filterPrefix = null;
83             if (caretOffset >= queryCaretOffset) {
84                 if (queryAnchorOffset < queryCaretOffset) {
85                     try {
86                         filterPrefix = doc.getText(queryAnchorOffset, caretOffset - queryAnchorOffset);
87                         if (!isJavaIdentifierPart(filterPrefix)) {
88                             filterPrefix = null;
89                         }
90                     } catch (BadLocationException JavaDoc e) {
91                         // filterPrefix stays null -> no filtering
92
}
93                 }
94             }
95             return (filterPrefix != null);
96         }
97         
98         protected void filter(CompletionResultSet resultSet) {
99             if (filterPrefix != null && queryResult != null) {
100                 resultSet.addAllItems(getFilteredData(queryResult, filterPrefix));
101             }
102             resultSet.finish();
103         }
104         
105         private boolean isJavaIdentifierPart(CharSequence JavaDoc text) {
106             for (int i = 0; i < text.length(); i++) {
107                 if (!(Character.isJavaIdentifierPart(text.charAt(i))) ) {
108                     return false;
109                 }
110             }
111             return true;
112         }
113         
114         private Collection JavaDoc getFilteredData(Collection JavaDoc data, String JavaDoc prefix) {
115             List JavaDoc ret = new ArrayList JavaDoc();
116             for (Iterator JavaDoc it = data.iterator(); it.hasNext();) {
117                 CodeTemplateCompletionItem itm = (CodeTemplateCompletionItem) it.next();
118                 if (itm.getInsertPrefix().toString().startsWith(prefix))
119                     ret.add(itm);
120             }
121             return ret;
122         }
123         
124         protected void query(CompletionResultSet resultSet, Document JavaDoc doc, int caretOffset) {
125             CodeTemplateManagerOperation op = CodeTemplateManagerOperation.get(doc);
126             String JavaDoc identifierBeforeCursor = null;
127             if (doc instanceof AbstractDocument JavaDoc) {
128                 AbstractDocument JavaDoc adoc = (AbstractDocument JavaDoc)doc;
129                 adoc.readLock();
130                 try {
131                     if (adoc instanceof BaseDocument) {
132                         identifierBeforeCursor = Utilities.getIdentifierBefore(
133                                 (BaseDocument)adoc, caretOffset);
134                     }
135                 } catch (BadLocationException JavaDoc e) {
136                     // leave identifierBeforeCursor null
137
} finally {
138                     adoc.readUnlock();
139                 }
140             }
141             
142             op.waitLoaded();
143
144             queryCaretOffset = caretOffset;
145             queryAnchorOffset = (identifierBeforeCursor != null) ? caretOffset - identifierBeforeCursor.length() : caretOffset;
146             if (identifierBeforeCursor != null) {
147                 boolean ignoreCase = !SettingsUtil.getBoolean(component.getUI().getEditorKit(component).getClass(), ExtSettingsNames.COMPLETION_CASE_SENSITIVE,
148                         ExtSettingsDefaults.defaultCompletionCaseSensitive);
149                 Collection JavaDoc cts = op.findByParametrizedText(identifierBeforeCursor, ignoreCase);
150                 Collection JavaDoc/*<CodeTemplateFilter>*/ filters = op.getTemplateFilters(component, queryAnchorOffset);
151                 queryResult = new ArrayList JavaDoc(cts.size());
152                 for (Iterator JavaDoc it = cts.iterator(); it.hasNext();) {
153                     CodeTemplate ct = (CodeTemplate)it.next();
154                     if (accept(ct, filters))
155                         queryResult.add(new CodeTemplateCompletionItem(ct));
156                 }
157                 resultSet.addAllItems(queryResult);
158             }
159             resultSet.setAnchorOffset(queryAnchorOffset);
160             resultSet.finish();
161         }
162
163         public void stateChanged(ChangeEvent JavaDoc evt) {
164             synchronized (this) {
165                 notify();
166             }
167         }
168         
169         private static boolean accept(CodeTemplate template, Collection JavaDoc/*<CodeTemplateFilter>*/ filters) {
170             for(Iterator JavaDoc it = filters.iterator(); it.hasNext();) {
171                 CodeTemplateFilter filter = (CodeTemplateFilter)it.next();
172                 if (!filter.accept(template))
173                     return false;
174             }
175             return true;
176         }
177         
178     }
179
180 }
181
Popular Tags