| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.netbeans.modules.parsing.ui; |
| |
| import java.awt.Color; |
| import java.awt.Font; |
| import java.awt.Graphics; |
| import java.awt.event.KeyEvent; |
| import java.util.Collections; |
| import java.util.concurrent.ExecutionException; |
| import java.util.concurrent.Future; |
| import java.util.concurrent.TimeUnit; |
| import java.util.concurrent.TimeoutException; |
| import java.util.concurrent.atomic.AtomicReference; |
| |
| import javax.swing.text.Document; |
| import javax.swing.text.JTextComponent; |
| |
| import org.netbeans.api.editor.completion.Completion; |
| import org.netbeans.api.editor.mimelookup.MimeRegistration; |
| import org.netbeans.api.editor.mimelookup.MimeRegistrations; |
| import org.netbeans.modules.parsing.api.ParserManager; |
| import org.netbeans.modules.parsing.api.ResultIterator; |
| import org.netbeans.modules.parsing.api.Source; |
| import org.netbeans.modules.parsing.api.UserTask; |
| import org.netbeans.modules.parsing.api.indexing.IndexingManager; |
| import org.netbeans.modules.parsing.spi.ParseException; |
| import org.netbeans.spi.editor.completion.CompletionItem; |
| import org.netbeans.spi.editor.completion.CompletionProvider; |
| import org.netbeans.spi.editor.completion.CompletionResultSet; |
| import org.netbeans.spi.editor.completion.CompletionTask; |
| import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery; |
| import org.netbeans.spi.editor.completion.support.AsyncCompletionTask; |
| import org.netbeans.spi.editor.completion.support.CompletionUtilities; |
| import org.openide.util.NbBundle; |
| import org.openide.util.RequestProcessor; |
| |
| /** |
| * |
| * @author Dusan Balek |
| */ |
| @MimeRegistrations({ |
| @MimeRegistration(mimeType = "text/x-java", service = CompletionProvider.class, position = 10) //NOI18N |
| }) |
| public final class WaitScanFinishedCompletionProvider implements CompletionProvider { |
| |
| private static final RequestProcessor RP = new RequestProcessor( |
| WaitScanFinishedCompletionProvider.class.getName(), |
| 1, |
| false, |
| false); |
| |
| @Override |
| public CompletionTask createTask(int queryType, JTextComponent component) { |
| return (queryType & COMPLETION_QUERY_TYPE) != 0 && IndexingManager.getDefault().isIndexing() ? new AsyncCompletionTask(new Query(), component) : null; |
| } |
| |
| @Override |
| public int getAutoQueryTypes(JTextComponent component, String typedText) { |
| return 0; |
| } |
| |
| @NbBundle.Messages("LBL_ScanningInProgress=Scanning in progress...") |
| private static final class Query extends AsyncCompletionQuery { |
| |
| private final AtomicReference<RequestProcessor.Task> task = new AtomicReference<RequestProcessor.Task>(); |
| |
| @Override |
| protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) { |
| try { |
| final Source source = Source.create(doc); |
| if (source != null) { |
| resultSet.setWaitText(Bundle.LBL_ScanningInProgress()); |
| resultSet.addItem(new Item()); |
| if (task.get() == null) { |
| final RequestProcessor.Task newTask = RP.create(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| Future<Void> f = ParserManager.parseWhenScanFinished(Collections.singletonList(source), new UserTask() { |
| |
| @Override |
| public void run(ResultIterator resultIterator) throws Exception { |
| } |
| }); |
| if (!f.isDone()) { |
| while (true) { |
| if (isTaskCancelled()) { |
| task.set(null); |
| f.cancel(false); |
| break; |
| } |
| try { |
| f.get(250, TimeUnit.MILLISECONDS); |
| task.set(null); |
| Completion.get().hideCompletion(); |
| Completion.get().showCompletion(); |
| break; |
| } catch (TimeoutException te) { |
| // retry |
| } |
| } |
| } |
| } catch (InterruptedException ie) { |
| } catch (ExecutionException ee) { |
| } catch (ParseException pe) { |
| } |
| } |
| }); |
| if (task.compareAndSet(null, newTask)) { |
| newTask.schedule(0); |
| } |
| } |
| } |
| } finally { |
| resultSet.finish(); |
| } |
| } |
| } |
| |
| @NbBundle.Messages("LBL_IncompleteResults=Searching for suggestions...") |
| private static final class Item implements CompletionItem { |
| |
| @Override |
| public void defaultAction(JTextComponent component) { |
| } |
| |
| @Override |
| public void processKeyEvent(KeyEvent evt) { |
| } |
| |
| @Override |
| public int getPreferredWidth(Graphics g, Font defaultFont) { |
| return CompletionUtilities.getPreferredWidth(Bundle.LBL_IncompleteResults(), null, g, defaultFont); |
| } |
| |
| @Override |
| public void render(Graphics g, Font defaultFont, Color defaultColor, Color backgroundColor, int width, int height, boolean selected) { |
| CompletionUtilities.renderHtml(null, Bundle.LBL_IncompleteResults(), null, g, defaultFont, defaultColor, width, height, selected); |
| g.setColor(Color.gray); |
| g.drawLine(0, 0, g.getClipBounds().width, 0); |
| g.setColor(defaultColor); |
| } |
| |
| @Override |
| public CompletionTask createDocumentationTask() { |
| return null; |
| } |
| |
| @Override |
| public CompletionTask createToolTipTask() { |
| return null; |
| } |
| |
| @Override |
| public boolean instantSubstitution(JTextComponent component) { |
| return false; |
| } |
| |
| @Override |
| public int getSortPriority() { |
| return Integer.MAX_VALUE; |
| } |
| |
| @Override |
| public CharSequence getSortText() { |
| return null; |
| } |
| |
| @Override |
| public CharSequence getInsertPrefix() { |
| return null; |
| } |
| } |
| } |