<commit_before>// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.idea.maven.indices;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.text.VersionComparatorUtil;
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItemWithClass;
import org.jetbrains.idea.maven.onlinecompletion.model.MavenRepositoryArtifactInfo;
import org.jetbrains.idea.maven.server.MavenServerIndexer;

import java.util.*;

public class MavenClassSearcher extends MavenSearcher<MavenClassSearchResult> {
  public static final String TERM = MavenServerIndexer.SEARCH_TERM_CLASS_NAMES;

  @Override
  protected List<MavenClassSearchResult> searchImpl(Project project, String pattern, int maxResult) {
    //todo
    throw new UnsupportedOperationException();
  }

  protected String preparePattern(String pattern) {
    pattern = StringUtil.toLowerCase(pattern);
    if (pattern.trim().length() == 0) {
      return pattern;
    }

    List<String> parts = StringUtil.split(pattern, ".");

    StringBuilder newPattern = new StringBuilder();
    for (int i = 0; i < parts.size() - 1; i++) {
      String each = parts.get(i);
      newPattern.append(each.trim());
      newPattern.append("*.");
    }

    String className = parts.get(parts.size() - 1);
    boolean exactSearch = className.endsWith(" ");
    newPattern.append(className.trim());
    if (!exactSearch) newPattern.append("*");

    return newPattern.toString();
  }

  protected List<MavenClassSearchResult> processResults(List<MavenDependencyCompletionItemWithClass> searchResults,
                                                        int maxResult) {

    Map<String, List<MavenDependencyCompletionItem>> classes = new HashMap<>();

    for (MavenDependencyCompletionItemWithClass item : searchResults) {
      for (String className : item.getNames()) {
        List<MavenDependencyCompletionItem> list = classes.get(className);
        if (list == null) {
          list = new ArrayList<>();
          classes.put(className, list);
        }
        list.add(item);
      }
    }

    List<MavenClassSearchResult> results = new ArrayList<>();
    for (Map.Entry<String, List<MavenDependencyCompletionItem>> entry : classes.entrySet()) {
      String className;
      String packageName;
      int pos = entry.getKey().lastIndexOf(".");
      if (pos == -1) {
        packageName = "default package";
        className = entry.getKey();
      }
      else {
        packageName = entry.getKey().substring(0, pos);
        className = entry.getKey().substring(pos + 1);
      }

      MavenDependencyCompletionItem firstOfBunch = entry.getValue().get(0);
      MavenDependencyCompletionItem[] items = entry.getValue().toArray(new MavenDependencyCompletionItem[0]);
      Arrays.sort(items, Comparator.comparing(c -> c.getVersion(), VersionComparatorUtil.COMPARATOR.reversed()));
      MavenClassSearchResult classResult = new MavenClassSearchResult(
        new MavenRepositoryArtifactInfo(firstOfBunch.getGroupId(), firstOfBunch.getArtifactId(), items), className, packageName);
      results.add(classResult);
    }
    return results;
  }
}<commit_msg> IDEA-215618 - restored searchForClass using indices<commit_after>/*
 * Copyright 2000-2015 JetBrains s.r.o.
 *
 * Licensed 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.jetbrains.idea.maven.indices;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.WildcardQuery;
import org.jetbrains.idea.maven.model.MavenArtifactInfo;
import org.jetbrains.idea.maven.onlinecompletion.model.MavenRepositoryArtifactInfo;
import org.jetbrains.idea.maven.server.MavenServerIndexer;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;

public class MavenClassSearcher extends MavenSearcher<MavenClassSearchResult> {
  public static final String TERM = MavenServerIndexer.SEARCH_TERM_CLASS_NAMES;

  @Override
  protected List<MavenClassSearchResult> searchImpl(Project project, String pattern, int maxResult) {
    Pair<String, Query> patternAndQuery = preparePatternAndQuery(pattern);

    MavenProjectIndicesManager m = MavenProjectIndicesManager.getInstance(project);
    Set<MavenArtifactInfo> infos = m.getIndices().stream().flatMap(
      i -> i.search(patternAndQuery.second, 50).stream()
    ).collect(Collectors.toSet());

    return new ArrayList<>(processResults(infos, patternAndQuery.first, maxResult));
  }

  protected Pair<String, Query> preparePatternAndQuery(String pattern) {
    pattern = pattern.toLowerCase();
    if (pattern.trim().length() == 0) {
      return new Pair<>(pattern, new MatchAllDocsQuery());
    }

    List<String> parts = StringUtil.split(pattern, ".");

    StringBuilder newPattern = new StringBuilder();
    for (int i = 0; i < parts.size() - 1; i++) {
      String each = parts.get(i);
      newPattern.append(each.trim());
      newPattern.append("*.");
    }

    String className = parts.get(parts.size() - 1);
    boolean exactSearch = className.endsWith(" ");
    newPattern.append(className.trim());
    if (!exactSearch) newPattern.append("*");

    pattern = newPattern.toString();
    String queryPattern = "*/" + pattern.replaceAll("\\.", "/");

    return new Pair<>(pattern, new WildcardQuery(new Term(TERM, queryPattern)));
  }

  protected Collection<MavenClassSearchResult> processResults(Set<MavenArtifactInfo> infos, String pattern, int maxResult) {
    if (pattern.length() == 0 || pattern.equals("*")) {
      pattern = "^/(.*)$";
    }
    else {
      pattern = pattern.replace(".", "/");

      int lastDot = pattern.lastIndexOf("/");
      String packagePattern = lastDot == -1 ? "" : (pattern.substring(0, lastDot) + "/");
      String classNamePattern = lastDot == -1 ? pattern : pattern.substring(lastDot + 1);

      packagePattern = packagePattern.replaceAll("\\*", ".*?");
      classNamePattern = classNamePattern.replaceAll("\\*", "[^/]*?");

      pattern = packagePattern + classNamePattern;

      pattern = ".*?/" + pattern;
      pattern = "^(" + pattern + ")$";
    }
    Pattern p;
    try {
      p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
    }
    catch (PatternSyntaxException e) {
      return Collections.emptyList();
    }

    Map<String, MavenClassSearchResult> result = new THashMap<>();
    for (MavenArtifactInfo each : infos) {
      if (each.getClassNames() == null) continue;

      Matcher matcher = p.matcher(each.getClassNames());
      while (matcher.find()) {
        String classFQName = matcher.group(1);
        classFQName = classFQName.replace("/", ".");
        classFQName = StringUtil.trimStart(classFQName, ".");

        String key = classFQName;

        MavenClassSearchResult classResult = result.get(key);
        if (classResult == null) {

          int pos = classFQName.lastIndexOf(".");
          MavenRepositoryArtifactInfo artifactInfo = new MavenRepositoryArtifactInfo(
            each.getGroupId(), each.getArtifactId(),
            Collections.singletonList(each.getVersion()));
          if (pos == -1) {
            result.put(key, new MavenClassSearchResult(artifactInfo, classFQName, "default package"));
          }
          else {
            result.put(key, new MavenClassSearchResult(artifactInfo, classFQName.substring(0, pos), classFQName.substring(pos + 1)));
          }
        }
        else {
          List<String> versions = ContainerUtil.map(classResult.getSearchResults().getItems(), i -> i.getVersion());
          versions.add(each.getVersion());
          MavenRepositoryArtifactInfo artifactInfo = new MavenRepositoryArtifactInfo(
            each.getGroupId(), each.getArtifactId(),
            versions);
          result.put(key, new MavenClassSearchResult(artifactInfo, classResult.getClassName(), classResult.getPackageName()));
        }


        if (result.size() > maxResult) break;
      }
    }

    return result.values();
  }
}
{'fraction_non_alphanumeric': 0.122843874391862, 'fraction_numerical': 0.005749668288367979, 'mean_word_length': 3.6077432501273563, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4234182', 'n_tokens_mistral': 2628, 'n_tokens_neox': 2537, 'n_words': 559}