org.springframework.ide.eclipse.boot.properties.editor.metadata.JdtSearchingValueProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ide.eclipse.boot.properties.editor.metadata.JdtSearchingValueProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2016 Pivotal, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Pivotal, Inc. - initial API and implementation
 *******************************************************************************/
package org.springframework.ide.eclipse.boot.properties.editor.metadata;

import java.util.function.Function;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchPattern;
import org.springframework.boot.configurationmetadata.ValueHint;
import org.springframework.ide.eclipse.boot.properties.editor.metadata.ValueProviderRegistry.ValueProviderStrategy;
import org.springframework.ide.eclipse.editor.support.util.FuzzyMatcher;
import org.springsource.ide.eclipse.commons.frameworks.core.async.FluxJdtSearch;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * Abstract implementation of {@link ValueProviderStrategy} based on a JDTSearch.
 * <p>
 * All a subclass must provide is the means to create a {@link SearchPattern} and, optionally a
 * {@link IJavaSearchScope}.
 *
 * @author Kris De Volder
 */
public abstract class JdtSearchingValueProvider extends CachingValueProvider {

    public static String toWildCardPattern(String query) {
        StringBuilder builder = new StringBuilder("*");
        for (char c : query.toCharArray()) {
            builder.append(c);
            builder.append('*');
        }
        return builder.toString();
    }

    public static SearchPattern toPackagePattern(String wildCardedQuery) {
        int searchFor = IJavaSearchConstants.PACKAGE;
        int limitTo = IJavaSearchConstants.DECLARATIONS;
        int matchRule = SearchPattern.R_PATTERN_MATCH;
        return SearchPattern.createPattern(wildCardedQuery, searchFor, limitTo, matchRule);
    }

    public static SearchPattern toClassPattern(String wildCardedQuery) {
        int searchFor = IJavaSearchConstants.CLASS;
        int limitTo = IJavaSearchConstants.DECLARATIONS;
        int matchRule = SearchPattern.R_PATTERN_MATCH;
        return SearchPattern.createPattern(wildCardedQuery, searchFor, limitTo, matchRule);
    }

    public static SearchPattern toTypePattern(String wildCardedQuery) {
        int searchFor = IJavaSearchConstants.TYPE;
        int limitTo = IJavaSearchConstants.DECLARATIONS;
        int matchRule = SearchPattern.R_PATTERN_MATCH;
        return SearchPattern.createPattern(wildCardedQuery, searchFor, limitTo, matchRule);
    }

    protected String asStringValue(IJavaElement element) {
        if (element instanceof IType) {
            IType type = (IType) element;
            return type.getFullyQualifiedName();
        } else if (element instanceof IPackageFragment) {
            IPackageFragment pkg = (IPackageFragment) element;
            return pkg.getElementName();
        }
        return null;
    }

    protected StsValueHint hint(IJavaElement e) {
        String fqName = asStringValue(e);
        return fqName == null ? null : StsValueHint.create(fqName, e);
    }

    protected abstract SearchPattern toPattern(String query);

    protected IJavaSearchScope getScope(IJavaProject javaProject) throws JavaModelException {
        return FluxJdtSearch.searchScope(javaProject);
    }

    @Override
    public Flux<StsValueHint> getValuesAsycn(IJavaProject javaProject, String query) {
        try {
            return new FluxJdtSearch().scope(getScope(javaProject)).pattern(toPattern(query)).search()
                    .flatMap(getPostProcessor())
                    .filter((hint) -> 0 != FuzzyMatcher.matchScore(query, hint.getValue()))
                    .distinct(StsValueHint::getValue);
        } catch (Exception e) {
            return Flux.error(e);
        }
    }

    protected Function<SearchMatch, Mono<StsValueHint>> getPostProcessor() {
        return (match) -> {
            Object e = match.getElement();
            if (e instanceof IJavaElement) {
                return Mono.justOrEmpty(hint((IJavaElement) e));
            }
            return Mono.empty();
        };
    }
}