com.google.dart.tools.ui.omni.elements.TopLevelElementProvider_NEW.java Source code

Java tutorial

Introduction

Here is the source code for com.google.dart.tools.ui.omni.elements.TopLevelElementProvider_NEW.java

Source

/*
 * Copyright (c) 2013, the Dart project authors.
 * 
 * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
 * 
 * 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 com.google.dart.tools.ui.omni.elements;

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Uninterruptibles;
import com.google.dart.server.FindTopLevelDeclarationsConsumer;
import com.google.dart.tools.core.DartCore;
import com.google.dart.tools.core.analysis.model.SearchResultsListener;
import com.google.dart.tools.ui.omni.OmniElement;
import com.google.dart.tools.ui.omni.OmniProposalProvider;
import com.google.dart.tools.ui.omni.util.CamelUtil;

import org.apache.commons.lang3.StringUtils;
import org.dartlang.analysis.server.protocol.RequestError;
import org.dartlang.analysis.server.protocol.SearchResult;
import org.eclipse.core.runtime.IProgressMonitor;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * Provider for class elements.
 */
public class TopLevelElementProvider_NEW extends OmniProposalProvider {
    /**
     * Place holder to indicate that a search is still in progress.
     */
    public final class SearchInProgressPlaceHolder extends HeaderElement {

        private SearchInProgressPlaceHolder(OmniProposalProvider provider) {
            super(provider);
        }

        @Override
        public void execute(String text) {
            //no-op
        }

        @Override
        public String getId() {
            return "";
        }

        @Override
        public String getLabel() {
            return "  searching...";
        }
    }

    private static final long WAIT_MS = 20;

    private static String getIdentifierCharacters(String str) {
        int length = str.length();
        StringBuilder buf = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            char c = str.charAt(i);
            if (Character.isJavaIdentifierPart(c)) {
                buf.append(c);
            }
        }
        return buf.toString();
    }

    private final Object lock = new Object();

    private final List<OmniElement> results = Lists.newArrayList();

    private String currentRequestPattern = null;
    private CountDownLatch currentRequestLatch;

    private boolean searchComplete;

    private final List<ProviderCompleteListener> listeners = Lists.newArrayList();

    public TopLevelElementProvider_NEW(IProgressMonitor progressMonitor) {
    }

    @Override
    public OmniElement getElementForId(String id) {
        OmniElement[] elements = getElements(id);
        if (elements.length == 0) {
            return null;
        }
        return elements[0];
    }

    @Override
    public OmniElement[] getElements(String pattern) {
        if (StringUtils.isBlank(pattern)) {
            return new OmniElement[0];
        }
        // initiate a new request, if a new pattern
        if (!StringUtils.equals(currentRequestPattern, pattern)) {
            currentRequestPattern = pattern;
            currentRequestLatch = new CountDownLatch(1);
            doSearch();
            // wait a little, if results are ready quickly
            Uninterruptibles.awaitUninterruptibly(currentRequestLatch, WAIT_MS, TimeUnit.MILLISECONDS);
        }
        // return current results
        synchronized (lock) {
            return results.toArray(new OmniElement[results.size()]);
        }
    }

    @Override
    public String getId() {
        return getClass().getName();
    }

    @Override
    public String getName() {
        return "Top-level declarations";
    }

    /**
     * Check if search is complete.
     */
    public boolean isSearchComplete() {
        return searchComplete;
    }

    /**
     * If the current search is not complete yet, the given listener will be notified when the search
     * is complete.
     */
    public void onComplete(ProviderCompleteListener listener) {
        synchronized (lock) {
            if (searchComplete) {
                return;
            }
        }
        synchronized (listeners) {
            listeners.add(listener);
        }
    }

    private void doSearch() {
        String text = getIdentifierCharacters(currentRequestPattern);
        final String pattern = "^" + CamelUtil.getCamelCaseRegExp(text) + ".*";
        final Pattern patternObj = Pattern.compile(pattern);
        //
        searchComplete = false;
        final List<OmniElement> newResults = Lists.newArrayList();
        final CountDownLatch latch = currentRequestLatch;
        DartCore.getAnalysisServer().search_findTopLevelDeclarations(pattern,
                new FindTopLevelDeclarationsConsumer() {
                    @Override
                    public void computedSearchId(String searchId) {
                        DartCore.getAnalysisServerData().addSearchResultsListener(searchId,
                                new SearchResultsListener() {
                                    @Override
                                    public void computedSearchResults(List<SearchResult> searchResults,
                                            boolean last) {
                                        if (latch == currentRequestLatch) {
                                            for (SearchResult searchResult : searchResults) {
                                                newResults.add(
                                                        new TopLevelElement_NEW(TopLevelElementProvider_NEW.this,
                                                                patternObj, searchResult));
                                            }
                                            if (last) {
                                                synchronized (lock) {
                                                    results.clear();
                                                    results.addAll(newResults);
                                                    searchComplete = true;
                                                    currentRequestLatch.getCount();
                                                }
                                                synchronized (listeners) {
                                                    for (ProviderCompleteListener listener : listeners) {
                                                        listener.complete(TopLevelElementProvider_NEW.this);
                                                    }
                                                    listeners.clear();
                                                }
                                            }
                                        }
                                    }
                                });
                    }

                    @Override
                    public void onError(RequestError requestError) {
                        if (latch == currentRequestLatch) {
                            synchronized (results) {
                                results.clear();
                                searchComplete = true;
                                currentRequestLatch.getCount();
                            }
                            synchronized (listeners) {
                                for (ProviderCompleteListener listener : listeners) {
                                    listener.complete(TopLevelElementProvider_NEW.this);
                                }
                                listeners.clear();
                            }
                        }
                    }
                });
    }
}