Source Code Cross Referenced for GsfCompletionProvider.java in  » IDE-Netbeans » gsf » org » netbeans » modules » gsfret » editor » completion » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » gsf » org.netbeans.modules.gsfret.editor.completion 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:        package org.netbeans.modules.gsfret.editor.completion;
042:
043:        import java.io.IOException;
044:        import java.util.ArrayList;
045:        import java.util.Collection;
046:        import java.util.Iterator;
047:        import java.util.List;
048:        import java.util.Set;
049:        import javax.swing.JToolTip;
050:        import javax.swing.text.AbstractDocument;
051:        import javax.swing.text.BadLocationException;
052:        import javax.swing.text.Document;
053:        import javax.swing.text.JTextComponent;
054:        import org.netbeans.api.editor.completion.Completion;
055:        import org.netbeans.modules.gsf.api.CompletionProposal;
056:        import org.netbeans.modules.gsf.api.Completable;
057:        import org.netbeans.modules.gsf.api.CancellableTask;
058:        import org.netbeans.modules.gsf.api.Completable.QueryType;
059:        import org.netbeans.modules.gsf.api.ElementHandle;
060:        import org.netbeans.modules.gsf.api.ElementKind;
061:        import org.netbeans.modules.gsf.api.NameKind;
062:        import org.netbeans.modules.gsf.api.ParameterInfo;
063:        import org.netbeans.api.lexer.TokenHierarchy;
064:        import org.netbeans.api.lexer.TokenId;
065:        import org.netbeans.api.lexer.TokenSequence;
066:        import org.netbeans.napi.gsfret.source.CompilationController;
067:        import org.netbeans.napi.gsfret.source.CompilationInfo;
068:        import org.netbeans.napi.gsfret.source.Phase;
069:        import org.netbeans.napi.gsfret.source.Source;
070:        import org.netbeans.napi.gsfret.source.SourceUtils;
071:        import org.netbeans.editor.BaseDocument;
072:        import org.netbeans.editor.Registry;
073:        import org.netbeans.editor.Settings;
074:        import org.netbeans.editor.SettingsChangeEvent;
075:        import org.netbeans.editor.SettingsChangeListener;
076:        import org.netbeans.editor.SettingsUtil;
077:        import org.netbeans.editor.ext.ExtSettingsDefaults;
078:        import org.netbeans.editor.ext.ExtSettingsNames;
079:        import org.netbeans.modules.gsf.GsfEditorKitFactory;
080:        import org.netbeans.modules.gsf.GsfHtmlFormatter;
081:        import org.netbeans.modules.gsf.Language;
082:        import org.netbeans.modules.gsf.LanguageRegistry;
083:        import org.netbeans.spi.editor.completion.*;
084:        import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery;
085:        import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
086:        import org.openide.ErrorManager;
087:        import org.openide.filesystems.FileObject;
088:        import org.openide.util.Exceptions;
089:        import org.openide.util.NbBundle;
090:
091:        /**
092:         * Code completion provider - delegates to language plugin for actual population of result set.
093:         * Based on JavaCompletionProvider by Dusan Balek.
094:         * 
095:         * @todo I may be able to rip out the code I had in here to work around the
096:         *   automatic completion vs "No Suggestions" issue; see 
097:         *    http://hg.netbeans.org/main?cmd=changeset;node=6740db8e6988
098:         *
099:         * @author Tor Norbye
100:         */
101:        public class GsfCompletionProvider implements  CompletionProvider {
102:
103:            private static final String COMMENT_CATEGORY_NAME = "comment";
104:
105:            /** 
106:             * Flag which is set when we're in a query that was initiated 
107:             * automatically rather than through an explicit gesture 
108:             */
109:            private static boolean isAutoQuery;
110:            private static boolean expectingCreateTask;
111:
112:            public static Completable getCompletable(CompilationInfo info,
113:                    int offset) {
114:                try {
115:                    return getCompletable(info.getDocument(), offset);
116:                } catch (IOException ioe) {
117:                    Exceptions.printStackTrace(ioe);
118:                    return null;
119:                }
120:            }
121:
122:            static Completable getCompletable(Document doc, int offset) {
123:                BaseDocument baseDoc = (BaseDocument) doc;
124:                List<Language> list = LanguageRegistry.getInstance()
125:                        .getEmbeddedLanguages(baseDoc, offset);
126:                for (Language l : list) {
127:                    if (l.getCompletionProvider() != null) {
128:                        return l.getCompletionProvider();
129:                    }
130:                }
131:
132:                return null;
133:            }
134:
135:            private static boolean isInCompletion(JTextComponent component) {
136:                Object o = component.getClientProperty("completion-active"); // NOI18N
137:                return o == Boolean.TRUE;
138:            }
139:
140:            public static int autoQueryTypes(JTextComponent component,
141:                    String typedText) {
142:                if (typedText.length() > 0) {
143:                    Completable provider = getCompletable(component
144:                            .getDocument(), component.getCaretPosition());
145:                    if (provider != null) {
146:                        QueryType autoQuery = provider.getAutoQuery(component,
147:                                typedText);
148:                        switch (autoQuery) {
149:                        case NONE:
150:                            return 0;
151:                        case STOP: {
152:                            isAutoQuery = false;
153:                            Completion.get().hideAll();
154:                            return 0;
155:                        }
156:                        case COMPLETION:
157:                            return COMPLETION_QUERY_TYPE;
158:                        case DOCUMENTATION:
159:                            return DOCUMENTATION_QUERY_TYPE;
160:                        case TOOLTIP:
161:                            return TOOLTIP_QUERY_TYPE;
162:                        case ALL_COMPLETION:
163:                            return COMPLETION_ALL_QUERY_TYPE;
164:                        }
165:                    }
166:                }
167:
168:                return 0;
169:            }
170:
171:            public int getAutoQueryTypes(JTextComponent component,
172:                    String typedText) {
173:                boolean isCompleting = isInCompletion(component);
174:                int type = autoQueryTypes(component, typedText);
175:                if (!isCompleting) {
176:                    isAutoQuery = (type != 0);
177:                    expectingCreateTask = (type != 0); // I get createTask even during editing (or just when matches==0?)
178:                }
179:
180:                return type;
181:            }
182:
183:            // From Utilities
184:            public static boolean isJavaContext(final JTextComponent component,
185:                    final int offset) {
186:                Document doc = component.getDocument();
187:                org.netbeans.api.lexer.Language language = (org.netbeans.api.lexer.Language) doc
188:                        .getProperty(org.netbeans.api.lexer.Language.class);
189:                if (language == null) {
190:                    return true;
191:                }
192:                if (doc instanceof  AbstractDocument) {
193:                    ((AbstractDocument) doc).readLock();
194:                }
195:                try {
196:                    TokenSequence ts = TokenHierarchy.get(
197:                            component.getDocument()).tokenSequence();
198:
199:                    if (ts == null) {
200:                        return false;
201:                    }
202:                    if (!ts.moveNext() || ts.move(offset) == 0) {
203:                        return true;
204:                    }
205:                    if (!ts.moveNext()) { // Move to the next token after move(offset)
206:                        return false;
207:                    }
208:
209:                    TokenId tokenId = ts.token().id();
210:
211:                    Set s = language.tokenCategories().contains(
212:                            COMMENT_CATEGORY_NAME) ? language
213:                            .tokenCategoryMembers(COMMENT_CATEGORY_NAME) : null;
214:
215:                    return s == null || !s.contains(tokenId); //NOI18N
216:                } finally {
217:                    if (doc instanceof  AbstractDocument) {
218:                        ((AbstractDocument) doc).readUnlock();
219:                    }
220:                }
221:            }
222:
223:            public static boolean startsWith(String theString, String prefix) {
224:                if (theString == null || theString.length() == 0)
225:                    return false;
226:                if (prefix == null || prefix.length() == 0)
227:                    return true;
228:                return isCaseSensitive() ? theString.startsWith(prefix)
229:                        : theString.toLowerCase().startsWith(
230:                                prefix.toLowerCase());
231:            }
232:
233:            public CompletionTask createTask(int type, JTextComponent component) {
234:                if (!expectingCreateTask) {
235:                    isAutoQuery = false;
236:                }
237:
238:                if (((type & COMPLETION_QUERY_TYPE) != 0)
239:                        || (type == TOOLTIP_QUERY_TYPE)
240:                        || (type == DOCUMENTATION_QUERY_TYPE)) {
241:                    return new AsyncCompletionTask(new JavaCompletionQuery(
242:                            type, component.getSelectionStart()), component);
243:                }
244:
245:                return null;
246:            }
247:
248:            static CompletionTask createDocTask(ElementHandle element,
249:                    CompilationInfo info) { // TODO - use ComObjectHandle ??
250:                JavaCompletionQuery query = new JavaCompletionQuery(
251:                        DOCUMENTATION_QUERY_TYPE, -1);
252:                query.element = element;
253:
254:                return new AsyncCompletionTask(query, Registry
255:                        .getMostActiveComponent());
256:            }
257:
258:            static final class JavaCompletionQuery extends AsyncCompletionQuery
259:                    implements  CancellableTask<CompilationController> {
260:                private Collection<CompletionItem> results;
261:                private JToolTip toolTip;
262:                private CompletionDocumentation documentation;
263:                private int anchorOffset;
264:                //private int toolTipOffset;
265:                private JTextComponent component;
266:                private int queryType;
267:                private int caretOffset;
268:                private String filterPrefix;
269:                private ElementHandle element;
270:                private Source source;
271:
272:                /** The compilation info that the Element was generated for */
273:
274:                private JavaCompletionQuery(int queryType, int caretOffset) {
275:                    this .queryType = queryType;
276:                    this .caretOffset = caretOffset;
277:                }
278:
279:                @Override
280:                protected void preQueryUpdate(JTextComponent component) {
281:                    int newCaretOffset = component.getSelectionStart();
282:
283:                    if (newCaretOffset >= caretOffset) {
284:                        try {
285:                            if (isJavaIdentifierPart(component.getDocument()
286:                                    .getText(caretOffset,
287:                                            newCaretOffset - caretOffset))) {
288:                                return;
289:                            }
290:                        } catch (BadLocationException e) {
291:                        }
292:                    }
293:
294:                    Completion.get().hideCompletion();
295:                }
296:
297:                @Override
298:                protected void prepareQuery(JTextComponent component) {
299:                    this .component = component;
300:                }
301:
302:                @Override
303:                protected void query(CompletionResultSet resultSet,
304:                        Document doc, int caretOffset) {
305:                    try {
306:                        this .caretOffset = caretOffset;
307:                        if (queryType == TOOLTIP_QUERY_TYPE
308:                                || queryType == DOCUMENTATION_QUERY_TYPE
309:                                || isJavaContext(component, caretOffset)) {
310:                            results = null;
311:                            documentation = null;
312:                            toolTip = null;
313:                            anchorOffset = -1;
314:                            Source js = Source.forDocument(doc);
315:                            if (js == null) {
316:                                FileObject fo = null;
317:                                if (element != null) {
318:                                    fo = element.getFileObject();
319:                                    if (fo != null) {
320:                                        js = Source.forFileObject(fo);
321:                                    }
322:                                }
323:                            }
324:                            //if (queryType == DOCUMENTATION_QUERY_TYPE && element != null) {
325:                            //    FileObject fo = SourceUtils.getFile(element, js.getClasspathInfo());
326:                            //    if (fo != null)
327:                            //        js = Source.forFileObject(fo);
328:                            //}
329:                            if (js != null) {
330:                                if (SourceUtils.isScanInProgress())
331:                                    resultSet.setWaitText(NbBundle.getMessage(
332:                                            GsfCompletionProvider.class,
333:                                            "scanning-in-progress")); //NOI18N
334:                                js.runUserActionTask(this , true);
335:                                if ((queryType & COMPLETION_QUERY_TYPE) != 0) {
336:                                    if (results != null)
337:                                        resultSet.addAllItems(results);
338:                                } else if (queryType == TOOLTIP_QUERY_TYPE) {
339:                                    if (toolTip != null)
340:                                        resultSet.setToolTip(toolTip);
341:                                } else if (queryType == DOCUMENTATION_QUERY_TYPE) {
342:                                    if (documentation != null)
343:                                        resultSet
344:                                                .setDocumentation(documentation);
345:                                }
346:                                if (anchorOffset > -1)
347:                                    resultSet.setAnchorOffset(anchorOffset);
348:                            }
349:                        }
350:                    } catch (IOException ioe) {
351:                        Exceptions.printStackTrace(ioe);
352:                    } finally {
353:                        resultSet.finish();
354:                    }
355:                }
356:
357:                @Override
358:                protected boolean canFilter(JTextComponent component) {
359:                    filterPrefix = null;
360:
361:                    int newOffset = component.getSelectionStart();
362:
363:                    if ((queryType & COMPLETION_QUERY_TYPE) != 0) {
364:                        if (newOffset >= caretOffset) {
365:                            if (anchorOffset > -1) {
366:                                try {
367:                                    String prefix = component.getDocument()
368:                                            .getText(anchorOffset,
369:                                                    newOffset - anchorOffset);
370:
371:                                    if (isJavaIdentifierPart(prefix)) {
372:                                        filterPrefix = prefix;
373:                                    }
374:                                } catch (BadLocationException e) {
375:                                }
376:                            }
377:                        }
378:
379:                        return filterPrefix != null;
380:                    } else if (queryType == TOOLTIP_QUERY_TYPE) {
381:                        try {
382:                            if (newOffset == caretOffset)
383:                                filterPrefix = "";
384:                            else if (newOffset - caretOffset > 0)
385:                                filterPrefix = component.getDocument().getText(
386:                                        caretOffset, newOffset - caretOffset);
387:                            else if (newOffset - caretOffset < 0)
388:                                filterPrefix = component.getDocument().getText(
389:                                        newOffset, caretOffset - newOffset);
390:                        } catch (BadLocationException ex) {
391:                        }
392:                        return (filterPrefix != null
393:                                && filterPrefix.indexOf(',') == -1
394:                                && filterPrefix.indexOf('(') == -1 && filterPrefix
395:                                .indexOf(')') == -1); // NOI18N
396:                    }
397:
398:                    return false;
399:                }
400:
401:                @Override
402:                protected void filter(CompletionResultSet resultSet) {
403:                    try {
404:                        if ((queryType & COMPLETION_QUERY_TYPE) != 0) {
405:                            if (results != null) {
406:                                if (filterPrefix != null) {
407:                                    resultSet.addAllItems(getFilteredData(
408:                                            results, filterPrefix));
409:                                } else {
410:                                    Completion.get().hideDocumentation();
411:                                    Completion.get().hideCompletion();
412:                                }
413:                            }
414:                        } else if (queryType == TOOLTIP_QUERY_TYPE) {
415:                            resultSet.setToolTip(toolTip);
416:                        }
417:
418:                        resultSet.setAnchorOffset(anchorOffset);
419:                    } catch (Exception ex) {
420:                        Exceptions.printStackTrace(ex);
421:                    }
422:
423:                    resultSet.finish();
424:                }
425:
426:                public void run(CompilationController controller)
427:                        throws Exception {
428:                    if (controller.getDocument() == null) {
429:                        return;
430:                    }
431:
432:                    if ((queryType & COMPLETION_QUERY_TYPE) != 0) {
433:                        resolveCompletion(controller);
434:                    } else if (queryType == TOOLTIP_QUERY_TYPE) {
435:                        resolveToolTip(controller);
436:                    } else if (queryType == DOCUMENTATION_QUERY_TYPE) {
437:                        resolveDocumentation(controller);
438:                    }
439:                    GsfCompletionItem.tipProposal = null;
440:                }
441:
442:                public void cancel() {
443:                }
444:
445:                private void resolveToolTip(
446:                        final CompilationController controller)
447:                        throws IOException {
448:                    CompletionProposal proposal = GsfCompletionItem.tipProposal;
449:                    Env env = getCompletionEnvironment(controller, false);
450:                    Completable completer = env.getCompletable();
451:
452:                    if (completer != null) {
453:                        int offset = env.getOffset();
454:                        ParameterInfo info = completer.parameters(controller,
455:                                offset, proposal);
456:                        if (info != ParameterInfo.NONE) {
457:
458:                            List<String> params = info.getNames();
459:
460:                            // Take the parameter list, and balance them out into
461:                            // a "2d" set of lists used by the method params tip component:
462:                            // a list of lists - one for each row, and each row is a list
463:                            // for the clumn
464:                            int MAX_WIDTH = 50; // Max width before wrapping to the next line
465:                            int column = 0;
466:                            List<List<String>> parameterList = new ArrayList<List<String>>();
467:                            List<String> p = new ArrayList<String>();
468:                            for (int length = params.size(), i = 0; i < length; i++) {
469:                                String parameter = params.get(i);
470:                                if (i < length - 1) {
471:                                    parameter = parameter + ", ";
472:                                }
473:                                p.add(parameter);
474:
475:                                column += parameter.length();
476:                                if (column > MAX_WIDTH) {
477:                                    column = 0;
478:                                    parameterList.add(p);
479:                                    p = new ArrayList<String>();
480:
481:                                }
482:                            }
483:                            if (p.size() > 0) {
484:                                parameterList.add(p);
485:                            }
486:
487:                            int index = info.getCurrentIndex();
488:                            anchorOffset = info.getAnchorOffset();
489:                            toolTip = new MethodParamsTipPaintComponent(
490:                                    parameterList, index, component);
491:                            //startPos = (int)sourcePositions.getEndPosition(env.getRoot(), mi.getMethodSelect());
492:                            //String text = controller.getText().substring(startPos, offset);
493:                            //anchorOffset = startPos + controller.getPositionConverter().getOriginalPosition(text.indexOf('(')); //NOI18N
494:                            //toolTipOffset = startPos + controller.getPositionConverter().getOriginalPosition(text.lastIndexOf(',')); //NOI18N
495:                            //if (toolTipOffset < anchorOffset)
496:                            //    toolTipOffset = anchorOffset;
497:                            return;
498:
499:                        }
500:                    }
501:                }
502:
503:                private void resolveDocumentation(
504:                        CompilationController controller) throws IOException {
505:                    controller.toPhase(Phase.RESOLVED);
506:
507:                    if (element != null) {
508:                        documentation = GsfCompletionDoc.create(controller,
509:                                element);
510:                    } else {
511:                        Env env = getCompletionEnvironment(controller, false);
512:                        int offset = env.getOffset();
513:                        String prefix = env.getPrefix();
514:                        results = new ArrayList<CompletionItem>();
515:                        anchorOffset = env.getOffset()
516:                                - ((prefix != null) ? prefix.length() : 0);
517:
518:                        Completable completer = env.getCompletable();
519:
520:                        if (completer != null) {
521:                            List<CompletionProposal> proposals = completer
522:                                    .complete(controller, offset, prefix,
523:                                            NameKind.EXACT_NAME,
524:                                            QueryType.DOCUMENTATION,
525:                                            isCaseSensitive(),
526:                                            new CompletionFormatter());
527:
528:                            if (proposals != null) {
529:                                for (CompletionProposal proposal : proposals) {
530:                                    ElementHandle element = proposal
531:                                            .getElement();
532:                                    if (element != null) {
533:                                        documentation = GsfCompletionDoc
534:                                                .create(controller, element);
535:                                        // TODO - find some way to show the multiple overloaded methods?
536:                                        if (documentation.getText() != null
537:                                                && documentation.getText()
538:                                                        .length() > 0) {
539:                                            // Make sure we at least pick an alternative that has documentation
540:                                            break;
541:                                        }
542:                                    }
543:                                }
544:                            }
545:                        }
546:                    }
547:                }
548:
549:                private void resolveCompletion(CompilationController controller)
550:                        throws IOException {
551:                    Env env = getCompletionEnvironment(controller, true);
552:                    int offset = env.getOffset();
553:                    String prefix = env.getPrefix();
554:                    results = new ArrayList<CompletionItem>();
555:                    anchorOffset = env.getOffset()
556:                            - ((prefix != null) ? prefix.length() : 0);
557:
558:                    Completable completer = env.getCompletable();
559:
560:                    if (completer != null) {
561:                        List<CompletionProposal> proposals = completer
562:                                .complete(
563:                                        controller,
564:                                        offset,
565:                                        prefix,
566:                                        isCaseSensitive() ? NameKind.PREFIX
567:                                                : NameKind.CASE_INSENSITIVE_PREFIX,
568:                                        QueryType.COMPLETION,
569:                                        isCaseSensitive(),
570:                                        new CompletionFormatter());
571:
572:                        if (proposals != null) {
573:                            for (CompletionProposal proposal : proposals) {
574:                                GsfCompletionItem item = GsfCompletionItem
575:                                        .createItem(proposal, controller);
576:
577:                                if (item != null) {
578:                                    results.add(item);
579:                                }
580:                            }
581:                        }
582:
583:                        // If we automatically queried, and there were no hits, take it down
584:                        if (isAutoQuery
585:                                && (proposals == null || proposals.size() == 0)) {
586:                            Completion.get().hideCompletion();
587:                            expectingCreateTask = false;
588:                        }
589:                    }
590:                }
591:
592:                // TODO - delegate to language support!
593:                private boolean isJavaIdentifierPart(String text) {
594:                    for (int i = 0; i < text.length(); i++) {
595:                        if (!(Character.isJavaIdentifierPart(text.charAt(i)))) {
596:                            return false;
597:                        }
598:                    }
599:
600:                    return true;
601:                }
602:
603:                private Collection getFilteredData(
604:                        Collection<CompletionItem> data, String prefix) {
605:                    if (prefix.length() == 0) {
606:                        return data;
607:                    }
608:
609:                    List ret = new ArrayList();
610:
611:                    for (Iterator<CompletionItem> it = data.iterator(); it
612:                            .hasNext();) {
613:                        CompletionItem itm = it.next();
614:
615:                        if (startsWith(itm.getInsertPrefix().toString(), prefix)) {
616:                            ret.add(itm);
617:                        }
618:
619:                        //                else if (itm instanceof LazyTypeCompletionItem && Utilities.startsWith(((LazyTypeCompletionItem)itm).getItemText(), prefix))
620:                        //                    ret.add(itm);
621:                    }
622:
623:                    return ret;
624:                }
625:
626:                /**
627:                 * 
628:                 * @param upToOffset If set, complete only up to the given caret offset, otherwise complete
629:                 *   the full symbol at the offset
630:                 */
631:                private Env getCompletionEnvironment(
632:                        CompilationController controller, boolean upToOffset)
633:                        throws IOException {
634:                    // If you invoke code completion while indexing is in progress, the
635:                    // completion job (which stores the caret offset) will be delayed until
636:                    // indexing is complete - potentially minutes later. When the job
637:                    // is finally run we need to make sure the caret position is still valid. (93017)
638:                    Document doc = controller.getDocument();
639:                    int length = doc != null ? doc.getLength()
640:                            : (int) controller.getFileObject().getSize();
641:                    if (caretOffset > length) {
642:                        caretOffset = length;
643:                    }
644:
645:                    int offset = caretOffset;
646:                    String prefix = null;
647:
648:                    // 
649:                    // TODO - handle the upToOffset parameter
650:                    // Look at the parse tree, and find the corresponding end node
651:                    // offset...
652:
653:                    Completable completer = getCompletable(controller, offset);
654:                    try {
655:                        // TODO: use the completion helper to get the contxt
656:                        if (completer != null) {
657:                            prefix = completer.getPrefix(controller, offset,
658:                                    upToOffset);
659:                        }
660:                        if (prefix == null) {
661:                            int[] blk = org.netbeans.editor.Utilities
662:                                    .getIdentifierBlock(
663:                                            (BaseDocument) controller
664:                                                    .getDocument(), offset);
665:
666:                            if (blk != null) {
667:                                int start = blk[0];
668:
669:                                if (start < offset) {
670:                                    if (upToOffset) {
671:                                        prefix = controller.getDocument()
672:                                                .getText(start, offset - start);
673:                                    } else {
674:                                        prefix = controller.getDocument()
675:                                                .getText(start, blk[1] - start);
676:                                    }
677:                                }
678:                            }
679:                        }
680:                    } catch (BadLocationException ex) {
681:                        ErrorManager.getDefault().notify(ex);
682:                    } catch (IOException ex) {
683:                        ErrorManager.getDefault().notify(ex);
684:                    }
685:
686:                    controller.toPhase(Phase.PARSED);
687:
688:                    return new Env(offset, prefix, controller, completer);
689:                }
690:
691:                private class Env {
692:                    private int offset;
693:                    private String prefix;
694:                    private CompilationController controller;
695:                    private Completable completable;
696:                    private boolean autoCompleting;
697:
698:                    private Env(int offset, String prefix,
699:                            CompilationController controller,
700:                            Completable completable) {
701:                        this .offset = offset;
702:                        this .prefix = prefix;
703:                        this .controller = controller;
704:                        this .completable = completable;
705:                    }
706:
707:                    public int getOffset() {
708:                        return offset;
709:                    }
710:
711:                    public String getPrefix() {
712:                        return prefix;
713:                    }
714:
715:                    public boolean isAutoCompleting() {
716:                        return autoCompleting;
717:                    }
718:
719:                    public void setAutoCompleting(boolean autoCompleting) {
720:                        this .autoCompleting = autoCompleting;
721:                    }
722:
723:                    public CompilationController getController() {
724:                        return controller;
725:                    }
726:
727:                    public Completable getCompletable() {
728:                        return completable;
729:                    }
730:                }
731:            }
732:
733:            /** Format parameters in orange etc. */
734:            private static class CompletionFormatter extends GsfHtmlFormatter {
735:                private static final String METHOD_COLOR = "<font color=#000000>"; //NOI18N
736:                private static final String PARAMETER_NAME_COLOR = "<font color=#a06001>"; //NOI18N
737:                private static final String END_COLOR = "</font>"; // NOI18N
738:                private static final String CLASS_COLOR = "<font color=#560000>"; //NOI18N
739:                private static final String PKG_COLOR = "<font color=#808080>"; //NOI18N
740:                private static final String KEYWORD_COLOR = "<font color=#000099>"; //NOI18N
741:                private static final String FIELD_COLOR = "<font color=#008618>"; //NOI18N
742:                private static final String VARIABLE_COLOR = "<font color=#00007c>"; //NOI18N
743:                private static final String CONSTRUCTOR_COLOR = "<font color=#b28b00>"; //NOI18N
744:                private static final String INTERFACE_COLOR = "<font color=#404040>"; //NOI18N
745:                private static final String PARAMETERS_COLOR = "<font color=#808080>"; //NOI18N
746:                private static final String ACTIVE_PARAMETER_COLOR = "<font color=#000000>"; //NOI18N
747:
748:                @Override
749:                public void parameters(boolean start) {
750:                    assert start != isParameter;
751:                    isParameter = start;
752:
753:                    if (isParameter) {
754:                        sb.append(PARAMETER_NAME_COLOR);
755:                    } else {
756:                        sb.append(END_COLOR);
757:                    }
758:                }
759:
760:                @Override
761:                public void active(boolean start) {
762:                    if (start) {
763:                        sb.append(ACTIVE_PARAMETER_COLOR);
764:                        sb.append("<b>");
765:                    } else {
766:                        sb.append("</b>");
767:                        sb.append(END_COLOR);
768:                    }
769:                }
770:
771:                @Override
772:                public void name(ElementKind kind, boolean start) {
773:                    assert start != isName;
774:                    isName = start;
775:
776:                    if (isName) {
777:                        switch (kind) {
778:                        case CONSTRUCTOR:
779:                            sb.append(CONSTRUCTOR_COLOR);
780:                            break;
781:                        case CALL:
782:                            sb.append(PARAMETERS_COLOR);
783:                            break;
784:                        case DB:
785:                        case METHOD:
786:                            sb.append(METHOD_COLOR);
787:                            break;
788:                        case CLASS:
789:                            sb.append(CLASS_COLOR);
790:                            break;
791:                        case FIELD:
792:                            sb.append(FIELD_COLOR);
793:                            break;
794:                        case MODULE:
795:                            sb.append(PKG_COLOR);
796:                            break;
797:                        case KEYWORD:
798:                            sb.append(KEYWORD_COLOR);
799:                            sb.append("<b>");
800:                            break;
801:                        case VARIABLE:
802:                            sb.append(VARIABLE_COLOR);
803:                            sb.append("<b>");
804:                            break;
805:                        default:
806:                            sb.append("<font>");
807:                        }
808:                    } else {
809:                        switch (kind) {
810:                        case KEYWORD:
811:                        case VARIABLE:
812:                            sb.append("</b>");
813:                            break;
814:                        }
815:                        sb.append(END_COLOR);
816:                    }
817:                }
818:
819:            }
820:
821:            // From Utilities
822:            private static boolean caseSensitive = true;
823:            private static boolean inited;
824:
825:            public static boolean isCaseSensitive() {
826:                lazyInit();
827:                return caseSensitive;
828:            }
829:
830:            private static class SettingsListener implements 
831:                    SettingsChangeListener {
832:
833:                public void settingsChange(SettingsChangeEvent evt) {
834:                    setCaseSensitive(SettingsUtil.getBoolean(
835:                            GsfEditorKitFactory.GsfEditorKit.class,
836:                            ExtSettingsNames.COMPLETION_CASE_SENSITIVE,
837:                            ExtSettingsDefaults.defaultCompletionCaseSensitive));
838:                }
839:            }
840:
841:            private static SettingsChangeListener settingsListener = new SettingsListener();
842:
843:            public static void setCaseSensitive(boolean b) {
844:                lazyInit();
845:                caseSensitive = b;
846:            }
847:
848:            private static void lazyInit() {
849:                if (!inited) {
850:                    inited = true;
851:                    Settings.addSettingsChangeListener(settingsListener);
852:                    setCaseSensitive(SettingsUtil.getBoolean(
853:                            GsfEditorKitFactory.GsfEditorKit.class,
854:                            ExtSettingsNames.COMPLETION_CASE_SENSITIVE,
855:                            ExtSettingsDefaults.defaultCompletionCaseSensitive));
856:                }
857:            }
858:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.