mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-197739 -introducing maven online autocompletion without using indices
This commit is contained in:
@@ -32,7 +32,7 @@ import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.maven.indices.MavenIndex;
|
||||
import org.jetbrains.idea.maven.indices.MavenSearchIndex;
|
||||
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
import org.jetbrains.idea.maven.model.MavenRemoteRepository;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
@@ -127,7 +127,7 @@ class ImportMavenRepositoriesTask {
|
||||
.filter(index -> index.getUpdateTimestamp() == -1 &&
|
||||
index.getFailureMessage() == null &&
|
||||
MavenRepositoriesHolder.getInstance(myProject).contains(index.getRepositoryPathOrUrl()))
|
||||
.map(MavenIndex::getRepositoryPathOrUrl)
|
||||
.map(MavenSearchIndex::getRepositoryPathOrUrl)
|
||||
.collect(Collectors.toList());
|
||||
MavenRepositoriesHolder.getInstance(myProject).updateNotIndexedUrls(repositoriesWithEmptyIndex);
|
||||
});
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.indices.MavenSearchIndex;
|
||||
import org.jetbrains.idea.maven.indices.MavenIndex;
|
||||
import org.jetbrains.idea.maven.indices.MavenIndicesManager;
|
||||
import org.jetbrains.idea.maven.model.MavenRemoteRepository;
|
||||
@@ -69,7 +70,7 @@ public class MavenRepositoriesHolder {
|
||||
if (notificationManager.isNotificationActive(NOTIFICATION_KEY)) return;
|
||||
|
||||
final MavenIndicesManager indicesManager = MavenIndicesManager.getInstance();
|
||||
for (MavenIndex index : indicesManager.getIndices()) {
|
||||
for (MavenSearchIndex index : indicesManager.getIndices()) {
|
||||
if (indicesManager.getUpdatingState(index) != IDLE) return;
|
||||
}
|
||||
|
||||
@@ -87,7 +88,7 @@ public class MavenRepositoriesHolder {
|
||||
ContainerUtil.filter(indicesManager.getIndices(), index -> isNotIndexed(index.getRepositoryPathOrUrl()));
|
||||
indicesManager.scheduleUpdate(myProject, notIndexed).onSuccess(aVoid -> {
|
||||
if (myNotIndexedUrls.isEmpty()) return;
|
||||
for (MavenIndex index : notIndexed) {
|
||||
for (MavenSearchIndex index : notIndexed) {
|
||||
if (index.getUpdateTimestamp() != -1 || index.getFailureMessage() != null) {
|
||||
myNotIndexedUrls.remove(index.getRepositoryPathOrUrl());
|
||||
}
|
||||
|
||||
+20
-41
@@ -4,10 +4,10 @@ package org.jetbrains.idea.maven.dom.converters;
|
||||
import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.codeInsight.completion.InsertHandler;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.OffsetKey;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.codeInsight.template.TemplateManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -23,10 +23,12 @@ import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
|
||||
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifact;
|
||||
import org.jetbrains.idea.maven.model.MavenId;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.DependencySearchService;
|
||||
import org.jetbrains.idea.maven.project.MavenProject;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MavenArtifactCoordinatesArtifactIdConverter extends MavenArtifactCoordinatesConverter {
|
||||
@Override
|
||||
@@ -58,9 +60,9 @@ public class MavenArtifactCoordinatesArtifactIdConverter extends MavenArtifactCo
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> doGetVariants(MavenId id, MavenProjectIndicesManager manager) {
|
||||
protected Set<String> doGetVariants(MavenId id, DependencySearchService searchService) {
|
||||
if (StringUtil.isEmptyOrSpaces(id.getGroupId())) return Collections.emptySet();
|
||||
return manager.getArtifactIds(id.getGroupId());
|
||||
return searchService.findArtifactCandidates(id).stream().map(s -> s.getArtifactId()).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private static class MavenArtifactInsertHandler implements InsertHandler<LookupElement> {
|
||||
@@ -76,7 +78,7 @@ public class MavenArtifactCoordinatesArtifactIdConverter extends MavenArtifactCo
|
||||
context.commitDocument();
|
||||
|
||||
PsiFile contextFile = context.getFile();
|
||||
if(!(contextFile instanceof XmlFile)) return;
|
||||
if (!(contextFile instanceof XmlFile)) return;
|
||||
|
||||
XmlFile xmlFile = (XmlFile)contextFile;
|
||||
|
||||
@@ -91,50 +93,27 @@ public class MavenArtifactCoordinatesArtifactIdConverter extends MavenArtifactCo
|
||||
|
||||
MavenDomDependency dependency = (MavenDomDependency)domElement;
|
||||
|
||||
String artifactId = item.getLookupString();
|
||||
MavenId id = new MavenId(item.getLookupString());
|
||||
String artifactId = id.getArtifactId();
|
||||
|
||||
String groupId = dependency.getGroupId().getStringValue();
|
||||
OffsetKey startRef = context.trackOffset(context.getStartOffset(), false);
|
||||
int len = context.getTailOffset() - context.getStartOffset();
|
||||
if (StringUtil.isEmpty(groupId)) {
|
||||
String g = getUniqueGroupIdOrNull(context.getProject(), artifactId);
|
||||
if (g != null) {
|
||||
dependency.getGroupId().setStringValue(g);
|
||||
groupId = g;
|
||||
}
|
||||
else {
|
||||
if (groupId == null) {
|
||||
dependency.getGroupId().setStringValue("");
|
||||
}
|
||||
|
||||
XmlTag groupIdTag = dependency.getGroupId().getXmlTag();
|
||||
context.getEditor().getCaretModel().moveToOffset(groupIdTag.getValue().getTextRange().getStartOffset());
|
||||
|
||||
MavenDependencyCompletionUtil.invokeCompletion(context, CompletionType.SMART);
|
||||
|
||||
return;
|
||||
groupId = id.getGroupId();
|
||||
if (StringUtil.isEmpty(groupId)) {
|
||||
dependency.getGroupId().setStringValue("");
|
||||
}
|
||||
XmlTag groupIdTag = dependency.getGroupId().getXmlTag();
|
||||
context.getEditor().getCaretModel().moveToOffset(groupIdTag.getValue().getTextRange().getStartOffset());
|
||||
MavenDependencyCompletionUtil.invokeCompletion(context, CompletionType.SMART);
|
||||
return;
|
||||
}
|
||||
int offset = context.getOffset(startRef);
|
||||
context.getDocument().replaceString(offset, offset + len, artifactId);
|
||||
context.commitDocument();
|
||||
|
||||
MavenDependencyCompletionUtil.addTypeAndClassifierAndVersion(context, dependency, groupId, artifactId);
|
||||
}
|
||||
|
||||
private static String getUniqueGroupIdOrNull(@NotNull Project project, @NotNull String artifactId) {
|
||||
MavenProjectIndicesManager manager = MavenProjectIndicesManager.getInstance(project);
|
||||
|
||||
String res = null;
|
||||
|
||||
for (String groupId : manager.getGroupIds()) {
|
||||
if (manager.getArtifactIds(groupId).contains(artifactId)) {
|
||||
if (res == null) {
|
||||
res = groupId;
|
||||
}
|
||||
else {
|
||||
return null; // There are more then one appropriate groupId.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+22
-34
@@ -26,7 +26,10 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.xml.*;
|
||||
import com.intellij.util.xml.ConvertContext;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.GenericDomValue;
|
||||
import com.intellij.util.xml.ResolvingConverter;
|
||||
import com.intellij.util.xml.impl.GenericDomValueReference;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -40,6 +43,7 @@ import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifact;
|
||||
import org.jetbrains.idea.maven.model.MavenId;
|
||||
import org.jetbrains.idea.maven.model.MavenPlugin;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.DependencySearchService;
|
||||
import org.jetbrains.idea.maven.project.MavenProject;
|
||||
import org.jetbrains.idea.maven.project.MavenProjectsManager;
|
||||
import org.jetbrains.idea.maven.utils.MavenArtifactUtil;
|
||||
@@ -69,15 +73,15 @@ public abstract class MavenArtifactCoordinatesConverter extends ResolvingConvert
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<String> getVariants(ConvertContext context) {
|
||||
MavenProjectIndicesManager manager = MavenProjectIndicesManager.getInstance(context.getProject());
|
||||
DependencySearchService searchService = MavenProjectIndicesManager.getInstance(context.getProject()).getSearchService();
|
||||
MavenId id = MavenArtifactCoordinatesHelper.getId(context);
|
||||
|
||||
MavenDomShortArtifactCoordinates coordinates = MavenArtifactCoordinatesHelper.getCoordinates(context);
|
||||
|
||||
return selectStrategy(context).getVariants(id, manager, coordinates);
|
||||
return selectStrategy(context).getVariants(id, searchService, coordinates);
|
||||
}
|
||||
|
||||
protected abstract Set<String> doGetVariants(MavenId id, MavenProjectIndicesManager manager);
|
||||
protected abstract Set<String> doGetVariants(MavenId id, DependencySearchService searchService);
|
||||
|
||||
@Override
|
||||
public PsiElement resolve(String o, ConvertContext context) {
|
||||
@@ -94,7 +98,14 @@ public abstract class MavenArtifactCoordinatesConverter extends ResolvingConvert
|
||||
|
||||
@Override
|
||||
public LocalQuickFix[] getQuickFixes(ConvertContext context) {
|
||||
return ArrayUtil.append(super.getQuickFixes(context), new MyUpdateIndicesFix());
|
||||
MavenId id = MavenArtifactCoordinatesHelper.getId(context);
|
||||
MavenProjectIndicesManager manager = MavenProjectIndicesManager.getInstance(context.getProject());
|
||||
if (manager.hasOfflineIndexes()) {
|
||||
return ArrayUtil.append(super.getQuickFixes(context), new MyUpdateIndicesFix());
|
||||
}
|
||||
else {
|
||||
return super.getQuickFixes(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,8 +202,8 @@ public abstract class MavenArtifactCoordinatesConverter extends ResolvingConvert
|
||||
return doIsValid(id, manager, context) || resolveBySpecifiedPath() != null;
|
||||
}
|
||||
|
||||
public Set<String> getVariants(MavenId id, MavenProjectIndicesManager manager, MavenDomShortArtifactCoordinates coordinates) {
|
||||
return doGetVariants(id, manager);
|
||||
public Set<String> getVariants(MavenId id, DependencySearchService searchService, MavenDomShortArtifactCoordinates coordinates) {
|
||||
return doGetVariants(id, searchService);
|
||||
}
|
||||
|
||||
public PsiFile resolve(MavenId id, ConvertContext context) {
|
||||
@@ -318,21 +329,6 @@ public abstract class MavenArtifactCoordinatesConverter extends ResolvingConvert
|
||||
public PsiFile resolveBySpecifiedPath() {
|
||||
return myDependency.getSystemPath().getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getVariants(MavenId id, MavenProjectIndicesManager manager, MavenDomShortArtifactCoordinates coordinates) {
|
||||
if (StringUtil.isEmpty(id.getGroupId())) {
|
||||
Set<String> result = new THashSet<>();
|
||||
|
||||
for (String each : manager.getGroupIds()) {
|
||||
id = new MavenId(each, id.getArtifactId(), id.getVersion());
|
||||
result.addAll(super.getVariants(id, manager, coordinates));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return super.getVariants(id, manager, coordinates);
|
||||
}
|
||||
}
|
||||
|
||||
private class ExclusionStrategy extends ConverterStrategy {
|
||||
@@ -372,25 +368,17 @@ public abstract class MavenArtifactCoordinatesConverter extends ResolvingConvert
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getVariants(MavenId id, MavenProjectIndicesManager manager, MavenDomShortArtifactCoordinates coordinates) {
|
||||
public Set<String> getVariants(MavenId id, DependencySearchService searchService, MavenDomShortArtifactCoordinates coordinates) {
|
||||
if (StringUtil.isEmpty(id.getGroupId())) {
|
||||
Set<String> result = new THashSet<>();
|
||||
|
||||
for (String each : getGroupIdVariants(manager, coordinates)) {
|
||||
for (String each : MavenArtifactUtil.DEFAULT_GROUPS) {
|
||||
id = new MavenId(each, id.getArtifactId(), id.getVersion());
|
||||
result.addAll(super.getVariants(id, manager, coordinates));
|
||||
result.addAll(super.getVariants(id, searchService, coordinates));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return super.getVariants(id, manager, coordinates);
|
||||
}
|
||||
|
||||
private String[] getGroupIdVariants(MavenProjectIndicesManager manager, MavenDomShortArtifactCoordinates coordinates) {
|
||||
if (DomUtil.hasXml(coordinates.getGroupId())) {
|
||||
Set<String> strings = manager.getGroupIds();
|
||||
return ArrayUtil.toStringArray(strings);
|
||||
}
|
||||
return MavenArtifactUtil.DEFAULT_GROUPS;
|
||||
return super.getVariants(id, searchService, coordinates);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-5
@@ -22,10 +22,12 @@ import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
|
||||
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifact;
|
||||
import org.jetbrains.idea.maven.model.MavenId;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.DependencySearchService;
|
||||
import org.jetbrains.idea.maven.project.MavenProject;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MavenArtifactCoordinatesGroupIdConverter extends MavenArtifactCoordinatesConverter implements MavenSmartConverter<String> {
|
||||
@Override
|
||||
@@ -34,7 +36,7 @@ public class MavenArtifactCoordinatesGroupIdConverter extends MavenArtifactCoord
|
||||
|
||||
if (manager.hasGroupId(id.getGroupId())) return true;
|
||||
|
||||
// Check if artifact was found on importing.
|
||||
// Check if artifact was found on importing.
|
||||
MavenProject mavenProject = findMavenProject(context);
|
||||
if (mavenProject != null) {
|
||||
for (MavenArtifact artifact : mavenProject.findDependencies(id.getGroupId(), id.getArtifactId())) {
|
||||
@@ -48,8 +50,8 @@ public class MavenArtifactCoordinatesGroupIdConverter extends MavenArtifactCoord
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> doGetVariants(MavenId id, MavenProjectIndicesManager manager) {
|
||||
return manager.getGroupIds();
|
||||
protected Set<String> doGetVariants(MavenId id, DependencySearchService searchService) {
|
||||
return searchService.findGroupCandidates(id).stream().map(s -> s.getGroupId()).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -88,7 +90,7 @@ public class MavenArtifactCoordinatesGroupIdConverter extends MavenArtifactCoord
|
||||
context.commitDocument();
|
||||
|
||||
PsiFile contextFile = context.getFile();
|
||||
if(!(contextFile instanceof XmlFile)) return;
|
||||
if (!(contextFile instanceof XmlFile)) return;
|
||||
|
||||
XmlFile xmlFile = (XmlFile)contextFile;
|
||||
|
||||
@@ -109,5 +111,4 @@ public class MavenArtifactCoordinatesGroupIdConverter extends MavenArtifactCoord
|
||||
MavenDependencyCompletionUtil.addTypeAndClassifierAndVersion(context, dependency, item.getLookupString(), artifactId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -36,8 +36,8 @@ public class MavenArtifactCoordinatesHelper {
|
||||
if (coords instanceof MavenDomArtifactCoordinates) {
|
||||
version = ((MavenDomArtifactCoordinates)coords).getVersion().getStringValue();
|
||||
}
|
||||
return new MavenId(coords.getGroupId().getStringValue(),
|
||||
coords.getArtifactId().getStringValue(),
|
||||
version);
|
||||
return new MavenId(MavenDependencyCompletionUtil.removeDummy(coords.getGroupId().getStringValue()),
|
||||
MavenDependencyCompletionUtil.removeDummy(coords.getArtifactId().getStringValue()),
|
||||
MavenDependencyCompletionUtil.removeDummy(version));
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.xml.ConvertContext;
|
||||
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
import org.jetbrains.idea.maven.model.MavenId;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.DependencySearchService;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
@@ -40,7 +41,7 @@ public class MavenArtifactCoordinatesVersionConverter extends MavenArtifactCoord
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> doGetVariants(MavenId id, MavenProjectIndicesManager manager) {
|
||||
protected Set<String> doGetVariants(MavenId id, DependencySearchService searchService) {
|
||||
// Do nothing. Completion variants are generated by MavenVersionCompletionContributor.
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
+67
-5
@@ -18,19 +18,28 @@ package org.jetbrains.idea.maven.dom.converters;
|
||||
import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
|
||||
import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.maven.dom.MavenDomProjectProcessorUtils;
|
||||
import org.jetbrains.idea.maven.dom.model.*;
|
||||
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.DependencySearchService;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
|
||||
import java.util.Set;
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.codeInsight.completion.CompletionUtil.DUMMY_IDENTIFIER;
|
||||
import static com.intellij.codeInsight.completion.CompletionUtil.DUMMY_IDENTIFIER_TRIMMED;
|
||||
|
||||
/**
|
||||
* @author Sergey Evdokimov
|
||||
@@ -89,11 +98,11 @@ public class MavenDependencyCompletionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
MavenProjectIndicesManager manager = MavenProjectIndicesManager.getInstance(project);
|
||||
DependencySearchService service = MavenProjectIndicesManager.getInstance(project).getSearchService();
|
||||
|
||||
Set<String> versions = manager.getVersions(groupId, artifactId);
|
||||
List<MavenDependencyCompletionItem> versions = service.findAllVersions(new MavenDependencyCompletionItem(groupId, artifactId, null));
|
||||
if (versions.size() == 1) {
|
||||
dependency.getVersion().setStringValue(ContainerUtil.getFirstItem(versions));
|
||||
dependency.getVersion().setStringValue(ContainerUtil.getFirstItem(versions).getVersion());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -113,4 +122,57 @@ public class MavenDependencyCompletionUtil {
|
||||
() -> new CodeCompletionHandlerBase(completionType).invokeCompletion(context.getProject(), context.getEditor()));
|
||||
}
|
||||
|
||||
public static LookupElementBuilder lookupElement(MavenDependencyCompletionItem item, String lookup) {
|
||||
return LookupElementBuilder.create(item, lookup)
|
||||
.withIcon(getIcon(item.getType()));
|
||||
}
|
||||
|
||||
public static LookupElementBuilder lookupElement(MavenDependencyCompletionItem item) {
|
||||
return lookupElement(item, getLookupString(item));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Icon getIcon(@Nullable MavenDependencyCompletionItem.Type type) {
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
switch (type) {
|
||||
case REMOTE:
|
||||
return AllIcons.Nodes.PpWeb;
|
||||
case LOCAL:
|
||||
return AllIcons.Nodes.PpLibFolder;
|
||||
case CACHED_ERROR:
|
||||
return AllIcons.Nodes.PpInvalid;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getLookupString(MavenDependencyCompletionItem description) {
|
||||
StringBuilder builder = new StringBuilder(description.getGroupId());
|
||||
if (description.getArtifactId() == null) {
|
||||
builder.append(":...");
|
||||
}
|
||||
else {
|
||||
builder.append(":").append(description.getArtifactId());
|
||||
if (description.getPackaging() != null) {
|
||||
builder.append(":").append(description.getPackaging());
|
||||
}
|
||||
if (description.getVersion() != null) {
|
||||
builder.append(":").append(description.getVersion());
|
||||
}
|
||||
else {
|
||||
builder.append(":...");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static @NotNull String removeDummy(@Nullable String str) {
|
||||
if(str ==null){
|
||||
return "";
|
||||
}
|
||||
return StringUtil.trim(str.replace(DUMMY_IDENTIFIER, "").replace(DUMMY_IDENTIFIER_TRIMMED, ""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.idea.maven.dom.model;
|
||||
|
||||
import com.intellij.ide.presentation.Presentation;
|
||||
import com.intellij.spellchecker.xml.NoSpellchecking;
|
||||
import com.intellij.util.xml.Convert;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
@@ -22,7 +23,10 @@ import com.intellij.util.xml.GenericDomValue;
|
||||
import com.intellij.util.xml.Required;
|
||||
import org.jetbrains.idea.maven.dom.converters.MavenArtifactCoordinatesArtifactIdConverter;
|
||||
import org.jetbrains.idea.maven.dom.converters.MavenArtifactCoordinatesGroupIdConverter;
|
||||
import org.jetbrains.idea.maven.dom.model.presentation.MavenArtifactCoordinatesPresentationProvider;
|
||||
|
||||
|
||||
@Presentation(typeName = "Dependency", icon = "AllIcons.Nodes.PpLib", provider = MavenArtifactCoordinatesPresentationProvider.class)
|
||||
public interface MavenDomShortArtifactCoordinates extends DomElement {
|
||||
@Required
|
||||
@NoSpellchecking
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
// 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.dom.model.completion;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionContributor;
|
||||
import com.intellij.codeInsight.completion.CompletionParameters;
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.psi.xml.XmlText;
|
||||
import com.intellij.psi.xml.XmlTokenType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.dom.converters.MavenDependencyCompletionUtil;
|
||||
import org.jetbrains.idea.maven.dom.model.completion.insert.MavenDependencyInsertHandler;
|
||||
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.utils.MavenLog;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.codeInsight.completion.CompletionUtil.DUMMY_IDENTIFIER;
|
||||
import static com.intellij.codeInsight.completion.CompletionUtil.DUMMY_IDENTIFIER_TRIMMED;
|
||||
|
||||
public class MavenArtifactCompletionContributor extends CompletionContributor {
|
||||
|
||||
|
||||
@Override
|
||||
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
|
||||
if (System.currentTimeMillis() > 1) return;
|
||||
try {
|
||||
PsiElement xmlText = parameters.getPosition().getParent();
|
||||
|
||||
if (!(xmlText instanceof XmlText)) return;
|
||||
|
||||
PsiElement tag = xmlText.getParent();
|
||||
if (!(tag instanceof XmlTag)) return;
|
||||
|
||||
XmlTag parentTag = (XmlTag)tag;
|
||||
|
||||
XmlText currentText = (XmlText)xmlText;
|
||||
|
||||
if (!PsiImplUtil.isLeafElementOfType(xmlText.getPrevSibling(), XmlTokenType.XML_TAG_END)
|
||||
|| !PsiImplUtil.isLeafElementOfType(xmlText.getNextSibling(), XmlTokenType.XML_END_TAG_START)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ("dependency".equals(parentTag.getName())) {
|
||||
fillAllVariants(parameters, result, currentText, parentTag, MavenProjectIndicesManager.getInstance(tag.getProject()));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
MavenLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String getCoordValue(XmlTag dependencyTag, final String tagName) {
|
||||
String result = null;
|
||||
for (XmlTag sub : dependencyTag.getSubTags()) {
|
||||
if (tagName.equals(sub.getName())) {
|
||||
XmlText type = PsiTreeUtil.getChildOfType(sub, XmlText.class);
|
||||
if (type == null) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
result = type.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addToResultSet(CompletionResultSet result, XmlTag dependencyTag, List<MavenDependencyCompletionItem> candidates) {
|
||||
for (MavenDependencyCompletionItem description : candidates) {
|
||||
if (description.getGroupId() == null) {
|
||||
continue;
|
||||
}
|
||||
result.addElement(MavenDependencyCompletionUtil.lookupElement(description)
|
||||
.withInsertHandler(MavenDependencyInsertHandler.INSTANCE));
|
||||
}
|
||||
}
|
||||
|
||||
private void fillAllVariants(CompletionParameters parameters,
|
||||
CompletionResultSet result,
|
||||
XmlText xmlText,
|
||||
XmlTag dependencyTag, MavenProjectIndicesManager instance) {
|
||||
List<MavenDependencyCompletionItem> candidates = instance.getSearchService().findByTemplate(
|
||||
getText(xmlText));
|
||||
|
||||
addToResultSet(result, dependencyTag, candidates);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private static String getText(XmlText text) {
|
||||
return text.getValue().replace(DUMMY_IDENTIFIER, "").replace(DUMMY_IDENTIFIER_TRIMMED, "");
|
||||
}
|
||||
}
|
||||
+53
-25
@@ -4,8 +4,6 @@ package org.jetbrains.idea.maven.dom.model.completion;
|
||||
import com.intellij.codeInsight.actions.ReformatCodeProcessor;
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -23,6 +21,14 @@ import org.jetbrains.idea.maven.dom.converters.MavenDependencyCompletionUtil;
|
||||
import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
|
||||
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
|
||||
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.MavenScopeTable;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.codeInsight.completion.CompletionUtil.DUMMY_IDENTIFIER;
|
||||
import static com.intellij.codeInsight.completion.CompletionUtil.DUMMY_IDENTIFIER_TRIMMED;
|
||||
import static com.intellij.patterns.StandardPatterns.string;
|
||||
|
||||
/**
|
||||
* @author Sergey Evdokimov
|
||||
@@ -43,7 +49,7 @@ public class MavenDependenciesCompletionProvider extends CompletionContributor {
|
||||
if (!"dependency".equals(dependencyTag.getName())) return;
|
||||
|
||||
if (!PsiImplUtil.isLeafElementOfType(xmlText.getPrevSibling(), XmlTokenType.XML_TAG_END)
|
||||
|| !PsiImplUtil.isLeafElementOfType(xmlText.getNextSibling(), XmlTokenType.XML_END_TAG_START)) {
|
||||
|| !PsiImplUtil.isLeafElementOfType(xmlText.getNextSibling(), XmlTokenType.XML_END_TAG_START)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -54,16 +60,14 @@ public class MavenDependenciesCompletionProvider extends CompletionContributor {
|
||||
return;
|
||||
}
|
||||
|
||||
MavenProjectIndicesManager indicesManager = MavenProjectIndicesManager.getInstance(project);
|
||||
|
||||
for (String groupId : indicesManager.getGroupIds()) {
|
||||
for (String artifactId : indicesManager.getArtifactIds(groupId)) {
|
||||
LookupElement builder = LookupElementBuilder.create(groupId + ':' + artifactId)
|
||||
.withIcon(AllIcons.Nodes.PpLib).withInsertHandler(MavenDependencyInsertHandler.INSTANCE);
|
||||
List<MavenDependencyCompletionItem> candidates = MavenProjectIndicesManager.getInstance(project).getSearchService().findByTemplate(
|
||||
StringUtil.trim(xmlText.getText().replace(DUMMY_IDENTIFIER, "").replace(DUMMY_IDENTIFIER_TRIMMED, "")));
|
||||
|
||||
result.addElement(builder);
|
||||
}
|
||||
for (MavenDependencyCompletionItem candidate : candidates) {
|
||||
result.addElement(MavenDependencyCompletionUtil.lookupElement(candidate).withInsertHandler(MavenDependencyInsertHandler.INSTANCE));
|
||||
}
|
||||
result.restartCompletionOnPrefixChange(string().containsChars(":-."));
|
||||
}
|
||||
|
||||
private static class MavenDependencyInsertHandler implements InsertHandler<LookupElement> {
|
||||
@@ -72,38 +76,50 @@ public class MavenDependenciesCompletionProvider extends CompletionContributor {
|
||||
|
||||
@Override
|
||||
public void handleInsert(@NotNull final InsertionContext context, @NotNull LookupElement item) {
|
||||
String s = item.getLookupString();
|
||||
int idx = s.indexOf(':');
|
||||
Object obj = item.getObject();
|
||||
if (!(obj instanceof MavenDependencyCompletionItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String groupId = s.substring(0, idx);
|
||||
String artifactId = s.substring(idx + 1);
|
||||
MavenDependencyCompletionItem dependencyToSet = (MavenDependencyCompletionItem)obj;
|
||||
|
||||
int startOffset = context.getStartOffset();
|
||||
|
||||
PsiFile psiFile = context.getFile();
|
||||
|
||||
DomFileElement<MavenDomProjectModel> domModel = DomManager.getDomManager(context.getProject()).getFileElement((XmlFile)psiFile, MavenDomProjectModel.class);
|
||||
DomFileElement<MavenDomProjectModel> domModel =
|
||||
DomManager.getDomManager(context.getProject()).getFileElement((XmlFile)psiFile, MavenDomProjectModel.class);
|
||||
if (domModel == null) return;
|
||||
|
||||
boolean shouldInvokeCompletion = false;
|
||||
|
||||
MavenDomDependency managedDependency = MavenDependencyCompletionUtil.findManagedDependency(domModel.getRootElement(),
|
||||
context.getProject(), groupId, artifactId);
|
||||
MavenDomDependency managedDependency = findManagedDomDependency(context, dependencyToSet, domModel);
|
||||
if (managedDependency == null) {
|
||||
String value = "<groupId>" + groupId + "</groupId>\n" +
|
||||
"<artifactId>" + artifactId + "</artifactId>\n" +
|
||||
"<version></version>";
|
||||
String classifier =
|
||||
dependencyToSet.getClassifier() == null ? "" : "<classifier>" + dependencyToSet.getClassifier() + "</classifier>\n";
|
||||
String packaging =
|
||||
dependencyToSet.getPackaging() == null || dependencyToSet.getPackaging().equals("jar")
|
||||
? ""
|
||||
: "<packaging>" + dependencyToSet.getPackaging() + "</packaging>\n";
|
||||
String usualScope = MavenScopeTable.getUsualScope(dependencyToSet);
|
||||
String scope = usualScope == null ? "" : "<scope>" + usualScope + "</scope>\n";
|
||||
String version = dependencyToSet.getVersion() == null ? "" : dependencyToSet.getVersion();
|
||||
String value = "<groupId>" + dependencyToSet.getGroupId() + "</groupId>\n" +
|
||||
"<artifactId>" + dependencyToSet.getArtifactId() + "</artifactId>\n" +
|
||||
classifier + packaging + scope +
|
||||
"<version>" + version + "</version>";
|
||||
|
||||
context.getDocument().replaceString(startOffset, context.getSelectionEndOffset(), value);
|
||||
|
||||
context.getEditor().getCaretModel().moveToOffset(startOffset + value.length() - 10);
|
||||
|
||||
shouldInvokeCompletion = true;
|
||||
if (dependencyToSet.getVersion() == null) {
|
||||
context.getEditor().getCaretModel().moveToOffset(startOffset + value.length() - "</version>".length());
|
||||
shouldInvokeCompletion = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<groupId>").append(groupId).append("</groupId>\n")
|
||||
.append("<artifactId>").append(artifactId).append("</artifactId>\n");
|
||||
sb.append("<groupId>").append(dependencyToSet.getGroupId()).append("</groupId>\n")
|
||||
.append("<artifactId>").append(dependencyToSet.getArtifactId()).append("</artifactId>\n");
|
||||
|
||||
String type = managedDependency.getType().getRawText();
|
||||
if (type != null && !type.equals("jar")) {
|
||||
@@ -133,5 +149,17 @@ public class MavenDependenciesCompletionProvider extends CompletionContributor {
|
||||
MavenDependencyCompletionUtil.invokeCompletion(context, CompletionType.BASIC);
|
||||
}
|
||||
}
|
||||
|
||||
private MavenDomDependency findManagedDomDependency(@NotNull InsertionContext context,
|
||||
MavenDependencyCompletionItem dependencyToSet,
|
||||
DomFileElement<MavenDomProjectModel> domModel) {
|
||||
if (dependencyToSet.getGroupId() == null || dependencyToSet.getArtifactId() == null) {
|
||||
return null;
|
||||
}
|
||||
return MavenDependencyCompletionUtil.findManagedDependency(domModel.getRootElement(),
|
||||
context.getProject(),
|
||||
dependencyToSet.getGroupId(),
|
||||
dependencyToSet.getArtifactId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-22
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.jetbrains.idea.maven.dom.model.completion;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.completion.impl.NegatingComparable;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
@@ -33,13 +32,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.maven.dom.MavenVersionComparable;
|
||||
import org.jetbrains.idea.maven.dom.converters.MavenArtifactCoordinatesVersionConverter;
|
||||
import org.jetbrains.idea.maven.dom.converters.MavenDependencyCompletionUtil;
|
||||
import org.jetbrains.idea.maven.dom.model.MavenDomArtifactCoordinates;
|
||||
import org.jetbrains.idea.maven.dom.model.MavenDomPlugin;
|
||||
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
import org.jetbrains.idea.maven.utils.MavenArtifactUtil;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.server.MavenServerManager;
|
||||
import org.jetbrains.idea.maven.utils.library.RepositoryLibraryDescription;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Sergey Evdokimov
|
||||
@@ -61,6 +61,10 @@ public class MavenVersionCompletionContributor extends CompletionContributor {
|
||||
|
||||
XmlTag tag = (XmlTag)tagElement;
|
||||
|
||||
if (!"version".equals(tag.getName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Project project = element.getProject();
|
||||
|
||||
DomElement domElement = DomManager.getDomManager(project).getDomElement(tag);
|
||||
@@ -78,6 +82,7 @@ public class MavenVersionCompletionContributor extends CompletionContributor {
|
||||
|
||||
if (StringUtil.isEmptyOrSpaces(artifactId)) return;
|
||||
|
||||
|
||||
CompletionResultSet newResultSet = result.withRelevanceSorter(CompletionService.getCompletionService().emptySorter().weigh(
|
||||
new LookupElementWeigher("mavenVersionWeigher") {
|
||||
@Nullable
|
||||
@@ -87,28 +92,23 @@ public class MavenVersionCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}));
|
||||
|
||||
MavenProjectIndicesManager indicesManager = MavenProjectIndicesManager.getInstance(project);
|
||||
List<MavenDependencyCompletionItem> completionItems = searchVersions(groupId, artifactId, coordinates, project);
|
||||
|
||||
Set<String> versions;
|
||||
|
||||
if (StringUtil.isEmptyOrSpaces(groupId)) {
|
||||
if (!(coordinates instanceof MavenDomPlugin)) return;
|
||||
|
||||
versions = indicesManager.getVersions(MavenArtifactUtil.DEFAULT_GROUPS[0], artifactId);
|
||||
for (int i = 0; i < MavenArtifactUtil.DEFAULT_GROUPS.length; i++) {
|
||||
versions = Sets.union(versions, indicesManager.getVersions(MavenArtifactUtil.DEFAULT_GROUPS[i], artifactId));
|
||||
}
|
||||
for (MavenDependencyCompletionItem item : completionItems) {
|
||||
newResultSet.addElement(MavenDependencyCompletionUtil.lookupElement(item, item.getVersion()));
|
||||
}
|
||||
else {
|
||||
versions = indicesManager.getVersions(groupId, artifactId);
|
||||
if (MavenServerManager.getInstance().isUseMaven2()) {
|
||||
newResultSet.addElement(LookupElementBuilder.create(RepositoryLibraryDescription.ReleaseVersionId).withStrikeoutness(true));
|
||||
newResultSet.addElement(LookupElementBuilder.create(RepositoryLibraryDescription.LatestVersionId).withStrikeoutness(true));
|
||||
}
|
||||
|
||||
for (String version : versions) {
|
||||
newResultSet.addElement(LookupElementBuilder.create(version));
|
||||
}
|
||||
newResultSet.addElement(LookupElementBuilder.create(RepositoryLibraryDescription.ReleaseVersionId));
|
||||
newResultSet.addElement(LookupElementBuilder.create(RepositoryLibraryDescription.LatestVersionId));
|
||||
}
|
||||
}
|
||||
|
||||
private List<MavenDependencyCompletionItem> searchVersions(String groupId,
|
||||
String artifactId,
|
||||
MavenDomArtifactCoordinates coordinates,
|
||||
Project project) {
|
||||
return MavenProjectIndicesManager.getInstance(project).getSearchService()
|
||||
.findAllVersions(new MavenDependencyCompletionItem(groupId, artifactId, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
// 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.dom.model.completion.insert;
|
||||
|
||||
import com.intellij.codeInsight.actions.ReformatCodeProcessor;
|
||||
import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.codeInsight.completion.InsertHandler;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.source.xml.XmlTagImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.maven.dom.converters.MavenDependencyCompletionUtil;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.MavenScopeTable;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.utils.MavenLog;
|
||||
|
||||
public class MavenDependencyInsertHandler implements InsertHandler<LookupElement> {
|
||||
|
||||
public static final InsertHandler<LookupElement> INSTANCE = new MavenDependencyInsertHandler();
|
||||
|
||||
|
||||
@Override
|
||||
public void handleInsert(@NotNull final InsertionContext context, @NotNull LookupElement item) {
|
||||
try {
|
||||
doHandleInsert(context, item);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
MavenLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void doHandleInsert(@NotNull final InsertionContext context, @NotNull LookupElement item) {
|
||||
|
||||
MavenDependencyCompletionItem mavenId = extract(item);
|
||||
|
||||
int startOffset = context.getStartOffset();
|
||||
|
||||
PsiFile psiFile = context.getFile();
|
||||
XmlTagImpl dependencyTag = getDependencyTag(startOffset, psiFile);
|
||||
if (dependencyTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean shouldInvokeCompletion = setDependency(context, mavenId, dependencyTag);
|
||||
|
||||
context.commitDocument();
|
||||
|
||||
PsiElement e = getDependencyTag(startOffset, psiFile);
|
||||
|
||||
if (e != null) {
|
||||
new ReformatCodeProcessor(psiFile.getProject(), psiFile, e.getTextRange(), false).run();
|
||||
}
|
||||
|
||||
if (shouldInvokeCompletion) {
|
||||
MavenDependencyCompletionUtil.invokeCompletion(context, CompletionType.BASIC);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private XmlTagImpl getDependencyTag(int startOffset, PsiFile psiFile) {
|
||||
PsiElement e = psiFile.findElementAt(startOffset);
|
||||
while (e != null && (!(e instanceof XmlTagImpl) || !"dependency".equals(((XmlTagImpl)e).getName()))) {
|
||||
e = e.getParent();
|
||||
}
|
||||
return (XmlTagImpl)e;
|
||||
}
|
||||
|
||||
private boolean setDependency(@NotNull InsertionContext context,
|
||||
@NotNull MavenDependencyCompletionItem item, XmlTagImpl dependencyTag) {
|
||||
|
||||
int startOffset = dependencyTag.getStartOffset() + "<dependency>".length();
|
||||
int endOffset = dependencyTag.getTextRange().getEndOffset();
|
||||
while ("\n".equals(context.getDocument().getText(new TextRange(endOffset - 1, endOffset)))) {
|
||||
endOffset--;
|
||||
}
|
||||
endOffset -= "</dependency>".length();
|
||||
|
||||
if (item.getGroupId() == null) {
|
||||
return false;
|
||||
}
|
||||
else if (item.getArtifactId() == null) {
|
||||
String value = "\n<groupId>" + item.getGroupId() + "</groupId>\n" +
|
||||
"<artifactId></artifactId>";
|
||||
|
||||
context.getDocument().replaceString(startOffset, endOffset, value);
|
||||
context.getEditor().getCaretModel().moveToOffset(startOffset + value.length() - "</artifactId>".length());
|
||||
return true;
|
||||
}
|
||||
else if (item.getVersion() == null) {
|
||||
String value = "\n<groupId>" + item.getGroupId() + "</groupId>\n" +
|
||||
"<artifactId>" + item.getArtifactId() + "</artifactId>\n" +
|
||||
"<version></version>\n";
|
||||
|
||||
context.getDocument().replaceString(startOffset, endOffset, value);
|
||||
context.getEditor().getCaretModel().moveToOffset(startOffset + value.length() - "</version>".length());
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
String classifier = item.getClassifier() == null ? "" : "<classifier>" + item.getClassifier() + "</classifier>\n";
|
||||
String packaging =
|
||||
item.getPackaging() == null || item.getPackaging().equals("jar") ? "" : "<packaging>" + item.getPackaging() + "</packaging>\n";
|
||||
String usualScope = MavenScopeTable.getUsualScope(item);
|
||||
String scope = usualScope == null ? "" : "<scope>" + usualScope + "</scope>\n";
|
||||
String value = "\n<groupId>" + item.getGroupId() + "</groupId>\n" +
|
||||
"<artifactId>" + item.getArtifactId() + "</artifactId>\n" +
|
||||
classifier + packaging + scope +
|
||||
"<version>" + item.getVersion() + "</version>\n";
|
||||
|
||||
context.getDocument().replaceString(startOffset, endOffset, value);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static MavenDependencyCompletionItem extract(LookupElement item) {
|
||||
Object object = item.getObject();
|
||||
if (object instanceof MavenDependencyCompletionItem) {
|
||||
return (MavenDependencyCompletionItem)object;
|
||||
}
|
||||
else {
|
||||
return new MavenDependencyCompletionItem(item.getLookupString(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-15
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// 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.application.ApplicationManager;
|
||||
|
||||
+18
-14
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 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.
|
||||
// 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.icons.AllIcons;
|
||||
@@ -14,8 +14,9 @@ import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ui.AbstractLayoutManager;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifactInfo;
|
||||
import org.jetbrains.idea.maven.dom.converters.MavenDependencyCompletionUtil;
|
||||
import org.jetbrains.idea.maven.model.MavenId;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.utils.MavenLog;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -180,7 +181,7 @@ public class MavenArtifactSearchPanel extends JPanel {
|
||||
for (MavenArtifactSearchResult searchResult : result) {
|
||||
if (searchResult.versions.isEmpty()) continue;
|
||||
|
||||
MavenArtifactInfo artifactInfo = searchResult.versions.get(0);
|
||||
MavenDependencyCompletionItem artifactInfo = searchResult.getSearchResults().get(0);
|
||||
final String managedVersion = myManagedDependenciesMap.get(Pair.create(artifactInfo.getGroupId(), artifactInfo.getArtifactId()));
|
||||
if (managedVersion != null) {
|
||||
Collections.sort(searchResult.versions, (o1, o2) -> {
|
||||
@@ -219,12 +220,12 @@ public class MavenArtifactSearchPanel extends JPanel {
|
||||
|
||||
for (TreePath each : myResultList.getSelectionPaths()) {
|
||||
Object sel = each.getLastPathComponent();
|
||||
MavenArtifactInfo info;
|
||||
if (sel instanceof MavenArtifactInfo) {
|
||||
info = (MavenArtifactInfo)sel;
|
||||
MavenDependencyCompletionItem info;
|
||||
if (sel instanceof MavenDependencyCompletionItem) {
|
||||
info = (MavenDependencyCompletionItem)sel;
|
||||
}
|
||||
else {
|
||||
info = ((MavenArtifactSearchResult)sel).versions.get(0);
|
||||
info = ((MavenArtifactSearchResult)sel).getSearchResults().get(0);
|
||||
}
|
||||
result.add(new MavenId(info.getGroupId(), info.getArtifactId(), info.getVersion()));
|
||||
}
|
||||
@@ -357,17 +358,20 @@ public class MavenArtifactSearchPanel extends JPanel {
|
||||
else if (value instanceof MavenArtifactSearchResult) {
|
||||
formatSearchResult(tree, (MavenArtifactSearchResult)value, selected);
|
||||
}
|
||||
else if (value instanceof MavenArtifactInfo) {
|
||||
MavenArtifactInfo info = (MavenArtifactInfo)value;
|
||||
else if (value instanceof MavenDependencyCompletionItem) {
|
||||
MavenDependencyCompletionItem info = (MavenDependencyCompletionItem)value;
|
||||
String version = info.getVersion();
|
||||
Icon icon = MavenDependencyCompletionUtil.getIcon(info.getType());
|
||||
|
||||
String managedVersion = myManagedDependenciesMap.get(Pair.create(info.getGroupId(), info.getArtifactId()));
|
||||
|
||||
if (managedVersion != null && managedVersion.equals(version)) {
|
||||
myLeftComponent.setIcon(icon);
|
||||
myLeftComponent.append(version, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
myLeftComponent.append(" (from <dependencyManagement>)", SimpleTextAttributes.GRAYED_ATTRIBUTES);
|
||||
}
|
||||
else {
|
||||
myLeftComponent.setIcon(icon);
|
||||
myLeftComponent.append(version, SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
@@ -376,12 +380,12 @@ public class MavenArtifactSearchPanel extends JPanel {
|
||||
}
|
||||
|
||||
protected void formatSearchResult(JTree tree, MavenArtifactSearchResult searchResult, boolean selected) {
|
||||
MavenArtifactInfo info = searchResult.versions.get(0);
|
||||
MavenDependencyCompletionItem info = searchResult.getSearchResults().get(0);
|
||||
myLeftComponent.setIcon(AllIcons.Nodes.PpLib);
|
||||
appendArtifactInfo(myLeftComponent, info, selected);
|
||||
}
|
||||
|
||||
protected void appendArtifactInfo(SimpleColoredComponent component, MavenArtifactInfo info, boolean selected) {
|
||||
protected void appendArtifactInfo(SimpleColoredComponent component, MavenDependencyCompletionItem info, boolean selected) {
|
||||
component.append(info.getGroupId() + ":", getGrayAttributes(selected));
|
||||
component.append(info.getArtifactId(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
component.append(":" + info.getVersion(), getGrayAttributes(selected));
|
||||
@@ -401,11 +405,11 @@ public class MavenArtifactSearchPanel extends JPanel {
|
||||
@Override
|
||||
protected void formatSearchResult(JTree tree, MavenArtifactSearchResult searchResult, boolean selected) {
|
||||
MavenClassSearchResult classResult = (MavenClassSearchResult)searchResult;
|
||||
MavenArtifactInfo info = searchResult.versions.get(0);
|
||||
MavenDependencyCompletionItem info = searchResult.getSearchResults().get(0);
|
||||
|
||||
myLeftComponent.setIcon(AllIcons.Nodes.Class);
|
||||
myLeftComponent.append(classResult.className, SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
myLeftComponent.append(" (" + classResult.packageName + ")", getGrayAttributes(selected));
|
||||
myLeftComponent.append(classResult.getClassName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
myLeftComponent.append(" (" + classResult.getPackageName() + ")", getGrayAttributes(selected));
|
||||
|
||||
appendArtifactInfo(myRightComponent, info, selected);
|
||||
}
|
||||
|
||||
+34
-16
@@ -1,26 +1,44 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
// 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.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifactInfo;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class MavenArtifactSearchResult {
|
||||
public List<MavenArtifactInfo> versions = new ArrayList<>();
|
||||
@Deprecated
|
||||
/* @deprecated use getSearchResults instead */
|
||||
public List<MavenArtifactInfo> versions;
|
||||
|
||||
private List<MavenDependencyCompletionItem> myResults;
|
||||
|
||||
|
||||
@Deprecated
|
||||
public MavenArtifactSearchResult() {
|
||||
this(new ArrayList<>());
|
||||
}
|
||||
public MavenArtifactSearchResult(@NotNull List<MavenDependencyCompletionItem> results) {
|
||||
setVersions(results);
|
||||
this.myResults = results;
|
||||
}
|
||||
|
||||
public void setResults(List<MavenDependencyCompletionItem> results) {
|
||||
setVersions(results);
|
||||
myResults = results;
|
||||
}
|
||||
|
||||
private void setVersions(@NotNull List<MavenDependencyCompletionItem> results) {
|
||||
versions = ContainerUtil.map(results, d -> new MavenArtifactInfo(d, d.getPackaging(), d.getClassifier()));
|
||||
}
|
||||
|
||||
public List<MavenDependencyCompletionItem> getSearchResults(){
|
||||
return Collections.unmodifiableList(myResults);
|
||||
}
|
||||
}
|
||||
|
||||
+33
-59
@@ -1,77 +1,51 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
// 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.containers.ContainerUtil;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifactInfo;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.DependencySearchService;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.openapi.util.text.StringUtil.*;
|
||||
import static org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters.Flags.ALL_VERSIONS;
|
||||
import static org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters.Flags.FULL_RESOLVE;
|
||||
|
||||
public class MavenArtifactSearcher extends MavenSearcher<MavenArtifactSearchResult> {
|
||||
|
||||
private static final Pattern VERSION_PATTERN = Pattern.compile("[.\\d]+");
|
||||
|
||||
@Override
|
||||
protected List<MavenArtifactSearchResult> searchImpl(Project project, String pattern, int maxResult) {
|
||||
List<String> parts = new ArrayList<>();
|
||||
for (String each : tokenize(pattern, " :")) {
|
||||
parts.add(trimStart(trimEnd(each, "*"), "*"));
|
||||
if (StringUtil.isEmpty(pattern)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
DependencySearchService service = MavenProjectIndicesManager.getInstance(project).getSearchService();
|
||||
List<MavenDependencyCompletionItem> searchResults =
|
||||
service.findByTemplate(pattern, new SearchParameters(1000, 5000, EnumSet.of(FULL_RESOLVE, ALL_VERSIONS)));
|
||||
return processResults(searchResults, pattern);
|
||||
}
|
||||
|
||||
List<MavenArtifactSearchResult> searchResults = ContainerUtil.newSmartList();
|
||||
MavenProjectIndicesManager m = MavenProjectIndicesManager.getInstance(project);
|
||||
int count = 0;
|
||||
List<MavenArtifactInfo> versions = new ArrayList<>();
|
||||
for (String groupId : m.getGroupIds()) {
|
||||
if (count >= maxResult) break;
|
||||
if (parts.size() < 1 || contains(groupId, parts.get(0))) {
|
||||
for (String artifactId : m.getArtifactIds(groupId)) {
|
||||
if (parts.size() < 2 || contains(artifactId, parts.get(1))) {
|
||||
for (String version : m.getVersions(groupId, artifactId)) {
|
||||
if (parts.size() < 3 || contains(version, parts.get(2))) {
|
||||
versions.add(new MavenArtifactInfo(groupId, artifactId, version, "jar", null));
|
||||
if (++count >= maxResult) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parts.size() == 2 && VERSION_PATTERN.matcher(parts.get(1)).matches()) {
|
||||
for (String version : m.getVersions(groupId, artifactId)) {
|
||||
if (contains(version, parts.get(1))) {
|
||||
versions.add(new MavenArtifactInfo(groupId, artifactId, version, "jar", null));
|
||||
if (++count >= maxResult) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!versions.isEmpty()) {
|
||||
MavenArtifactSearchResult searchResult = new MavenArtifactSearchResult();
|
||||
searchResult.versions.addAll(versions);
|
||||
searchResults.add(searchResult);
|
||||
versions.clear();
|
||||
}
|
||||
|
||||
if (count >= maxResult) break;
|
||||
}
|
||||
private static List<MavenArtifactSearchResult> processResults(List<MavenDependencyCompletionItem> searchResults, String pattern) {
|
||||
Map<String, List<MavenDependencyCompletionItem>> results = new HashMap<>();
|
||||
for (MavenDependencyCompletionItem item : searchResults) {
|
||||
if (item.getGroupId() == null || item.getArtifactId() == null || item.getVersion() == null) {
|
||||
continue;
|
||||
}
|
||||
String key = item.getGroupId() + ":" + item.getArtifactId();
|
||||
if(!key.contains(pattern)){
|
||||
continue;
|
||||
}
|
||||
List<MavenDependencyCompletionItem> list = results.get(key);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
results.put(key, list);
|
||||
}
|
||||
list.add(item);
|
||||
}
|
||||
return searchResults;
|
||||
;
|
||||
return ContainerUtil.map(results.values(), MavenArtifactSearchResult::new);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-15
@@ -1,21 +1,30 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
*/
|
||||
// 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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MavenClassSearchResult extends MavenArtifactSearchResult {
|
||||
@Deprecated
|
||||
/* @deprecated use getClassName */
|
||||
public String className;
|
||||
@Deprecated
|
||||
/* @deprecated use getPackageName */
|
||||
public String packageName;
|
||||
|
||||
public MavenClassSearchResult(@NotNull List<MavenDependencyCompletionItem> results, String className, String packageName) {
|
||||
super(results);
|
||||
this.className = className;
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
}
|
||||
+46
-94
@@ -1,53 +1,34 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// 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.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
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.DependencySearchService;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItemWithClass;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters;
|
||||
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 static org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters.Flags.ALL_VERSIONS;
|
||||
import static org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters.Flags.FULL_RESOLVE;
|
||||
|
||||
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.search(patternAndQuery.second, maxResult);
|
||||
|
||||
return new ArrayList<>(processResults(infos, patternAndQuery.first, maxResult));
|
||||
DependencySearchService service = MavenProjectIndicesManager.getInstance(project).getSearchService();
|
||||
List<MavenDependencyCompletionItemWithClass> items = service.findClasses(pattern, new SearchParameters(1000, 5000, EnumSet
|
||||
.of(FULL_RESOLVE, ALL_VERSIONS)));
|
||||
return processResults(items, maxResult);
|
||||
}
|
||||
|
||||
protected Pair<String, Query> preparePatternAndQuery(String pattern) {
|
||||
protected String preparePattern(String pattern) {
|
||||
pattern = pattern.toLowerCase();
|
||||
if (pattern.trim().length() == 0) {
|
||||
return new Pair<>(pattern, new MatchAllDocsQuery());
|
||||
return pattern;
|
||||
}
|
||||
|
||||
List<String> parts = StringUtil.split(pattern, ".");
|
||||
@@ -64,81 +45,52 @@ public class MavenClassSearcher extends MavenSearcher<MavenClassSearchResult> {
|
||||
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)));
|
||||
return newPattern.toString();
|
||||
}
|
||||
|
||||
protected Collection<MavenClassSearchResult> processResults(Set<MavenArtifactInfo> infos, String pattern, int maxResult) {
|
||||
if (pattern.length() == 0 || pattern.equals("*")) {
|
||||
pattern = "^/(.*)$";
|
||||
}
|
||||
else {
|
||||
pattern = pattern.replace(".", "/");
|
||||
protected List<MavenClassSearchResult> processResults(List<MavenDependencyCompletionItemWithClass> searchResults,
|
||||
int maxResult) {
|
||||
|
||||
int lastDot = pattern.lastIndexOf("/");
|
||||
String packagePattern = lastDot == -1 ? "" : (pattern.substring(0, lastDot) + "/");
|
||||
String classNamePattern = lastDot == -1 ? pattern : pattern.substring(lastDot + 1);
|
||||
Map<String, List<MavenDependencyCompletionItem>> classes = new HashMap<>();
|
||||
|
||||
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 = makeKey(classFQName, each);
|
||||
|
||||
MavenClassSearchResult classResult = result.get(key);
|
||||
if (classResult == null) {
|
||||
classResult = new MavenClassSearchResult();
|
||||
int pos = classFQName.lastIndexOf(".");
|
||||
if (pos == -1) {
|
||||
classResult.packageName = "default package";
|
||||
classResult.className = classFQName;
|
||||
}
|
||||
else {
|
||||
classResult.packageName = classFQName.substring(0, pos);
|
||||
classResult.className = classFQName.substring(pos + 1);
|
||||
}
|
||||
result.put(key, classResult);
|
||||
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);
|
||||
}
|
||||
|
||||
classResult.versions.add(each);
|
||||
|
||||
if (result.size() > maxResult) break;
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return result.values();
|
||||
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);
|
||||
}
|
||||
|
||||
MavenClassSearchResult classResult = new MavenClassSearchResult(entry.getValue(), className, packageName);
|
||||
results.add(classResult);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String makeSortKey(MavenClassSearchResult result) {
|
||||
return makeKey(result.className, result.versions.get(0));
|
||||
return makeKey(result.getClassName(), result.getSearchResults().get(0));
|
||||
}
|
||||
|
||||
private String makeKey(String className, MavenArtifactInfo info) {
|
||||
private String makeKey(String className, MavenDependencyCompletionItem info) {
|
||||
return className + " " + super.makeKey(info);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.
|
||||
*/
|
||||
// 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.jarRepository.services.bintray.BintrayModel;
|
||||
@@ -52,7 +38,8 @@ import static com.intellij.openapi.util.text.StringUtil.join;
|
||||
import static com.intellij.openapi.util.text.StringUtil.split;
|
||||
import static com.intellij.util.containers.ContainerUtil.notNullize;
|
||||
|
||||
public class MavenIndex {
|
||||
@Deprecated
|
||||
public class MavenIndex implements MavenSearchIndex {
|
||||
private static final String CURRENT_VERSION = "5";
|
||||
|
||||
protected static final String INDEX_INFO_FILE = "index.properties";
|
||||
@@ -72,10 +59,6 @@ public class MavenIndex {
|
||||
private static final String VERSIONS_MAP_FILE = "versions-map.dat";
|
||||
private static final String ARCHETYPES_MAP_FILE = "archetypes-map.dat";
|
||||
|
||||
public enum Kind {
|
||||
LOCAL, REMOTE
|
||||
}
|
||||
|
||||
private final MavenIndexerWrapper myNexusIndexer;
|
||||
private final NotNexusIndexer myNotNexusIndexer;
|
||||
private final File myDir;
|
||||
@@ -170,6 +153,7 @@ public class MavenIndex {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerId(String repositoryId) throws MavenIndexException {
|
||||
if (myRegisteredRepositoryIds.add(repositoryId)) {
|
||||
save();
|
||||
@@ -252,6 +236,7 @@ public class MavenIndex {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close(boolean releaseIndexContext) {
|
||||
try {
|
||||
if (myData != null) myData.close(releaseIndexContext);
|
||||
@@ -289,40 +274,49 @@ public class MavenIndex {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRepositoryId() {
|
||||
return myId.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getRepositoryFile() {
|
||||
return myKind == Kind.LOCAL ? new File(myRepositoryPathOrUrl) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRepositoryUrl() {
|
||||
return myKind == Kind.REMOTE ? myRepositoryPathOrUrl : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRepositoryPathOrUrl() {
|
||||
return myRepositoryPathOrUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kind getKind() {
|
||||
return myKind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFor(Kind kind, String pathOrUrl) {
|
||||
if (myKind != kind) return false;
|
||||
if (kind == Kind.LOCAL) return FileUtil.pathsEqual(myRepositoryPathOrUrl, normalizePathOrUrl(pathOrUrl));
|
||||
return myRepositoryPathOrUrl.equalsIgnoreCase(normalizePathOrUrl(pathOrUrl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long getUpdateTimestamp() {
|
||||
return myUpdateTimestamp == null ? -1 : myUpdateTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String getFailureMessage() {
|
||||
return myFailureMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOrRepair(boolean fullUpdate, MavenGeneralSettings settings, MavenProgressIndicator progress)
|
||||
throws MavenProcessCanceledException {
|
||||
try {
|
||||
@@ -401,7 +395,7 @@ public class MavenIndex {
|
||||
synchronized (this) {
|
||||
IndexData oldData = myData;
|
||||
|
||||
if(oldData != null) {
|
||||
if (oldData != null) {
|
||||
oldData.close(true);
|
||||
}
|
||||
}
|
||||
@@ -748,10 +742,6 @@ public class MavenIndex {
|
||||
}
|
||||
}
|
||||
|
||||
public interface IndexListener {
|
||||
void indexIsBroken(@NotNull MavenIndex index);
|
||||
}
|
||||
|
||||
private class MyIndexRepositoryIdsProvider implements CachedValueProvider<String> {
|
||||
@Nullable
|
||||
@Override
|
||||
|
||||
@@ -33,12 +33,12 @@ public class MavenIndices {
|
||||
private final MavenIndexerWrapper myIndexer;
|
||||
|
||||
private final File myIndicesDir;
|
||||
private final MavenIndex.IndexListener myListener;
|
||||
private final MavenSearchIndex.IndexListener myListener;
|
||||
|
||||
private final List<MavenIndex> myIndices = new ArrayList<>();
|
||||
private static final Object ourDirectoryLock = new Object();
|
||||
|
||||
public MavenIndices(MavenIndexerWrapper indexer, File indicesDir, MavenIndex.IndexListener listener) {
|
||||
public MavenIndices(MavenIndexerWrapper indexer, File indicesDir, MavenSearchIndex.IndexListener listener) {
|
||||
myIndexer = indexer;
|
||||
myIndicesDir = indicesDir;
|
||||
myListener = listener;
|
||||
@@ -71,7 +71,7 @@ public class MavenIndices {
|
||||
}
|
||||
|
||||
public synchronized void close() {
|
||||
for (MavenIndex each : myIndices) {
|
||||
for (MavenSearchIndex each : myIndices) {
|
||||
each.close(false);
|
||||
}
|
||||
myIndices.clear();
|
||||
@@ -81,7 +81,7 @@ public class MavenIndices {
|
||||
return new ArrayList<>(myIndices);
|
||||
}
|
||||
|
||||
public synchronized MavenIndex add(String repositoryId, String repositoryPathOrUrl, MavenIndex.Kind kind) throws MavenIndexException {
|
||||
public synchronized MavenIndex add(String repositoryId, String repositoryPathOrUrl, MavenSearchIndex.Kind kind) throws MavenIndexException {
|
||||
MavenIndex index = find(repositoryPathOrUrl, kind);
|
||||
if (index != null) {
|
||||
index.registerId(repositoryId);
|
||||
@@ -95,7 +95,7 @@ public class MavenIndices {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MavenIndex find(String repositoryPathOrUrl, MavenIndex.Kind kind) {
|
||||
public MavenIndex find(String repositoryPathOrUrl, MavenSearchIndex.Kind kind) {
|
||||
for (MavenIndex each : myIndices) {
|
||||
if (each.isFor(kind, repositoryPathOrUrl)) return each;
|
||||
}
|
||||
@@ -123,7 +123,7 @@ public class MavenIndices {
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateOrRepair(MavenIndex index, boolean fullUpdate, MavenGeneralSettings settings, MavenProgressIndicator progress)
|
||||
public static void updateOrRepair(MavenSearchIndex index, boolean fullUpdate, MavenGeneralSettings settings, MavenProgressIndicator progress)
|
||||
throws MavenProcessCanceledException {
|
||||
index.updateOrRepair(fullUpdate, settings, progress);
|
||||
}
|
||||
|
||||
+31
-43
@@ -56,8 +56,8 @@ public class MavenIndicesManager implements Disposable {
|
||||
private volatile MavenIndices myIndices;
|
||||
|
||||
private final Object myUpdatingIndicesLock = new Object();
|
||||
private final List<MavenIndex> myWaitingIndices = new ArrayList<>();
|
||||
private volatile MavenIndex myUpdatingIndex;
|
||||
private final List<MavenSearchIndex> myWaitingIndices = new ArrayList<>();
|
||||
private volatile MavenSearchIndex myUpdatingIndex;
|
||||
private final BackgroundTaskQueue myUpdatingQueue = new BackgroundTaskQueue(null, IndicesBundle.message("maven.indices.updating"));
|
||||
|
||||
private volatile List<MavenArchetype> myUserArchetypes = new ArrayList<>();
|
||||
@@ -93,10 +93,12 @@ public class MavenIndicesManager implements Disposable {
|
||||
};
|
||||
MavenServerManager.getInstance().addDownloadListener(myDownloadListener);
|
||||
|
||||
myIndices = new MavenIndices(myIndexer, getIndicesDir().toFile(), new MavenIndex.IndexListener() {
|
||||
myIndices = new MavenIndices(myIndexer, getIndicesDir().toFile(), new MavenSearchIndex.IndexListener() {
|
||||
@Override
|
||||
public void indexIsBroken(@NotNull MavenIndex index) {
|
||||
scheduleUpdate(null, Collections.singletonList(index), false);
|
||||
public void indexIsBroken(@NotNull MavenSearchIndex index) {
|
||||
if(index instanceof MavenIndex) {
|
||||
scheduleUpdate(null, Collections.singletonList((MavenIndex)index), false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -147,51 +149,35 @@ public class MavenIndicesManager implements Disposable {
|
||||
return getIndicesObject().getIndices();
|
||||
}
|
||||
|
||||
public synchronized List<MavenIndex> ensureIndicesExist(Project project,
|
||||
File localRepository,
|
||||
Collection<Pair<String, String>> remoteRepositoriesIdsAndUrls) {
|
||||
// MavenIndices.add method returns an existing index if it has already been added, thus we have to use set here.
|
||||
LinkedHashSet<MavenIndex> result = new LinkedHashSet<>();
|
||||
|
||||
MavenIndices indicesObjectCache = getIndicesObject();
|
||||
|
||||
public synchronized MavenIndex ensureRemoteIndexExist(Project project, Pair<String, String> remoteIndexIdAndUrl) {
|
||||
try {
|
||||
MavenIndex localIndex = indicesObjectCache.add(LOCAL_REPOSITORY_ID, localRepository.getPath(), MavenIndex.Kind.LOCAL);
|
||||
result.add(localIndex);
|
||||
if (localIndex.getUpdateTimestamp() == -1) {
|
||||
scheduleUpdate(project, Collections.singletonList(localIndex));
|
||||
}
|
||||
MavenIndices indicesObjectCache = getIndicesObject();
|
||||
return indicesObjectCache.add(remoteIndexIdAndUrl.first, remoteIndexIdAndUrl.second, MavenSearchIndex.Kind.REMOTE);
|
||||
}
|
||||
catch (MavenIndexException e) {
|
||||
MavenLog.LOG.warn(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized List<MavenIndex> ensureIndicesExist(Project project,
|
||||
Collection<Pair<String, String>> remoteRepositoriesIdsAndUrls) {
|
||||
// MavenIndices.add method returns an existing index if it has already been added, thus we have to use set here.
|
||||
LinkedHashSet<MavenIndex> result = new LinkedHashSet<>();
|
||||
|
||||
for (Pair<String, String> eachIdAndUrl : remoteRepositoriesIdsAndUrls) {
|
||||
try {
|
||||
MavenIndex remoteIndex = indicesObjectCache.add(eachIdAndUrl.first, eachIdAndUrl.second, MavenIndex.Kind.REMOTE);
|
||||
|
||||
result.add(remoteIndex);
|
||||
if (!ApplicationManager.getApplication().isHeadlessEnvironment() &&
|
||||
MavenProjectsManager.getInstance(project).getGeneralSettings().isUpdateIndicesOnProjectOpen() &&
|
||||
remoteIndex.getUpdateTimestamp() < System.currentTimeMillis() - 3600 * 24 * 1000 &&
|
||||
remoteIndex.getUpdateTimestamp() != -1) {
|
||||
scheduleUpdate(project, Collections.singletonList(remoteIndex));
|
||||
}
|
||||
}
|
||||
catch (MavenIndexException e) {
|
||||
MavenLog.LOG.warn(e);
|
||||
}
|
||||
result.add(ensureRemoteIndexExist(project, eachIdAndUrl));
|
||||
}
|
||||
|
||||
return new ArrayList<>(result);
|
||||
}
|
||||
|
||||
private void addArtifact(File artifactFile, String relativePath) {
|
||||
String repositoryPath = getRepositoryUrl(artifactFile, relativePath);
|
||||
|
||||
MavenIndex index = getIndicesObject().find(repositoryPath, MavenIndex.Kind.LOCAL);
|
||||
if (index != null) {
|
||||
index.addArtifact(artifactFile);
|
||||
MavenSearchIndex index = getIndicesObject().find(repositoryPath, MavenSearchIndex.Kind.LOCAL);
|
||||
if (index instanceof MavenIndex) {
|
||||
((MavenIndex)index).addArtifact(artifactFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,10 +200,10 @@ public class MavenIndicesManager implements Disposable {
|
||||
}
|
||||
|
||||
private Promise<Void> scheduleUpdate(final Project projectOrNull, List<MavenIndex> indices, final boolean fullUpdate) {
|
||||
final List<MavenIndex> toSchedule = new ArrayList<>();
|
||||
final List<MavenSearchIndex> toSchedule = new ArrayList<>();
|
||||
|
||||
synchronized (myUpdatingIndicesLock) {
|
||||
for (MavenIndex each : indices) {
|
||||
for (MavenSearchIndex each : indices) {
|
||||
if (myWaitingIndices.contains(each)) continue;
|
||||
toSchedule.add(each);
|
||||
}
|
||||
@@ -246,14 +232,14 @@ public class MavenIndicesManager implements Disposable {
|
||||
return promise;
|
||||
}
|
||||
|
||||
private void doUpdateIndices(final Project projectOrNull, List<MavenIndex> indices, boolean fullUpdate, MavenProgressIndicator indicator)
|
||||
private void doUpdateIndices(final Project projectOrNull, List<MavenSearchIndex> indices, boolean fullUpdate, MavenProgressIndicator indicator)
|
||||
throws MavenProcessCanceledException {
|
||||
MavenLog.LOG.assertTrue(!fullUpdate || projectOrNull != null);
|
||||
|
||||
List<MavenIndex> remainingWaiting = new ArrayList<>(indices);
|
||||
List<MavenSearchIndex> remainingWaiting = new ArrayList<>(indices);
|
||||
|
||||
try {
|
||||
for (MavenIndex each : indices) {
|
||||
for (MavenSearchIndex each : indices) {
|
||||
if (indicator.isCanceled()) return;
|
||||
|
||||
indicator.setText(IndicesBundle.message("maven.indices.updating.index",
|
||||
@@ -302,7 +288,7 @@ public class MavenIndicesManager implements Disposable {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public IndexUpdatingState getUpdatingState(MavenIndex index) {
|
||||
public IndexUpdatingState getUpdatingState(MavenSearchIndex index) {
|
||||
synchronized (myUpdatingIndicesLock) {
|
||||
if (myUpdatingIndex == index) return IndexUpdatingState.UPDATING;
|
||||
if (myWaitingIndices.contains(index)) return IndexUpdatingState.WAITING;
|
||||
@@ -314,8 +300,10 @@ public class MavenIndicesManager implements Disposable {
|
||||
ensureInitialized();
|
||||
Set<MavenArchetype> result = new THashSet<>(myIndexer.getArchetypes());
|
||||
result.addAll(myUserArchetypes);
|
||||
for (MavenIndex index : myIndices.getIndices()) {
|
||||
result.addAll(index.getArchetypes());
|
||||
for (MavenSearchIndex index : myIndices.getIndices()) {
|
||||
if (index instanceof MavenIndex) {
|
||||
result.addAll(((MavenIndex)index).getArchetypes());
|
||||
}
|
||||
}
|
||||
|
||||
for (MavenArchetypesProvider each : MavenArchetypesProvider.EP_NAME.getExtensionList()) {
|
||||
|
||||
+90
-49
@@ -33,6 +33,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifactInfo;
|
||||
import org.jetbrains.idea.maven.model.MavenId;
|
||||
import org.jetbrains.idea.maven.model.MavenRemoteRepository;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.DependencyCompletionProvider;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.DependencySearchService;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.IndexBasedSearchService;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.LocalCompletionSearch;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.central.MavenCentralOnlineSearch;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.project.MavenProject;
|
||||
import org.jetbrains.idea.maven.project.MavenProjectChanges;
|
||||
import org.jetbrains.idea.maven.project.MavenProjectsManager;
|
||||
@@ -42,15 +48,19 @@ import org.jetbrains.idea.maven.utils.MavenMergingUpdateQueue;
|
||||
import org.jetbrains.idea.maven.utils.MavenSimpleProjectComponent;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MavenProjectIndicesManager extends MavenSimpleProjectComponent implements BaseComponent {
|
||||
private volatile List<MavenIndex> myProjectIndices = new ArrayList<>();
|
||||
private volatile boolean offlineIndexes = false;
|
||||
private volatile DependencySearchService mySearchService = new DependencySearchService(Collections.EMPTY_LIST);
|
||||
private final MergingUpdateQueue myUpdateQueue;
|
||||
|
||||
public boolean hasOfflineIndexes() {
|
||||
return offlineIndexes;
|
||||
}
|
||||
|
||||
public static MavenProjectIndicesManager getInstance(Project p) {
|
||||
return p.getComponent(MavenProjectIndicesManager.class);
|
||||
}
|
||||
@@ -92,6 +102,9 @@ public class MavenProjectIndicesManager extends MavenSimpleProjectComponent impl
|
||||
});
|
||||
}
|
||||
|
||||
public void scheduleUpdateRepositoryList() {
|
||||
scheduleUpdateIndicesList();
|
||||
}
|
||||
private void scheduleUpdateIndicesList() {
|
||||
scheduleUpdateIndicesList(null);
|
||||
}
|
||||
@@ -107,9 +120,36 @@ public class MavenProjectIndicesManager extends MavenSimpleProjectComponent impl
|
||||
remoteRepositoriesIdsAndUrls = ReadAction.compute(() -> myProject.isDisposed() ? null : collectRemoteRepositoriesIdsAndUrls());
|
||||
localRepository = ReadAction.compute(() -> myProject.isDisposed() ? null : getLocalRepository());
|
||||
if (remoteRepositoriesIdsAndUrls == null || localRepository == null) return;
|
||||
Set<DependencyCompletionProvider> providers = new HashSet<>();
|
||||
providers.add(new LocalCompletionSearch(localRepository));
|
||||
List<MavenIndex> newIndices = new ArrayList<>();
|
||||
|
||||
myProjectIndices = MavenIndicesManager.getInstance().ensureIndicesExist(myProject, localRepository, remoteRepositoriesIdsAndUrls);
|
||||
if(consumer != null) {
|
||||
Iterator<Pair<String, String>> iterator = remoteRepositoriesIdsAndUrls.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Pair<String, String> pair = iterator.next();
|
||||
if (pair.second.contains("repo.maven.apache.org/maven2") || "central".equals(pair.first)) {
|
||||
providers.add(new MavenCentralOnlineSearch());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
List<MavenIndex> offlineIndices =
|
||||
MavenIndicesManager.getInstance().ensureIndicesExist(myProject, remoteRepositoriesIdsAndUrls);
|
||||
|
||||
for (MavenSearchIndex index : offlineIndices) {
|
||||
if (index instanceof MavenIndex) {
|
||||
providers.add(new IndexBasedSearchService((MavenIndex)index));
|
||||
}
|
||||
}
|
||||
newIndices.addAll(offlineIndices);
|
||||
synchronized (this) {
|
||||
offlineIndexes = !remoteRepositoriesIdsAndUrls.isEmpty();
|
||||
myProjectIndices = newIndices;
|
||||
mySearchService = new DependencySearchService(new ArrayList<>(providers));
|
||||
}
|
||||
|
||||
if (consumer != null) {
|
||||
consumer.consume(myProjectIndices);
|
||||
}
|
||||
}
|
||||
@@ -135,6 +175,8 @@ public class MavenProjectIndicesManager extends MavenSimpleProjectComponent impl
|
||||
return result;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
/* @deprecated use getSearchService */
|
||||
public List<MavenIndex> getIndices() {
|
||||
return new ArrayList<>(myProjectIndices);
|
||||
}
|
||||
@@ -147,7 +189,7 @@ public class MavenProjectIndicesManager extends MavenSimpleProjectComponent impl
|
||||
MavenIndicesManager.getInstance().scheduleUpdate(myProject, indices);
|
||||
}
|
||||
|
||||
public MavenIndicesManager.IndexUpdatingState getUpdatingState(MavenIndex index) {
|
||||
public MavenIndicesManager.IndexUpdatingState getUpdatingState(MavenSearchIndex index) {
|
||||
return MavenIndicesManager.getInstance().getUpdatingState(index);
|
||||
}
|
||||
|
||||
@@ -155,39 +197,49 @@ public class MavenProjectIndicesManager extends MavenSimpleProjectComponent impl
|
||||
return MavenProjectsManager.getInstance(myProject);
|
||||
}
|
||||
|
||||
public Set<String> getGroupIds() {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
Set<String> result = getProjectGroupIds();
|
||||
for (MavenIndex each : myProjectIndices) {
|
||||
result.addAll(each.getGroupIds());
|
||||
}
|
||||
return result;
|
||||
|
||||
public synchronized DependencySearchService getSearchService() {
|
||||
return mySearchService;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
/** @deprecated use {@link org.jetbrains.idea.maven.onlinecompletion.DependencySearchService#findGroupCandidates} or{@link org.jetbrains.idea.maven.onlinecompletion.DependencySearchService#findByTemplate} instead**/
|
||||
public Set<String> getGroupIds() {
|
||||
return getGroupIds("");
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
/** @deprecated use {@link org.jetbrains.idea.maven.onlinecompletion.DependencySearchService#findGroupCandidates} or{@link org.jetbrains.idea.maven.onlinecompletion.DependencySearchService#findByTemplate} instead**/
|
||||
public Set<String> getGroupIds(String pattern) {
|
||||
pattern = pattern == null ? "" : pattern;
|
||||
//todo fix
|
||||
return getSearchService().findGroupCandidates(new MavenDependencyCompletionItem(pattern))
|
||||
.stream().map(d -> d.getArtifactId())
|
||||
.collect(
|
||||
Collectors.toSet());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
/** @deprecated use {@link org.jetbrains.idea.maven.onlinecompletion.DependencySearchService#findArtifactCandidates} or{@link org.jetbrains.idea.maven.onlinecompletion.DependencySearchService#findByTemplate} instead**/
|
||||
public Set<String> getArtifactIds(String groupId) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
Set<String> result = getProjectArtifactIds(groupId);
|
||||
for (MavenIndex each : myProjectIndices) {
|
||||
result.addAll(each.getArtifactIds(groupId));
|
||||
}
|
||||
return result;
|
||||
return getSearchService().findArtifactCandidates(new MavenDependencyCompletionItem(groupId)).stream().map(d -> d.getArtifactId())
|
||||
.collect(
|
||||
Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link org.jetbrains.idea.maven.onlinecompletion.DependencySearchService#findAllVersions or{@link org.jetbrains.idea.maven.onlinecompletion.DependencySearchService#findByTemplate} instead
|
||||
**/
|
||||
public Set<String> getVersions(String groupId, String artifactId) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
Set<String> result = getProjectVersions(groupId, artifactId);
|
||||
for (MavenIndex each : myProjectIndices) {
|
||||
result.addAll(each.getVersions(groupId, artifactId));
|
||||
}
|
||||
return result;
|
||||
return getSearchService().findAllVersions(new MavenDependencyCompletionItem(groupId, artifactId, null, null)).stream()
|
||||
.map(d -> d.getArtifactId()).collect(
|
||||
Collectors.toSet());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean hasGroupId(String groupId) {
|
||||
if (hasProjectGroupId(groupId)) return true;
|
||||
for (MavenIndex each : myProjectIndices) {
|
||||
if (each.hasGroupId(groupId)) return true;
|
||||
}
|
||||
return checkLocalRepository(groupId, null, null);
|
||||
return !getSearchService().findGroupCandidates(new MavenDependencyCompletionItem(groupId)).isEmpty();
|
||||
}
|
||||
|
||||
private boolean checkLocalRepository(String groupId, String artifactId, String version) {
|
||||
@@ -206,32 +258,21 @@ public class MavenProjectIndicesManager extends MavenSimpleProjectComponent impl
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean hasArtifactId(String groupId, String artifactId) {
|
||||
if (hasProjectArtifactId(groupId, artifactId)) return true;
|
||||
for (MavenIndex each : myProjectIndices) {
|
||||
if (each.hasArtifactId(groupId, artifactId)) return true;
|
||||
}
|
||||
return checkLocalRepository(groupId, artifactId, null);
|
||||
return !getSearchService().findAllVersions(new MavenDependencyCompletionItem(groupId, artifactId, null, null)).isEmpty();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean hasVersion(String groupId, String artifactId, String version) {
|
||||
if (hasProjectVersion(groupId, artifactId, version)) return true;
|
||||
for (MavenIndex each : myProjectIndices) {
|
||||
if (each.hasVersion(groupId, artifactId, version)) return true;
|
||||
}
|
||||
return checkLocalRepository(groupId, artifactId, version);
|
||||
return getSearchService().findAllVersions(new MavenDependencyCompletionItem(groupId, artifactId, null, null)).stream().anyMatch(
|
||||
s -> version.equals(s.getVersion())
|
||||
);
|
||||
}
|
||||
|
||||
public Set<MavenArtifactInfo> search(Query query, int maxResult) {
|
||||
Set<MavenArtifactInfo> result = new THashSet<>();
|
||||
|
||||
for (MavenIndex each : myProjectIndices) {
|
||||
int remained = maxResult - result.size();
|
||||
if (remained <= 0) break;
|
||||
result.addAll(each.search(query, remained));
|
||||
}
|
||||
|
||||
return result;
|
||||
//TODO
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
private Set<String> getProjectGroupIds() {
|
||||
|
||||
+9
-4
@@ -28,6 +28,8 @@ import java.awt.event.MouseMotionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.idea.maven.indices.MavenSearchIndex.Kind.REMOTE;
|
||||
|
||||
public class MavenRepositoriesConfigurable implements SearchableConfigurable, Configurable.NoScroll {
|
||||
private final MavenProjectIndicesManager myManager;
|
||||
|
||||
@@ -88,11 +90,12 @@ public class MavenRepositoriesConfigurable implements SearchableConfigurable, Co
|
||||
|
||||
private void updateButtonsState() {
|
||||
boolean hasSelection = !myIndicesTable.getSelectionModel().isSelectionEmpty();
|
||||
hasSelection = getSelectedIndices().stream().anyMatch(i -> i.getKind() == REMOTE);
|
||||
myUpdateButton.setEnabled(hasSelection);
|
||||
}
|
||||
|
||||
public void updateIndexHint(int row) {
|
||||
MavenIndex index = getIndexAt(row);
|
||||
MavenSearchIndex index = getIndexAt(row);
|
||||
String message = index.getFailureMessage();
|
||||
if (message == null) {
|
||||
myIndicesTable.setToolTipText(null);
|
||||
@@ -211,12 +214,13 @@ public class MavenRepositoriesConfigurable implements SearchableConfigurable, Co
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
MavenIndex i = getIndex(rowIndex);
|
||||
MavenSearchIndex i = getIndex(rowIndex);
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return i.getRepositoryPathOrUrl();
|
||||
case 1:
|
||||
if (i.getKind() == MavenIndex.Kind.LOCAL) return "Local";
|
||||
if (i.getKind() == MavenSearchIndex.Kind.LOCAL) return "Local";
|
||||
if (i.getKind() == MavenSearchIndex.Kind.ONLINE) return "Online";
|
||||
return "Remote";
|
||||
case 2:
|
||||
if (i.getFailureMessage() != null) {
|
||||
@@ -224,6 +228,7 @@ public class MavenRepositoriesConfigurable implements SearchableConfigurable, Co
|
||||
}
|
||||
long timestamp = i.getUpdateTimestamp();
|
||||
if (timestamp == -1) return IndicesBundle.message("maven.index.updated.never");
|
||||
if (i.getKind() != REMOTE) return IndicesBundle.message("maven.index.updated.notapplicable");
|
||||
return DateFormatUtil.formatDate(timestamp);
|
||||
case 3:
|
||||
return myManager.getUpdatingState(i);
|
||||
@@ -245,7 +250,7 @@ public class MavenRepositoriesConfigurable implements SearchableConfigurable, Co
|
||||
|
||||
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
|
||||
MavenIndex index = getIndexAt(row);
|
||||
MavenSearchIndex index = getIndexAt(row);
|
||||
if (index.getFailureMessage() != null) {
|
||||
if (isSelected) {
|
||||
setForeground(JBColor.PINK);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.project.MavenGeneralSettings;
|
||||
import org.jetbrains.idea.maven.utils.MavenProcessCanceledException;
|
||||
import org.jetbrains.idea.maven.utils.MavenProgressIndicator;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface MavenSearchIndex {
|
||||
|
||||
enum Kind {
|
||||
LOCAL, REMOTE, ONLINE
|
||||
}
|
||||
|
||||
void registerId(String repositoryId) throws MavenIndexException;
|
||||
|
||||
void close(boolean releaseIndexContext);
|
||||
|
||||
String getRepositoryId();
|
||||
|
||||
File getRepositoryFile();
|
||||
|
||||
String getRepositoryUrl();
|
||||
|
||||
String getRepositoryPathOrUrl();
|
||||
|
||||
Kind getKind();
|
||||
|
||||
boolean isFor(Kind kind, String pathOrUrl);
|
||||
|
||||
long getUpdateTimestamp();
|
||||
|
||||
String getFailureMessage();
|
||||
|
||||
void updateOrRepair(boolean fullUpdate, MavenGeneralSettings settings, MavenProgressIndicator progress)
|
||||
throws MavenProcessCanceledException;
|
||||
|
||||
interface IndexListener {
|
||||
void indexIsBroken(@NotNull MavenSearchIndex index);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ package org.jetbrains.idea.maven.indices;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.idea.maven.dom.MavenVersionComparable;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifactInfo;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -32,27 +32,23 @@ public abstract class MavenSearcher<RESULT_TYPE extends MavenArtifactSearchResul
|
||||
private List<RESULT_TYPE> sort(List<RESULT_TYPE> result) {
|
||||
for (RESULT_TYPE each : result) {
|
||||
if (each.versions.size() > 1) {
|
||||
TreeMap<MavenVersionComparable, MavenArtifactInfo> tree = new TreeMap<>(Collections.reverseOrder());
|
||||
TreeMap<MavenVersionComparable, MavenDependencyCompletionItem> tree = new TreeMap<>(Collections.reverseOrder());
|
||||
|
||||
for (MavenArtifactInfo artifactInfo : each.versions) {
|
||||
for (MavenDependencyCompletionItem artifactInfo : each.getSearchResults()) {
|
||||
tree.put(new MavenVersionComparable(artifactInfo.getVersion()), artifactInfo);
|
||||
}
|
||||
|
||||
each.versions.clear();
|
||||
each.versions.addAll(tree.values());
|
||||
each.setResults(new ArrayList<>(tree.values()));
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(result, Comparator.comparing(this::makeSortKey));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected String makeSortKey(RESULT_TYPE result) {
|
||||
return makeKey(result.versions.get(0));
|
||||
return makeKey(result.getSearchResults().get(0));
|
||||
}
|
||||
|
||||
protected String makeKey(MavenArtifactInfo result) {
|
||||
protected String makeKey(MavenDependencyCompletionItem result) {
|
||||
return result.getGroupId() + ":" + result.getArtifactId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// 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 org.jetbrains.idea.maven.project.MavenGeneralSettings;
|
||||
import org.jetbrains.idea.maven.utils.MavenProcessCanceledException;
|
||||
import org.jetbrains.idea.maven.utils.MavenProgressIndicator;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/*this class used only for backward compatibility for legacy code, which expect to get MavenIndices. To be removed in future releases*/
|
||||
public class OnlineMavenIndex implements MavenSearchIndex {
|
||||
private final String myRepositoryId;
|
||||
private final String myRepositoryUrl;
|
||||
|
||||
public OnlineMavenIndex(String repositoryId, String repositoryUrl) {
|
||||
myRepositoryId = repositoryId;
|
||||
myRepositoryUrl = repositoryUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerId(String repositoryId) throws MavenIndexException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(boolean releaseIndexContext) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRepositoryId() {
|
||||
return myRepositoryId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getRepositoryFile() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRepositoryUrl() {
|
||||
return myRepositoryUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRepositoryPathOrUrl() {
|
||||
return myRepositoryUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kind getKind() {
|
||||
return Kind.ONLINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFor(Kind kind, String pathOrUrl) {
|
||||
return kind == Kind.ONLINE && myRepositoryUrl.equals(pathOrUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUpdateTimestamp() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFailureMessage() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOrRepair(boolean fullUpdate, MavenGeneralSettings settings, MavenProgressIndicator progress)
|
||||
throws MavenProcessCanceledException {
|
||||
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// 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.onlinecompletion;
|
||||
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
class DeduplicationCollector<Result extends MavenDependencyCompletionItem>
|
||||
implements
|
||||
Collector<List<? extends Result>, Map<String, Result>, List<Result>> {
|
||||
static final Set<Characteristics> CHARACTERISTICS
|
||||
= Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED));
|
||||
|
||||
private final Function<Result, String> myDeduplicationKey;
|
||||
|
||||
DeduplicationCollector(Function<Result, String> deduplicationKey) {
|
||||
myDeduplicationKey = deduplicationKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<Map<String, Result>> supplier() {
|
||||
return () -> new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiConsumer<Map<String, Result>, List<? extends Result>> accumulator() {
|
||||
return (m, l) -> {
|
||||
if (l != null && m != null) {
|
||||
for (Result item : l) {
|
||||
String key = myDeduplicationKey.apply(item);
|
||||
Result present = m.get(key);
|
||||
if (present == null || present.getType().getWeight() < item.getType().getWeight()) {
|
||||
m.put(key, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryOperator<Map<String, Result>> combiner() {
|
||||
return (m, l) -> {
|
||||
for (Result item : l.values()) {
|
||||
String key = myDeduplicationKey.apply(item);
|
||||
Result present = m.get(key);
|
||||
if (present != null && item.getType() == null) {
|
||||
continue;
|
||||
}
|
||||
if (present == null ||
|
||||
present.getType() == null && item.getType() != null ||
|
||||
present.getType().getWeight() < item.getType().getWeight()) {
|
||||
m.put(key, item);
|
||||
}
|
||||
}
|
||||
return m;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<Map<String, Result>, List<Result>> finisher() {
|
||||
return m -> new ArrayList<>(m.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Characteristics> characteristics() {
|
||||
return CHARACTERISTICS;
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// 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.onlinecompletion;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.model.MavenCoordinate;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItemWithClass;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public interface DependencyCompletionProvider {
|
||||
|
||||
|
||||
@NotNull
|
||||
List<MavenDependencyCompletionItem> findGroupCandidates(MavenCoordinate template, SearchParameters searchParameters)
|
||||
throws IOException;
|
||||
|
||||
@NotNull
|
||||
List<MavenDependencyCompletionItem> findArtifactCandidates(MavenCoordinate template, SearchParameters searchParameters)
|
||||
throws IOException;
|
||||
|
||||
@NotNull
|
||||
List<MavenDependencyCompletionItem> findAllVersions(MavenCoordinate template, SearchParameters searchParameters)
|
||||
throws IOException;
|
||||
|
||||
@NotNull
|
||||
List<MavenDependencyCompletionItemWithClass> findClassesByString(String str, SearchParameters searchParameters)
|
||||
throws IOException;
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
// 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.onlinecompletion;
|
||||
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.idea.maven.model.MavenCoordinate;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItemWithClass;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters;
|
||||
import org.jetbrains.idea.maven.utils.MavenLog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
public class DependencySearchService {
|
||||
|
||||
private static final DeduplicationCollector<MavenDependencyCompletionItem> GROUP_COLLECTOR =
|
||||
new DeduplicationCollector<>(m -> m.getGroupId());
|
||||
private static final DeduplicationCollector<MavenDependencyCompletionItem> ARTIFACT_COLLECTOR =
|
||||
new DeduplicationCollector<>(m -> m.getGroupId() + ":" + m.getArtifactId());
|
||||
private static final DeduplicationCollector VERSION_COLLECTOR =
|
||||
new DeduplicationCollector<>(m -> m.getGroupId() + ":" + m.getArtifactId() + ":" + m.getVersion());
|
||||
private final List<DependencyCompletionProvider> myProviders;
|
||||
|
||||
public DependencySearchService(List<DependencyCompletionProvider> providers) {
|
||||
myProviders = providers;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<MavenDependencyCompletionItem> findByTemplate(@NotNull String coord) {
|
||||
return findByTemplate(coord, SearchParameters.DEFAULT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<MavenDependencyCompletionItem> findByTemplate(@NotNull String coord, @NotNull SearchParameters parameters) {
|
||||
MavenDependencyCompletionItem template = new MavenDependencyCompletionItem(coord, null);
|
||||
if (StringUtil.isEmpty(template.getGroupId())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
else if (StringUtil.isEmpty(template.getArtifactId())) {
|
||||
List<MavenDependencyCompletionItem> result = new ArrayList<>();
|
||||
result.addAll(findGroupCandidates(template, parameters));
|
||||
result.addAll(findArtifactCandidates(template, parameters));
|
||||
return result;
|
||||
}
|
||||
else if (StringUtil.isEmpty(template.getVersion())) {
|
||||
List<MavenDependencyCompletionItem> result = new ArrayList<>();
|
||||
result.addAll(findArtifactCandidates(template, parameters));
|
||||
result.addAll(findAllVersions(template, parameters));
|
||||
return result;
|
||||
}
|
||||
return findAllVersions(template, parameters);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<MavenDependencyCompletionItem> findGroupCandidates(@NotNull MavenCoordinate template) {
|
||||
return findGroupCandidates(template, SearchParameters.DEFAULT);
|
||||
}
|
||||
|
||||
public List<MavenDependencyCompletionItem> findGroupCandidates(@NotNull MavenCoordinate template, @NotNull SearchParameters parameters) {
|
||||
return doQuery(parameters, template, (p, s) -> p.findGroupCandidates(s, parameters), GROUP_COLLECTOR);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public List<MavenDependencyCompletionItem> findArtifactCandidates(@NotNull MavenCoordinate template) {
|
||||
return findArtifactCandidates(template, SearchParameters.DEFAULT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<MavenDependencyCompletionItem> findArtifactCandidates(@NotNull MavenCoordinate template,
|
||||
@NotNull SearchParameters parameters) {
|
||||
return doQuery(parameters, template, (p, s) -> p.findArtifactCandidates(s, parameters), ARTIFACT_COLLECTOR);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<MavenDependencyCompletionItem> findAllVersions(@NotNull MavenCoordinate template) {
|
||||
return findAllVersions(template, SearchParameters.DEFAULT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<MavenDependencyCompletionItem> findAllVersions(@NotNull MavenCoordinate template, @NotNull SearchParameters parameters) {
|
||||
return doQuery(parameters, template, (p, s) -> p.findAllVersions(s, parameters), VERSION_COLLECTOR);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<MavenDependencyCompletionItemWithClass> findClasses(@NotNull String className) {
|
||||
return findClasses(className, SearchParameters.DEFAULT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<MavenDependencyCompletionItemWithClass> findClasses(@NotNull String className, @NotNull SearchParameters parameters) {
|
||||
return doQuery(parameters, className, (p, s) -> p.findClassesByString(s, parameters), VERSION_COLLECTOR);
|
||||
}
|
||||
|
||||
private <PARAM, RESULT extends MavenDependencyCompletionItem> List<RESULT> doQuery(@NotNull SearchParameters parameters,
|
||||
PARAM template,
|
||||
ThrowingSearch<PARAM, RESULT> search,
|
||||
Collector<? super List<RESULT>, ?, List<RESULT>> collector) {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
|
||||
return myProviders
|
||||
.stream().map(provider -> application.executeOnPooledThread(
|
||||
() -> search.search(provider, template)))
|
||||
.map(f -> {
|
||||
try {
|
||||
return f.get(parameters.getMillisToWait(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||
if (application.isInternal()) {
|
||||
MavenLog.LOG.error(e);
|
||||
}
|
||||
else {
|
||||
MavenLog.LOG.debug(e);
|
||||
}
|
||||
return Collections.<RESULT>emptyList();
|
||||
}
|
||||
}).collect(collector);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface ThrowingSearch<PARAM, RESULT extends MavenDependencyCompletionItem> {
|
||||
List<RESULT> search(DependencyCompletionProvider p, PARAM t) throws IOException;
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public List<DependencyCompletionProvider> getProviders() {
|
||||
return myProviders;
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
// 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.onlinecompletion;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
||||
import org.apache.lucene.queryParser.ParseException;
|
||||
import org.apache.lucene.queryParser.QueryParser;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.indices.MavenSearchIndex;
|
||||
import org.jetbrains.idea.maven.indices.MavenIndex;
|
||||
import org.jetbrains.idea.maven.model.MavenCoordinate;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItemWithClass;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters;
|
||||
import org.jetbrains.idea.maven.utils.MavenLog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* This class is used as a solution to support completion from repositories, which do not support online completion
|
||||
*/
|
||||
public class IndexBasedSearchService implements DependencyCompletionProvider {
|
||||
|
||||
private final MavenIndex myIndex;
|
||||
|
||||
public IndexBasedSearchService(MavenIndex index) {myIndex = index;}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItem> findGroupCandidates(MavenCoordinate template, SearchParameters parameters) throws IOException {
|
||||
return ContainerUtil.map(myIndex.getGroupIds(), g -> new MavenDependencyCompletionItem(g, MavenDependencyCompletionItem.Type.REMOTE));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItem> findArtifactCandidates(MavenCoordinate template, SearchParameters parameters) throws IOException {
|
||||
return ContainerUtil.map(myIndex.getArtifactIds(template.getGroupId()), a ->
|
||||
new MavenDependencyCompletionItem(template.getGroupId(), a, null, MavenDependencyCompletionItem.Type.REMOTE));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItem> findAllVersions(MavenCoordinate template, SearchParameters parameters) throws IOException {
|
||||
return ContainerUtil.map(myIndex.getVersions(template.getGroupId(), template.getArtifactId()), v ->
|
||||
new MavenDependencyCompletionItem(template.getGroupId(), template.getArtifactId(), v, MavenDependencyCompletionItem.Type.REMOTE));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItemWithClass> findClassesByString(@NotNull String str, SearchParameters parameters) {
|
||||
if (StringUtil.isEmpty(str)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Query searchQuery = null;
|
||||
try {
|
||||
searchQuery = createSearchQuery(str);
|
||||
}
|
||||
catch (ParseException e) {
|
||||
MavenLog.LOG.debug(e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return ContainerUtil.map(myIndex.search(searchQuery, parameters.getMaxResults()),
|
||||
r -> new MavenDependencyCompletionItemWithClass(r.getGroupId(), r.getArtifactId(), r.getVersion(),
|
||||
MavenDependencyCompletionItem.Type.LOCAL,
|
||||
Collections.singletonList(r.getClassNames())));
|
||||
}
|
||||
|
||||
private static Query createSearchQuery(@NotNull String str) throws ParseException {
|
||||
String[] patterns = str.split("\\.");
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < patterns.length; i++) {
|
||||
builder.append("c:").append(patterns[i]).append(" OR ");
|
||||
}
|
||||
|
||||
builder.append("fc:").append(str);
|
||||
return new QueryParser("c", new StandardAnalyzer()).parse(builder.toString());
|
||||
}
|
||||
|
||||
public MavenSearchIndex getIndex() {
|
||||
return myIndex;
|
||||
}
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
// 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.onlinecompletion;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.model.MavenCoordinate;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItemWithClass;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem.Type.CACHED_ERROR;
|
||||
import static org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem.Type.LOCAL;
|
||||
|
||||
public class LocalCompletionSearch implements DependencyCompletionProvider {
|
||||
private final Path myLocalRepo;
|
||||
|
||||
private static final PathMatcher groupMatcher = FileSystems.getDefault().getPathMatcher("glob:**/*/*");
|
||||
private static final PathMatcher pomMatcher = FileSystems.getDefault().getPathMatcher("glob:**/*.pom");
|
||||
private static final PathMatcher errorUpdatedMatcher = FileSystems.getDefault().getPathMatcher("glob:**/*.lastUpdated");
|
||||
private static final PathMatcher versionMatcher = FileSystems.getDefault().getPathMatcher("glob:**/*.*");
|
||||
|
||||
public LocalCompletionSearch(File localRepo) {
|
||||
myLocalRepo = localRepo.toPath();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItem> findGroupCandidates(MavenCoordinate template, SearchParameters parameters) throws IOException {
|
||||
Set<String> collected = new HashSet<>();
|
||||
Files.walkFileTree(myLocalRepo, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
boolean isVersion = versionMatcher.matches(file);
|
||||
if (isVersion && attrs.isDirectory()) {
|
||||
String parentRelativePath = myLocalRepo.relativize(file.getParent().getParent()).toString();
|
||||
collected.add(parentRelativePath.replace(File.separatorChar, '.'));
|
||||
return FileVisitResult.SKIP_SUBTREE;
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
if (parameters.getFlags().contains(SearchParameters.Flags.FULL_RESOLVE)) {
|
||||
return collected.stream().flatMap(
|
||||
g -> {
|
||||
try {
|
||||
return findArtifactCandidates(new MavenDependencyCompletionItem(g, LOCAL), parameters).stream();
|
||||
}
|
||||
catch (IOException e) {
|
||||
return Stream.empty();
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
return ContainerUtil.map(collected, g -> new MavenDependencyCompletionItem(g, LOCAL));
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItem> findArtifactCandidates(MavenCoordinate template, SearchParameters parameters)
|
||||
throws IOException {
|
||||
if (template.getGroupId() == null || template.getGroupId().isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
File[] files = myLocalRepo.resolve(template.getGroupId().replace('.', File.separatorChar)).toFile().listFiles();
|
||||
if (files == null || files.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (parameters.getFlags().contains(SearchParameters.Flags.FULL_RESOLVE)) {
|
||||
return Arrays.stream(files).flatMap(
|
||||
f -> {
|
||||
try {
|
||||
return findAllVersions(new MavenDependencyCompletionItem(template.getGroupId(), f.getName(), null, LOCAL), parameters).stream();
|
||||
}
|
||||
catch (IOException e) {
|
||||
return Stream.empty();
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
return ContainerUtil.map(files, f -> new MavenDependencyCompletionItem(template.getGroupId(), f.getName(), null, LOCAL));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItem> findAllVersions(MavenCoordinate template, SearchParameters parameters) throws IOException {
|
||||
if (template.getGroupId() == null || template.getGroupId().isEmpty()
|
||||
|| template.getArtifactId() == null || template.getArtifactId().isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Path artifactDir = myLocalRepo.resolve(template.getGroupId().replace('.', File.separatorChar)).resolve(template.getArtifactId());
|
||||
if (!artifactDir.toFile().exists()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<MavenDependencyCompletionItem> result = new ArrayList<>();
|
||||
Files.walkFileTree(artifactDir, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
Path versionDir = file.getParent();
|
||||
String version = versionDir.toFile().getName();
|
||||
if (errorUpdatedMatcher.matches(file) && attrs.isRegularFile()) {
|
||||
result.add(new MavenDependencyCompletionItem(template.getGroupId(), template.getArtifactId(), version, CACHED_ERROR));
|
||||
return FileVisitResult.SKIP_SIBLINGS;
|
||||
}
|
||||
if (pomMatcher.matches(file) && attrs.isRegularFile()) {
|
||||
result.add(new MavenDependencyCompletionItem(template.getGroupId(), template.getArtifactId(), version, LOCAL));
|
||||
return FileVisitResult.SKIP_SIBLINGS;
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItemWithClass> findClassesByString(String str, SearchParameters parameters) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
LocalCompletionSearch search = (LocalCompletionSearch)o;
|
||||
return FileUtil.filesEqual(myLocalRepo.toFile(), search.myLocalRepo.toFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return FileUtil.fileHashCode(myLocalRepo.toFile());
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// 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.onlinecompletion;
|
||||
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
|
||||
public final class MavenScopeTable {
|
||||
|
||||
|
||||
private MavenScopeTable() {}
|
||||
|
||||
public static String getUsualScope(MavenDependencyCompletionItem item) {
|
||||
String groupId = item.getGroupId();
|
||||
if (groupId == null) {
|
||||
return null;
|
||||
}
|
||||
if (groupId.contains("junit") || groupId.equals("org.mockito") || groupId.equals("org.hamcrest")) {
|
||||
return "test";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
// 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.onlinecompletion.central;
|
||||
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItemWithClass;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MavenCentralModel {
|
||||
|
||||
public ResponseHeader responseHeader;
|
||||
public Response response;
|
||||
|
||||
public Highlighting highlighting;
|
||||
|
||||
|
||||
public static class ResponseHeader {
|
||||
public int status;
|
||||
}
|
||||
|
||||
public static class Response {
|
||||
public int numFound;
|
||||
public int start;
|
||||
public FoundDoc[] docs;
|
||||
public Highlighting highlighting;
|
||||
|
||||
public static class FoundDoc {
|
||||
public String id;
|
||||
public String g; //group
|
||||
public String a; //artifactId
|
||||
public String v; //version
|
||||
public String latestVersion;
|
||||
public String repositoryId;
|
||||
public String p; //packaging
|
||||
public int versionCount;
|
||||
public long timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Highlighting {
|
||||
public List<MavenDependencyCompletionItemWithClass> results;
|
||||
}
|
||||
|
||||
public static class HighlightingDeserializer implements JsonDeserializer<Highlighting> {
|
||||
|
||||
@Override
|
||||
public Highlighting deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
Highlighting result = new Highlighting();
|
||||
result.results = ContainerUtil.newArrayListWithCapacity(object.size());
|
||||
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
|
||||
JsonArray fch = entry.getValue().getAsJsonObject().get("fch").getAsJsonArray();
|
||||
String[] hightlights = new String[fch.size()];
|
||||
|
||||
for (int i = 0; i < hightlights.length; i++) {
|
||||
hightlights[i] = clearEM(fch.get(i).getAsString());
|
||||
}
|
||||
result.results.add(new MavenDependencyCompletionItemWithClass(entry.getKey(), MavenDependencyCompletionItem.Type.REMOTE,
|
||||
ContainerUtil.newArrayList(hightlights)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String clearEM(String string) {
|
||||
return string.replaceAll("<em>", "").replaceAll("</em>", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
// 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.onlinecompletion.central;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.io.HttpRequests;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.maven.model.MavenCoordinate;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.DependencyCompletionProvider;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItemWithClass;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters.Flags.ALL_VERSIONS;
|
||||
|
||||
public class MavenCentralOnlineSearch implements DependencyCompletionProvider {
|
||||
private static final String DEFAULT_SEARCH_URI = "https://search.maven.org/solrsearch/select?q=";
|
||||
private final static int MIN_LENGTH = 2;
|
||||
|
||||
private final Gson myGson;
|
||||
private final String mySearchUrl;
|
||||
public static final String UTF8 = StandardCharsets.UTF_8.toString();
|
||||
|
||||
public MavenCentralOnlineSearch() {
|
||||
myGson = new GsonBuilder()
|
||||
.registerTypeAdapter(MavenCentralModel.Highlighting.class, new MavenCentralModel.HighlightingDeserializer())
|
||||
.create();
|
||||
mySearchUrl = DEFAULT_SEARCH_URI;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return "Maven Central";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItem> findGroupCandidates(MavenCoordinate template, SearchParameters parameters) throws IOException {
|
||||
if (StringUtil.isEmpty(template.getGroupId())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String param = join(StringUtil.split(template.getGroupId(), "."));
|
||||
if (param.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String uri = createSearchUrl(param, parameters);
|
||||
return convert(doRequest(uri));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItem> findArtifactCandidates(@NotNull MavenCoordinate template, SearchParameters parameters)
|
||||
throws IOException {
|
||||
if (template.getGroupId() == null) {
|
||||
return findGroupCandidates(new MavenDependencyCompletionItem(template.getArtifactId()), parameters);
|
||||
}
|
||||
|
||||
String param = template.getArtifactId() == null
|
||||
? template.getGroupId()
|
||||
: template.getGroupId() + join(StringUtil.split(template.getArtifactId(), "-"));
|
||||
//we cannot query with GAV for maven search
|
||||
EnumSet<SearchParameters.Flags> newFlags = parameters.getFlags().clone();
|
||||
newFlags.remove(ALL_VERSIONS);
|
||||
SearchParameters newParameters = new SearchParameters(parameters.getMaxResults(), parameters.getMillisToWait(), newFlags);
|
||||
|
||||
String uri = createSearchUrl(param, newParameters);
|
||||
return convert(doRequest(uri));
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItem> findAllVersions(MavenCoordinate template, SearchParameters parameters) throws IOException {
|
||||
if (template.getArtifactId() == null) {
|
||||
return findArtifactCandidates(template, parameters);
|
||||
}
|
||||
String uri = createSearchUrl("g:\"" + template.getGroupId() + "\" AND a:\"" + template.getArtifactId() + "\"", parameters);
|
||||
return convert(doRequest(uri));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<MavenDependencyCompletionItemWithClass> findClassesByString(String str, SearchParameters parameters) throws IOException {
|
||||
String uri = createSearchUrl(createSearchQuery(str), parameters);
|
||||
MavenCentralModel model = doRequest(uri);
|
||||
if (model == null || model.highlighting == null || model.highlighting.results == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return model.highlighting.results;
|
||||
}
|
||||
|
||||
private static String createSearchQuery(@NotNull String str) {
|
||||
String[] patterns = str.split("\\.");
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < patterns.length; i++) {
|
||||
builder.append("c:").append("\"").append(patterns[i]).append("\"").append(" OR ");
|
||||
}
|
||||
|
||||
builder.append("fc:").append(str);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private MavenCentralModel doRequest(String uri) throws IOException {
|
||||
if (uri == null) {
|
||||
return null;
|
||||
}
|
||||
ProgressManager.checkCanceled();
|
||||
return HttpRequests.request(uri)
|
||||
.productNameAsUserAgent()
|
||||
.forceHttps(false)
|
||||
.connect(request -> {
|
||||
try {
|
||||
String s = request.readString(null);
|
||||
return myGson.fromJson(s, MavenCentralModel.class);
|
||||
}
|
||||
catch (HttpRequests.HttpStatusException ignored) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static String join(List<String> splitted) {
|
||||
if(splitted.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for (String value : splitted) {
|
||||
if (value.length() >= MIN_LENGTH) builder.append(value);
|
||||
builder.append(' ');
|
||||
}
|
||||
if (builder.charAt(builder.length() - 1) == ' ') builder.deleteCharAt(builder.length() - 1);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private static List<MavenDependencyCompletionItem> convert(MavenCentralModel model) {
|
||||
if (model == null ||
|
||||
model.responseHeader.status != 0 ||
|
||||
model.response == null ||
|
||||
model.response.docs == null ||
|
||||
model.response.docs.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<MavenDependencyCompletionItem> result = new ArrayList<>();
|
||||
for (MavenCentralModel.Response.FoundDoc doc : model.response.docs) {
|
||||
MavenDependencyCompletionItem description = new MavenDependencyCompletionItem(
|
||||
doc.g,
|
||||
doc.a,
|
||||
doc.v == null ? doc.latestVersion : doc.v,
|
||||
doc.p,
|
||||
null,
|
||||
MavenDependencyCompletionItem.Type.REMOTE);
|
||||
result.add(description);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private String createSearchUrl(String queryParam, SearchParameters parameters) {
|
||||
int rows = parameters.getMaxResults() < 20 ? 20 : parameters.getMaxResults();
|
||||
String gav = parameters.getFlags().contains(ALL_VERSIONS) ? "&core=gav" : "";
|
||||
try {
|
||||
return mySearchUrl + URLEncoder.encode(queryParam, UTF8) + "&rows=" + rows + "&wt=json" + gav;
|
||||
}
|
||||
catch (UnsupportedEncodingException neverHappens) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
MavenCentralOnlineSearch search = (MavenCentralOnlineSearch)o;
|
||||
return Objects.equals(mySearchUrl, search.mySearchUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mySearchUrl);
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
// 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.onlinecompletion.model;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.maven.model.MavenId;
|
||||
|
||||
public class MavenDependencyCompletionItem extends MavenId {
|
||||
|
||||
private final Type myType;
|
||||
|
||||
private final String packaging;
|
||||
private final String classifier;
|
||||
|
||||
public enum Type {
|
||||
REMOTE(10), LOCAL(20), CACHED_ERROR(-1);
|
||||
|
||||
private final int myWeight;
|
||||
|
||||
Type(int weight) {myWeight = weight;}
|
||||
|
||||
public int getWeight() {
|
||||
return myWeight;
|
||||
}
|
||||
}
|
||||
|
||||
public MavenDependencyCompletionItem(@Nullable String groupId,
|
||||
@Nullable String artifactId,
|
||||
@Nullable String version,
|
||||
@Nullable String packaging,
|
||||
@Nullable String classifier,
|
||||
@Nullable Type type) {
|
||||
super(groupId, artifactId, version);
|
||||
myType = type;
|
||||
this.packaging = packaging;
|
||||
this.classifier = classifier;
|
||||
}
|
||||
|
||||
public MavenDependencyCompletionItem(@Nullable String groupId,
|
||||
@Nullable String artifactId,
|
||||
@Nullable String version,
|
||||
@Nullable Type type) {
|
||||
this(groupId, artifactId, version, null, null, type);
|
||||
}
|
||||
|
||||
public MavenDependencyCompletionItem(@Nullable String groupId,
|
||||
@Nullable String artifactId,
|
||||
@Nullable String version) {
|
||||
this(groupId, artifactId, version, null, null, null);
|
||||
}
|
||||
|
||||
public MavenDependencyCompletionItem(@Nullable String coord, @Nullable Type type) {
|
||||
super(coord);
|
||||
packaging = null;
|
||||
classifier = null;
|
||||
myType = type;
|
||||
}
|
||||
|
||||
public MavenDependencyCompletionItem(@Nullable String coord) {
|
||||
this(coord, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Type getType() {
|
||||
return myType;
|
||||
}
|
||||
|
||||
|
||||
public String getPackaging() {
|
||||
return packaging;
|
||||
}
|
||||
|
||||
public String getClassifier() {
|
||||
return classifier;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// 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.onlinecompletion.model;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class MavenDependencyCompletionItemWithClass extends MavenDependencyCompletionItem {
|
||||
|
||||
private final Collection<String> myNames;
|
||||
|
||||
public MavenDependencyCompletionItemWithClass(@Nullable String groupId,
|
||||
@Nullable String artifactId,
|
||||
@Nullable String version,
|
||||
@Nullable Type type,
|
||||
Collection<String> klassNames) {
|
||||
super(groupId, artifactId, version, type);
|
||||
myNames = klassNames;
|
||||
}
|
||||
|
||||
public MavenDependencyCompletionItemWithClass(@Nullable String coord,
|
||||
@Nullable Type type,
|
||||
Collection<String> klassNames) {
|
||||
super(coord, type);
|
||||
myNames = klassNames;
|
||||
}
|
||||
|
||||
public Collection<String> getNames() {
|
||||
return Collections.unmodifiableCollection(myNames);
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// 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.onlinecompletion.model;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class SearchParameters {
|
||||
|
||||
public enum Flags {
|
||||
ALL_VERSIONS("requesting all versions"),
|
||||
FULL_RESOLVE("should not return partially resolved artifacts"),
|
||||
NOT_DEDUPLICATE("Deduplication will not be called");
|
||||
|
||||
Flags(String desc) {}
|
||||
}
|
||||
|
||||
public static final SearchParameters DEFAULT = new SearchParameters(20, 500, EnumSet.noneOf(Flags.class));
|
||||
private final int maxResults;
|
||||
private final long millisToWait;
|
||||
private final EnumSet<Flags> myFlags;
|
||||
|
||||
|
||||
public SearchParameters(int maxResults, long wait, EnumSet<Flags> flags) {
|
||||
this.maxResults = maxResults;
|
||||
millisToWait = wait;
|
||||
myFlags = flags;
|
||||
}
|
||||
|
||||
public int getMaxResults() {
|
||||
return maxResults;
|
||||
}
|
||||
|
||||
|
||||
public long getMillisToWait() {
|
||||
return millisToWait;
|
||||
}
|
||||
|
||||
public EnumSet<Flags> getFlags() {
|
||||
return EnumSet.copyOf(myFlags);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ maven.index.type=Type
|
||||
maven.index.updated=Updated
|
||||
maven.index.updated.never=Never
|
||||
maven.index.updated.error=Error
|
||||
maven.index.updated.notapplicable=N/A
|
||||
maven.indices.updating=Updating Maven Repository Indices...
|
||||
maven.indices.updating.index=Updating [{0}] {1}
|
||||
repository.plugin.corrupt={0} not a Maven 2 plugin file
|
||||
|
||||
@@ -151,6 +151,9 @@
|
||||
<completion.contributor language="XML"
|
||||
implementationClass="org.jetbrains.idea.maven.dom.model.completion.MavenDependenciesCompletionProvider"/>
|
||||
|
||||
<completion.contributor language="XML"
|
||||
implementationClass="org.jetbrains.idea.maven.dom.model.completion.MavenArtifactCompletionContributor"/>
|
||||
|
||||
<psi.referenceContributor implementation="org.jetbrains.idea.maven.dom.references.MavenPropertyPsiReferenceContributor"/>
|
||||
|
||||
<psi.referenceContributor language="XML" implementation="org.jetbrains.idea.maven.plugins.api.MavenPluginParamReferenceContributor"/>
|
||||
|
||||
-8
@@ -18,7 +18,6 @@ package org.jetbrains.idea.maven.dom;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import org.jetbrains.idea.maven.indices.MavenIndex;
|
||||
import org.jetbrains.idea.maven.indices.MavenIndicesTestFixture;
|
||||
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
|
||||
@@ -81,13 +80,6 @@ public class MavenExtensionCompletionAndResolutionTest extends MavenDomWithIndic
|
||||
MavenProjectIndicesManager instance = MavenProjectIndicesManager.getInstance(myProject);
|
||||
System.out.println("GetArtifacts: " + new HashSet<>(instance.getArtifactIds("org.apache.maven.plugins")));
|
||||
System.out.println("Indexes: " + instance.getIndices());
|
||||
|
||||
for (MavenIndex index : instance.getIndices()) {
|
||||
System.out.println("Index: repositoryId=" + index.getRepositoryId() + " repositoryUrl=" + index.getRepositoryUrl() + " repositoryPathOrUrl" + index.getRepositoryPathOrUrl());
|
||||
System.out.println("Dir: " + index.getDir());
|
||||
index.printInfo();
|
||||
}
|
||||
|
||||
throw new AssertionError("GetArtifacts: " + instance.getArtifactIds("org.apache.maven.plugins") + " Indexes: " + instance.getIndices());
|
||||
}
|
||||
}
|
||||
|
||||
+7
-28
@@ -49,40 +49,19 @@ public class MavenIndicesManagerTest extends MavenIndicesTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testEnsuringLocalRepositoryIndex() {
|
||||
File dir1 = myIndicesFixture.getRepositoryHelper().getTestData("dir/foo");
|
||||
File dir2 = myIndicesFixture.getRepositoryHelper().getTestData("dir\\foo");
|
||||
File dir3 = myIndicesFixture.getRepositoryHelper().getTestData("dir\\foo\\");
|
||||
File dir4 = myIndicesFixture.getRepositoryHelper().getTestData("dir/bar");
|
||||
|
||||
List<MavenIndex> indices1 = myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, dir1,
|
||||
Collections.emptyList());
|
||||
assertEquals(1, indices1.size());
|
||||
assertTrue(myIndicesFixture.getIndicesManager().getIndices().contains(indices1.get(0)));
|
||||
|
||||
assertEquals(indices1, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, dir2,
|
||||
Collections.emptyList()));
|
||||
assertEquals(indices1, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, dir3,
|
||||
Collections.emptyList()));
|
||||
|
||||
List<MavenIndex> indices2 = myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, dir4,
|
||||
Collections.emptyList());
|
||||
assertFalse(indices1.get(0).equals(indices2.get(0)));
|
||||
}
|
||||
|
||||
public void testEnsuringRemoteRepositoryIndex() {
|
||||
File local = myIndicesFixture.getRepositoryHelper().getTestData("dir");
|
||||
Pair<String, String> remote1 = Pair.create("id1", "http://foo/bar");
|
||||
Pair<String, String> remote2 = Pair.create("id1", " http://foo\\bar\\\\ ");
|
||||
Pair<String, String> remote3 = Pair.create("id3", "http://foo\\bar\\baz");
|
||||
Pair<String, String> remote4 = Pair.create("id4", "http://foo/bar"); // same url
|
||||
Pair<String, String> remote5 = Pair.create("id4", "http://foo/baz"); // same id
|
||||
|
||||
assertEquals(2, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, local, Collections.singleton(remote1)).size());
|
||||
assertEquals(2, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, local, asList(remote1, remote2)).size());
|
||||
assertEquals(3, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, local, asList(remote1, remote2, remote3)).size());
|
||||
assertEquals(3, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, local, asList(remote1, remote2, remote3, remote4)).size());
|
||||
assertEquals(4, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, local, asList(remote1, remote2, remote3, remote4, remote5)).size());
|
||||
assertEquals(2, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, Collections.singleton(remote1)).size());
|
||||
assertEquals(2, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, asList(remote1, remote2)).size());
|
||||
assertEquals(3, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, asList(remote1, remote2, remote3)).size());
|
||||
assertEquals(3, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, asList(remote1, remote2, remote3, remote4)).size());
|
||||
assertEquals(4, myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, asList(remote1, remote2, remote3, remote4, remote5)).size());
|
||||
}
|
||||
|
||||
public void testDefaultArchetypes() {
|
||||
@@ -91,7 +70,7 @@ public class MavenIndicesManagerTest extends MavenIndicesTestCase {
|
||||
|
||||
public void testIndexedArchetypes() throws Exception {
|
||||
myIndicesFixture.getRepositoryHelper().addTestData("archetypes");
|
||||
myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, myIndicesFixture.getRepositoryHelper().getTestData("archetypes"),
|
||||
myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject,
|
||||
Collections.emptyList());
|
||||
|
||||
assertArchetypeExists("org.apache.maven.archetypes:maven-archetype-foobar:1.0");
|
||||
@@ -99,7 +78,7 @@ public class MavenIndicesManagerTest extends MavenIndicesTestCase {
|
||||
|
||||
public void testIndexedArchetypesWithSeveralIndicesAfterReopening() throws Exception {
|
||||
myIndicesFixture.getRepositoryHelper().addTestData("archetypes");
|
||||
myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject, myIndicesFixture.getRepositoryHelper().getTestData("archetypes"),
|
||||
myIndicesFixture.getIndicesManager().ensureIndicesExist(myProject,
|
||||
Collections.singleton(Pair.create("id", "foo://bar.baz")));
|
||||
|
||||
assertArchetypeExists("org.apache.maven.archetypes:maven-archetype-foobar:1.0");
|
||||
|
||||
@@ -1,487 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.WildcardQuery;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.MavenCustomRepositoryHelper;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifactInfo;
|
||||
import org.jetbrains.idea.maven.server.MavenIndexerWrapper;
|
||||
import org.jetbrains.idea.maven.server.MavenServerIndexer;
|
||||
import org.jetbrains.idea.maven.server.MavenServerManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MavenIndicesTest extends MavenIndicesTestCase {
|
||||
private MavenCustomRepositoryHelper myRepositoryHelper;
|
||||
private MavenIndices myIndices;
|
||||
private MavenIndexerWrapper myIndexer;
|
||||
private File myIndicesDir;
|
||||
private boolean isBroken;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
updateSettingsXmlFully("<settings>" +
|
||||
" <mirrors>" +
|
||||
" </mirrors>" +
|
||||
"</settings>");
|
||||
|
||||
myRepositoryHelper = new MavenCustomRepositoryHelper(myDir, "local1", "local2", "remote");
|
||||
initIndices();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
try {
|
||||
shutdownIndices();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
addSuppressedException(e);
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
private void initIndices() {
|
||||
initIndices("indices");
|
||||
}
|
||||
|
||||
private void initIndices(String relativeDir) {
|
||||
if (myIndices != null) {
|
||||
try {
|
||||
shutdownIndices();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
myIndexer = MavenServerManager.getInstance().createIndexer();
|
||||
myIndicesDir = new File(myDir, relativeDir);
|
||||
myIndices = new MavenIndices(myIndexer, myIndicesDir, new MavenIndex.IndexListener() {
|
||||
@Override
|
||||
public void indexIsBroken(@NotNull MavenIndex index) {
|
||||
isBroken = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void shutdownIndices() {
|
||||
myIndices.close();
|
||||
myIndexer.releaseInTests();
|
||||
}
|
||||
|
||||
private static void assertSearchResults(MavenIndex i, Query query, String... expectedArtifacts) {
|
||||
List<String> actualArtifacts = new ArrayList<>();
|
||||
for (MavenArtifactInfo each : i.search(query, 100)) {
|
||||
actualArtifacts.add(each.getGroupId() + ":" + each.getArtifactId() + ":" + each.getVersion());
|
||||
}
|
||||
assertUnorderedElementsAreEqual(actualArtifacts, expectedArtifacts);
|
||||
}
|
||||
|
||||
public void testCreatingAndUpdatingLocalWhenNoDirectory() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("do_not_exist"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertUnorderedElementsAreEqual(i.getGroupIds());
|
||||
}
|
||||
|
||||
public void testCreatingSeveral() throws Exception {
|
||||
MavenIndex i1 = myIndices.add("id1", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndex i2 = myIndices.add("id2", myRepositoryHelper.getTestDataPath("local2"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i1, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
MavenIndices.updateOrRepair(i2, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertUnorderedElementsAreEqual(i1.getGroupIds(), "junit", "asm", "commons-io", "org.ow2.asm");
|
||||
assertUnorderedElementsAreEqual(i2.getGroupIds(), "jmock");
|
||||
}
|
||||
|
||||
public void testCreatingSeveralWithSameIdAndDifferentUrl() throws Exception {
|
||||
MavenIndex i1 = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndex i2 = myIndices.add("id", myRepositoryHelper.getTestDataPath("local2"), MavenIndex.Kind.LOCAL);
|
||||
assertNotSame(i1, i2);
|
||||
MavenIndices.updateOrRepair(i1, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
MavenIndices.updateOrRepair(i2, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertUnorderedElementsAreEqual(i1.getGroupIds(), "junit", "asm", "commons-io", "org.ow2.asm");
|
||||
assertUnorderedElementsAreEqual(i2.getGroupIds(), "jmock");
|
||||
}
|
||||
|
||||
public void testCreatingSeveralWithDifferentIdAndSameUrl() throws Exception {
|
||||
MavenIndex i1 = myIndices.add("id1", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndex i2 = myIndices.add("id2", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
assertSame(i1, i2);
|
||||
MavenIndices.updateOrRepair(i1, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
MavenIndices.updateOrRepair(i2, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertUnorderedElementsAreEqual(i1.getGroupIds(), "junit", "asm", "commons-io", "org.ow2.asm");
|
||||
assertUnorderedElementsAreEqual(i2.getGroupIds(), "junit", "asm", "commons-io", "org.ow2.asm");
|
||||
}
|
||||
|
||||
public void testAddingWithoutUpdate() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
assertTrue(i.getGroupIds().isEmpty());
|
||||
}
|
||||
|
||||
public void testUpdatingLocalClearsPreviousIndex() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
assertUnorderedElementsAreEqual(i.getGroupIds(), "junit", "asm", "commons-io", "org.ow2.asm");
|
||||
|
||||
myRepositoryHelper.delete("local1");
|
||||
myRepositoryHelper.copy("local2", "local1");
|
||||
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
assertUnorderedElementsAreEqual(i.getGroupIds(), "jmock");
|
||||
}
|
||||
|
||||
public void testClearingUpdateDirAfterUpdate() {
|
||||
ignore();
|
||||
//MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
//
|
||||
//myIndices.updateOrRepair(i, myEmbedder, true, new EmptyProgressIndicator());
|
||||
//assertUnorderedElementsAreEqual(i.getGroupIds(), "junit");
|
||||
//
|
||||
//assertFalse(i.getUpdateDir().exists());
|
||||
}
|
||||
|
||||
public void testAddingRemote() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", "file:///" + myRepositoryHelper.getTestDataPath("remote"), MavenIndex.Kind.REMOTE);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertUnorderedElementsAreEqual(i.getGroupIds(), "junit");
|
||||
}
|
||||
|
||||
public void testUpdatingRemote() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", "file:///" + myRepositoryHelper.getTestDataPath("remote"), MavenIndex.Kind.REMOTE);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
//shouldn't throw 'The existing index is for repository [remote] and not for repository [xxx]'
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
assertUnorderedElementsAreEqual(i.getGroupIds(), "junit");
|
||||
}
|
||||
|
||||
public void testDoNotAddSameIndexTwice() throws Exception {
|
||||
MavenIndex local = myIndices.add("local", myRepositoryHelper.getTestDataPath("foo"), MavenIndex.Kind.LOCAL);
|
||||
|
||||
if (!SystemInfo.isFileSystemCaseSensitive) {
|
||||
assertSame(local, myIndices.add("local", myRepositoryHelper.getTestDataPath("FOO"), MavenIndex.Kind.LOCAL));
|
||||
}
|
||||
assertSame(local, myIndices.add("local", myRepositoryHelper.getTestDataPath("foo") + "/\\", MavenIndex.Kind.LOCAL));
|
||||
assertSame(local, myIndices.add("local", " " + myRepositoryHelper.getTestDataPath("foo") + " ", MavenIndex.Kind.LOCAL));
|
||||
|
||||
MavenIndex remote = myIndices.add("remote", "http://foo.bar", MavenIndex.Kind.REMOTE);
|
||||
|
||||
assertSame(remote, myIndices.add("remote", "HTTP://FOO.BAR", MavenIndex.Kind.REMOTE));
|
||||
assertSame(remote, myIndices.add("remote", "http://foo.bar/\\", MavenIndex.Kind.REMOTE));
|
||||
assertSame(remote, myIndices.add("remote", " http://foo.bar ", MavenIndex.Kind.REMOTE));
|
||||
}
|
||||
|
||||
public void testAddingInAbsenceOfParentDirectories() throws Exception {
|
||||
String subDir = "subDir1/subDir2/index";
|
||||
initIndices(subDir);
|
||||
myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
}
|
||||
|
||||
public void testAddingCorrectlyToIndexer() throws Exception {
|
||||
assertEquals(0, myIndexer.getIndexCount());
|
||||
|
||||
MavenIndex i1 = myIndices.add("local", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
assertEquals(1, myIndexer.getIndexCount());
|
||||
|
||||
MavenIndex i2 = myIndices.add("local", myRepositoryHelper.getTestDataPath("local2"), MavenIndex.Kind.LOCAL);
|
||||
assertEquals(2, myIndexer.getIndexCount());
|
||||
|
||||
MavenIndices.updateOrRepair(i1, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
assertEquals(2, myIndexer.getIndexCount());
|
||||
|
||||
MavenIndices.updateOrRepair(i2, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
assertEquals(2, myIndexer.getIndexCount());
|
||||
}
|
||||
|
||||
public void testClearingIndexDirOnLoadError() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local2"), MavenIndex.Kind.LOCAL);
|
||||
shutdownIndices();
|
||||
|
||||
FileWriter w = new FileWriter(new File(i.getDir(), MavenIndex.INDEX_INFO_FILE));
|
||||
w.write("bad content");
|
||||
w.close();
|
||||
|
||||
initIndices();
|
||||
|
||||
assertTrue(myIndices.getIndices().isEmpty());
|
||||
assertFalse(i.getDir().exists());
|
||||
}
|
||||
|
||||
public void testDoNotClearAlreadyLoadedIndexesOnLoadError() throws Exception {
|
||||
myIndices.add("id1", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndex i2 = myIndices.add("id2", myRepositoryHelper.getTestDataPath("local2"), MavenIndex.Kind.LOCAL);
|
||||
shutdownIndices();
|
||||
|
||||
FileWriter w = new FileWriter(new File(i2.getDir(), MavenIndex.INDEX_INFO_FILE));
|
||||
w.write("bad content");
|
||||
w.close();
|
||||
|
||||
initIndices();
|
||||
|
||||
assertEquals(1, myIndices.getIndices().size());
|
||||
assertEquals("local1", myIndices.getIndices().get(0).getRepositoryFile().getName());
|
||||
}
|
||||
|
||||
public void testLoadingIndexIfCachesAreBroken() throws Exception {
|
||||
MavenIndex i1 = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndex i2 = myIndices.add("id", myRepositoryHelper.getTestDataPath("local2"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i1, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
MavenIndices.updateOrRepair(i2, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertUnorderedElementsAreEqual(i1.getGroupIds(), "junit", "asm", "commons-io", "org.ow2.asm");
|
||||
assertUnorderedElementsAreEqual(i2.getGroupIds(), "jmock");
|
||||
|
||||
shutdownIndices();
|
||||
damageFile(i1, "artifactIds-map.dat", true);
|
||||
initIndices();
|
||||
|
||||
assertEquals(2, myIndices.getIndices().size());
|
||||
|
||||
assertTrue(myIndices.getIndices().get(0).getGroupIds().isEmpty());
|
||||
assertUnorderedElementsAreEqual(myIndices.getIndices().get(1).getGroupIds(), "jmock");
|
||||
|
||||
MavenIndices.updateOrRepair(myIndices.getIndices().get(0), false, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
assertUnorderedElementsAreEqual(myIndices.getIndices().get(0).getGroupIds(), "junit", "asm", "commons-io", "org.ow2.asm");
|
||||
}
|
||||
|
||||
public void testDoNotLoadSameIndexTwice() throws Exception {
|
||||
MavenIndex index = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
File dir = index.getDir();
|
||||
shutdownIndices();
|
||||
|
||||
File copy = new File(dir.getParentFile(), "ZZZ_INDEX_COPY");
|
||||
FileUtil.copyDir(dir, copy);
|
||||
|
||||
initIndices();
|
||||
|
||||
assertEquals(1, myIndices.getIndices().size());
|
||||
assertFalse(copy.exists());
|
||||
}
|
||||
|
||||
public void testAddingIndexWithExistingDirectoryDoesNotThrowException() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
shutdownIndices();
|
||||
|
||||
initIndices();
|
||||
i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
}
|
||||
|
||||
public void testIndicesAreValidAfterReopening() throws Exception {
|
||||
myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
shutdownIndices();
|
||||
initIndices();
|
||||
|
||||
assertFalse(isBroken);
|
||||
}
|
||||
|
||||
public void testSavingFailureMessage() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", "xxx", MavenIndex.Kind.REMOTE);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
String message = i.getFailureMessage();
|
||||
assertNotNull(message);
|
||||
|
||||
shutdownIndices();
|
||||
initIndices();
|
||||
|
||||
assertEquals(message, myIndices.getIndices().get(0).getFailureMessage());
|
||||
}
|
||||
|
||||
public void testRepairingIndicesOnReadError() throws Exception {
|
||||
MavenIndex index = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(index, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
shutdownIndices();
|
||||
damageFile(index, "artifactIds-map.dat", false);
|
||||
initIndices();
|
||||
|
||||
index = myIndices.getIndices().get(0);
|
||||
|
||||
index.getGroupIds();
|
||||
assertTrue(isBroken);
|
||||
|
||||
assertTrue(index.getGroupIds().isEmpty());
|
||||
|
||||
MavenIndices.updateOrRepair(myIndices.getIndices().get(0), false, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
assertUnorderedElementsAreEqual(index.getGroupIds(), "junit", "asm", "commons-io", "org.ow2.asm");
|
||||
}
|
||||
|
||||
public void testRepairingIndicesOnReadWhileAddingArtifact() throws Exception {
|
||||
MavenIndex index = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(index, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
shutdownIndices();
|
||||
damageFile(index, "artifactIds-map.dat", false);
|
||||
initIndices();
|
||||
|
||||
index = myIndices.getIndices().get(0);
|
||||
|
||||
index.addArtifact(null);
|
||||
assertTrue(isBroken);
|
||||
|
||||
assertTrue(index.getGroupIds().isEmpty());
|
||||
|
||||
MavenIndices.updateOrRepair(myIndices.getIndices().get(0), false, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
assertUnorderedElementsAreEqual(index.getGroupIds(), "junit", "asm", "commons-io", "org.ow2.asm");
|
||||
}
|
||||
|
||||
public void testCorrectlyClosingIndicesOnRemoteFacadeShutdown() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
MavenServerManager.getInstance().shutdown(true);
|
||||
initIndices();
|
||||
|
||||
i = myIndices.getIndices().get(0);
|
||||
|
||||
assertSearchResults(i, new WildcardQuery(new Term(MavenServerIndexer.SEARCH_TERM_CLASS_NAMES, "*junit*")),
|
||||
"junit:junit:3.8.1", "junit:junit:3.8.2", "junit:junit:4.0");
|
||||
}
|
||||
|
||||
public void testRestartingIndicesManagerOnRemoteMavenServerShutdown() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertSearchResults(i, new WildcardQuery(new Term(MavenServerIndexer.SEARCH_TERM_CLASS_NAMES, "*junit*")),
|
||||
"junit:junit:3.8.1", "junit:junit:3.8.2", "junit:junit:4.0");
|
||||
|
||||
MavenServerManager.getInstance().shutdown(true);
|
||||
|
||||
assertSearchResults(i, new WildcardQuery(new Term(MavenServerIndexer.SEARCH_TERM_CLASS_NAMES, "*junit*")),
|
||||
"junit:junit:3.8.1", "junit:junit:3.8.2", "junit:junit:4.0");
|
||||
}
|
||||
|
||||
private static void damageFile(MavenIndex index, String fileName, boolean fullDamage) throws IOException {
|
||||
File cachesDir = index.getCurrentDataDir();
|
||||
File file = new File(cachesDir, fileName);
|
||||
assertTrue(file.exists());
|
||||
|
||||
if (fullDamage) {
|
||||
FileWriter w = new FileWriter(file);
|
||||
w.write("bad content");
|
||||
w.close();
|
||||
}
|
||||
else {
|
||||
byte[] content = FileUtil.loadFileBytes(file);
|
||||
for (int i = 0; i < content.length; i+=2) {
|
||||
content[i] = -1;
|
||||
}
|
||||
FileUtil.writeToFile(file, content);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGettingArtifactInfos() throws Exception {
|
||||
myRepositoryHelper.copy("local2", "local1");
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertUnorderedElementsAreEqual(i.getGroupIds(), "junit", "jmock", "asm", "commons-io", "org.ow2.asm");
|
||||
|
||||
assertUnorderedElementsAreEqual(i.getArtifactIds("junit"), "junit");
|
||||
assertUnorderedElementsAreEqual(i.getArtifactIds("jmock"), "jmock");
|
||||
assertUnorderedElementsAreEqual(i.getArtifactIds("unknown"));
|
||||
|
||||
assertUnorderedElementsAreEqual(i.getVersions("junit", "junit"), "3.8.1", "3.8.2", "4.0");
|
||||
assertUnorderedElementsAreEqual(i.getVersions("junit", "jmock"));
|
||||
assertUnorderedElementsAreEqual(i.getVersions("unknown", "unknown"));
|
||||
}
|
||||
|
||||
public void testGettingArtifactInfosFromNotUpdatedRepositories() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
assertUnorderedElementsAreEqual(i.getGroupIds()); // shouldn't throw
|
||||
}
|
||||
|
||||
public void testGettingArtifactInfosAfterReload() throws Exception {
|
||||
MavenIndices.updateOrRepair(myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL),
|
||||
true,
|
||||
getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
shutdownIndices();
|
||||
initIndices();
|
||||
|
||||
assertUnorderedElementsAreEqual(myIndices.getIndices().get(0).getGroupIds(), "junit", "asm", "commons-io", "org.ow2.asm");
|
||||
}
|
||||
|
||||
public void testHasArtifactInfo() throws Exception {
|
||||
myRepositoryHelper.copy("local2", "local1");
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertTrue(i.hasGroupId("junit"));
|
||||
assertTrue(i.hasGroupId("jmock"));
|
||||
assertFalse(i.hasGroupId("xxx"));
|
||||
|
||||
assertTrue(i.hasArtifactId("junit", "junit"));
|
||||
assertTrue(i.hasArtifactId("jmock", "jmock"));
|
||||
assertFalse(i.hasArtifactId("junit", "jmock"));
|
||||
|
||||
assertTrue(i.hasVersion("junit", "junit", "4.0"));
|
||||
assertTrue(i.hasVersion("jmock", "jmock", "1.0.0"));
|
||||
assertFalse(i.hasVersion("junit", "junit", "666"));
|
||||
}
|
||||
|
||||
public void testSearching() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertSearchResults(i, new WildcardQuery(new Term(MavenServerIndexer.SEARCH_TERM_CLASS_NAMES, "*junit*")),
|
||||
"junit:junit:3.8.1", "junit:junit:3.8.2", "junit:junit:4.0");
|
||||
}
|
||||
|
||||
public void testSearchingAfterArtifactAddition() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
i.addArtifact(new File(myRepositoryHelper.getTestDataPath("local2/jmock/jmock/1.0.0/jmock-1.0.0.jar")));
|
||||
|
||||
assertSearchResults(i, new WildcardQuery(new Term(MavenServerIndexer.SEARCH_TERM_CLASS_NAMES, "*mock*")), "jmock:jmock:1.0.0");
|
||||
}
|
||||
|
||||
public void testSearchingForClasses() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
assertSearchResults(i, new WildcardQuery(new Term(MavenServerIndexer.SEARCH_TERM_CLASS_NAMES, "*runwith*")), "junit:junit:4.0");
|
||||
}
|
||||
|
||||
public void testSearchingForClassesAfterArtifactAddition() throws Exception {
|
||||
MavenIndex i = myIndices.add("id", myRepositoryHelper.getTestDataPath("local1"), MavenIndex.Kind.LOCAL);
|
||||
MavenIndices.updateOrRepair(i, true, getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS);
|
||||
|
||||
i.addArtifact(new File(myRepositoryHelper.getTestDataPath("local2/jmock/jmock/1.0.0/jmock-1.0.0.jar")));
|
||||
|
||||
assertSearchResults(i, new WildcardQuery(new Term(MavenServerIndexer.SEARCH_TERM_CLASS_NAMES, "*mock*")), "jmock:jmock:1.0.0");
|
||||
}
|
||||
}
|
||||
+10
-124
@@ -15,6 +15,10 @@
|
||||
*/
|
||||
package org.jetbrains.idea.maven.indices;
|
||||
|
||||
import org.jetbrains.idea.maven.onlinecompletion.DependencySearchService;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.LocalCompletionSearch;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.central.MavenCentralOnlineSearch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MavenProjectIndicesManagerTest extends MavenIndicesTestCase {
|
||||
@@ -45,139 +49,21 @@ public class MavenProjectIndicesManagerTest extends MavenIndicesTestCase {
|
||||
|
||||
assertEquals(1, indices.size());
|
||||
|
||||
assertEquals(MavenIndex.Kind.LOCAL, indices.get(0).getKind());
|
||||
assertEquals(MavenSearchIndex.Kind.LOCAL, indices.get(0).getKind());
|
||||
assertTrue(indices.get(0).getRepositoryPathOrUrl().endsWith("local1"));
|
||||
assertTrue(myIndicesFixture.getProjectIndicesManager().hasVersion("junit", "junit", "4.0"));
|
||||
}
|
||||
|
||||
public void testAutomaticallyAddRemoteRepositoriesOnProjectUpdate() {
|
||||
public void testAutomaticallyAddSearchService() {
|
||||
importProject("<groupId>test</groupId>" +
|
||||
"<artifactId>project</artifactId>" +
|
||||
"<version>1</version>");
|
||||
|
||||
List<MavenIndex> indices = myIndicesFixture.getProjectIndicesManager().getIndices();
|
||||
assertEquals(2, indices.size());
|
||||
DependencySearchService service = myIndicesFixture.getProjectIndicesManager().getSearchService();
|
||||
assertEquals(2, service.getProviders().size());
|
||||
|
||||
assertTrue(indices.get(0).getRepositoryPathOrUrl().endsWith("local1"));
|
||||
assertEquals("https://repo.maven.apache.org/maven2", indices.get(1).getRepositoryPathOrUrl());
|
||||
assertTrue(service.getProviders().get(0) instanceof LocalCompletionSearch);
|
||||
assertTrue(service.getProviders().get(1) instanceof MavenCentralOnlineSearch);
|
||||
}
|
||||
|
||||
public void testUpdatingIndicesOnResolution() {
|
||||
removeFromLocalRepository("junit/junit/4.0");
|
||||
myIndicesFixture.getProjectIndicesManager().scheduleUpdate(myIndicesFixture.getProjectIndicesManager().getIndices());
|
||||
|
||||
assertUnorderedElementsAreEqual(myIndicesFixture.getProjectIndicesManager().getVersions("junit", "junit"), "3.8.1", "3.8.2");
|
||||
|
||||
importProject("<groupId>test</groupId>" +
|
||||
"<artifactId>project</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
|
||||
"<dependencies>" +
|
||||
" <dependency>" +
|
||||
" <groupId>junit</groupId>" +
|
||||
" <artifactId>junit</artifactId>" +
|
||||
" <version>4.0</version>" +
|
||||
" </dependency>" +
|
||||
"</dependencies>");
|
||||
|
||||
assertUnorderedElementsAreEqual(myIndicesFixture.getProjectIndicesManager().getVersions("junit", "junit"), "3.8.1", "3.8.2", "4.0");
|
||||
}
|
||||
|
||||
public void testUpdatingIndexUsingMirrors() throws Exception {
|
||||
myIndicesFixture.tearDown();
|
||||
myIndicesFixture = new MavenIndicesTestFixture(myDir.toPath(), myProject, "local2", "remote_mirror");
|
||||
myIndicesFixture.setUp();
|
||||
|
||||
updateSettingsXmlFully("<settings>" +
|
||||
" <mirrors>" +
|
||||
" </mirrors>" +
|
||||
"</settings>");
|
||||
|
||||
importProject("<groupId>test</groupId>" +
|
||||
"<artifactId>project</artifactId>" +
|
||||
"<version>1</version>" +
|
||||
|
||||
"<repositories>" +
|
||||
" <repository>" +
|
||||
" <id>central</id>" +
|
||||
" <url>xxx://does.not.matter</url>" +
|
||||
" </repository>" +
|
||||
"</repositories>");
|
||||
|
||||
myIndicesFixture.getProjectIndicesManager().scheduleUpdateAll();
|
||||
assertUnorderedElementsAreEqual(myIndicesFixture.getProjectIndicesManager().getGroupIds(), "test", "jmock");
|
||||
|
||||
updateSettingsXmlFully("<settings>" +
|
||||
" <mirrors>" +
|
||||
" <mirror>" +
|
||||
" <id>nexus</id>" +
|
||||
" <mirrorOf>anotherRepoId</mirrorOf>" +
|
||||
" <url>file:///" + myIndicesFixture.getRepositoryHelper().getTestDataPath("remote_mirror") + "</url>" +
|
||||
" </mirror>" +
|
||||
" </mirrors>" +
|
||||
"</settings>");
|
||||
|
||||
myIndicesFixture.getProjectIndicesManager().scheduleUpdateAll();
|
||||
assertUnorderedElementsAreEqual(myIndicesFixture.getProjectIndicesManager().getGroupIds(), "test", "jmock");
|
||||
|
||||
updateSettingsXmlFully("<settings>" +
|
||||
" <mirrors>" +
|
||||
" <mirror>" +
|
||||
" <id>nexus</id>" +
|
||||
" <mirrorOf>central</mirrorOf>" +
|
||||
" <url>file:///" + myIndicesFixture.getRepositoryHelper().getTestDataPath("remote_mirror") + "</url>" +
|
||||
" </mirror>" +
|
||||
" </mirrors>" +
|
||||
"</settings>");
|
||||
|
||||
myIndicesFixture.getProjectIndicesManager().scheduleUpdateAll();
|
||||
assertUnorderedElementsAreEqual(myIndicesFixture.getProjectIndicesManager().getGroupIds(), "test", "jmock", "junit");
|
||||
|
||||
myIndicesFixture.tearDown();
|
||||
myIndicesFixture = new MavenIndicesTestFixture(myDir.toPath(), myProject, "local2", "remote_mirror");
|
||||
myIndicesFixture.setUp();
|
||||
|
||||
updateSettingsXmlFully("<settings>" +
|
||||
" <mirrors>" +
|
||||
" <mirror>" +
|
||||
" <id>nexus</id>" +
|
||||
" <mirrorOf>*</mirrorOf>" +
|
||||
" <url>file:///" + myIndicesFixture.getRepositoryHelper().getTestDataPath("remote_mirror") + "</url>" +
|
||||
" </mirror>" +
|
||||
" </mirrors>" +
|
||||
"</settings>");
|
||||
|
||||
myIndicesFixture.getProjectIndicesManager().scheduleUpdateAll();
|
||||
assertUnorderedElementsAreEqual(myIndicesFixture.getProjectIndicesManager().getGroupIds(), "test", "jmock", "junit");
|
||||
|
||||
}
|
||||
|
||||
public void testCheckingLocalRepositoryForAbsentIndices() throws Exception {
|
||||
myIndicesFixture.tearDown();
|
||||
myIndicesFixture = new MavenIndicesTestFixture(myDir.toPath(), myProject, "local2");
|
||||
myIndicesFixture.setUp();
|
||||
|
||||
myIndicesFixture.addToRepository("local1");
|
||||
|
||||
assertUnorderedElementsAreEqual(
|
||||
myIndicesFixture.getProjectIndicesManager().getGroupIds(), "jmock");
|
||||
|
||||
assertTrue(myIndicesFixture.getProjectIndicesManager().hasGroupId("junit"));
|
||||
assertFalse(myIndicesFixture.getProjectIndicesManager().hasGroupId("xxx"));
|
||||
|
||||
assertTrue(myIndicesFixture.getProjectIndicesManager().hasArtifactId("junit", "junit"));
|
||||
assertFalse(myIndicesFixture.getProjectIndicesManager().hasArtifactId("junit", "xxx"));
|
||||
assertFalse(myIndicesFixture.getProjectIndicesManager().hasArtifactId("xxx", "junit"));
|
||||
|
||||
assertTrue(myIndicesFixture.getProjectIndicesManager().hasVersion("junit", "junit", "4.0"));
|
||||
assertFalse(myIndicesFixture.getProjectIndicesManager().hasVersion("junit", "junit", "xxx"));
|
||||
assertFalse(myIndicesFixture.getProjectIndicesManager().hasVersion("junit", "xxx", "4.0"));
|
||||
assertFalse(myIndicesFixture.getProjectIndicesManager().hasVersion("xxx", "junit", "4.0"));
|
||||
//assertUnorderedElementsAreEqual(
|
||||
// myIndicesFixture.getProjectIndicesManager().getGroupIds(), "junit", "jmock");
|
||||
//assertUnorderedElementsAreEqual(
|
||||
// myIndicesFixture.getProjectIndicesManager().getArtifactIds("junit"), "junit");
|
||||
//assertUnorderedElementsAreEqual(
|
||||
// myIndicesFixture.getProjectIndicesManager().getVersions("junit", "junit"), "4.0");
|
||||
}
|
||||
}
|
||||
|
||||
+10
-5
@@ -15,11 +15,14 @@
|
||||
*/
|
||||
package org.jetbrains.idea.maven.indices;
|
||||
|
||||
import org.jetbrains.idea.maven.model.MavenArtifactInfo;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.junit.Ignore;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Ignore("tests for online search to be ready")
|
||||
public class MavenSearcherTest extends MavenIndicesTestCase {
|
||||
MavenIndicesTestFixture myIndicesFixture;
|
||||
|
||||
@@ -44,7 +47,8 @@ public class MavenSearcherTest extends MavenIndicesTestCase {
|
||||
}
|
||||
|
||||
public void testClassSearch() {
|
||||
assertTrue(!getClassSearchResults("").isEmpty());
|
||||
if(ignore()) return;
|
||||
assertTrue(getClassSearchResults("").isEmpty());
|
||||
|
||||
assertClassSearchResults("TestCas",
|
||||
"TestCase(junit.framework) junit:junit:4.0 junit:junit:3.8.2 junit:junit:3.8.1",
|
||||
@@ -95,6 +99,7 @@ public class MavenSearcherTest extends MavenIndicesTestCase {
|
||||
}
|
||||
|
||||
public void testArtifactSearch() {
|
||||
if(ignore()) return;
|
||||
assertArtifactSearchResults("",
|
||||
"asm:asm:3.3.1 asm:asm:3.3",
|
||||
"asm:asm-attrs:2.2.1",
|
||||
@@ -124,8 +129,8 @@ public class MavenSearcherTest extends MavenIndicesTestCase {
|
||||
private List<String> getClassSearchResults(String pattern) {
|
||||
List<String> actualArtifacts = new ArrayList<>();
|
||||
for (MavenClassSearchResult eachResult : new MavenClassSearcher().search(myProject, pattern, 100)) {
|
||||
StringBuilder s = new StringBuilder(eachResult.className + "(" + eachResult.packageName + ")");
|
||||
for (MavenArtifactInfo eachVersion : eachResult.versions) {
|
||||
StringBuilder s = new StringBuilder(eachResult.getClassName() + "(" + eachResult.getPackageName() + ")");
|
||||
for (MavenDependencyCompletionItem eachVersion : eachResult.getSearchResults()) {
|
||||
if (s.length() > 0) s.append(" ");
|
||||
s.append(eachVersion.getGroupId()).append(":").append(eachVersion.getArtifactId()).append(":").append(eachVersion.getVersion());
|
||||
}
|
||||
@@ -138,7 +143,7 @@ public class MavenSearcherTest extends MavenIndicesTestCase {
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (MavenArtifactSearchResult eachResult : new MavenArtifactSearcher().search(myProject, pattern, 100)) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (MavenArtifactInfo eachVersion : eachResult.versions) {
|
||||
for (MavenDependencyCompletionItem eachVersion : eachResult.getSearchResults()) {
|
||||
if (s.length() > 0) s.append(" ");
|
||||
s.append(eachVersion.getGroupId()).append(":").append(eachVersion.getArtifactId()).append(":").append(eachVersion.getVersion());
|
||||
}
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
// 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.onlinecompletion;
|
||||
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
public class DeduplicationCollectorTest extends UsefulTestCase {
|
||||
|
||||
public void testLocalBeforeRemote() {
|
||||
MavenDependencyCompletionItem local = new MavenDependencyCompletionItem("group:artifact:1", MavenDependencyCompletionItem.Type.LOCAL);
|
||||
MavenDependencyCompletionItem remote = new MavenDependencyCompletionItem("group:artifact:1", MavenDependencyCompletionItem.Type.REMOTE);
|
||||
Stream<List<MavenDependencyCompletionItem>> stream = Arrays.stream(new List[]{
|
||||
asList(local),
|
||||
asList(remote)}
|
||||
);
|
||||
|
||||
List<MavenDependencyCompletionItem> result = stream.collect(new DeduplicationCollector<>(m -> m.getDisplayString()));
|
||||
assertSize(1, result);
|
||||
assertEquals(MavenDependencyCompletionItem.Type.LOCAL, result.get(0).getType());
|
||||
}
|
||||
|
||||
public void testRemoteBeforeLocal() {
|
||||
MavenDependencyCompletionItem local = new MavenDependencyCompletionItem("group:artifact:1", MavenDependencyCompletionItem.Type.LOCAL);
|
||||
MavenDependencyCompletionItem remote = new MavenDependencyCompletionItem("group:artifact:1", MavenDependencyCompletionItem.Type.REMOTE);
|
||||
Stream<List<MavenDependencyCompletionItem>> stream = Arrays.stream(new List[]{
|
||||
asList(remote),
|
||||
asList(local)}
|
||||
);
|
||||
|
||||
List<MavenDependencyCompletionItem> result = stream.collect(new DeduplicationCollector<>(m -> m.getDisplayString()));
|
||||
assertSize(1, result);
|
||||
assertEquals(MavenDependencyCompletionItem.Type.LOCAL, result.get(0).getType());
|
||||
}
|
||||
|
||||
public void testShowLocalVersions() {
|
||||
MavenDependencyCompletionItem local = new MavenDependencyCompletionItem("group:artifact:1", MavenDependencyCompletionItem.Type.LOCAL);
|
||||
MavenDependencyCompletionItem remote = new MavenDependencyCompletionItem("group:artifact:2", MavenDependencyCompletionItem.Type.REMOTE);
|
||||
Stream<List<MavenDependencyCompletionItem>> stream = Arrays.stream(new List[]{
|
||||
asList(remote),
|
||||
asList(local)}
|
||||
);
|
||||
|
||||
List<MavenDependencyCompletionItem> result =
|
||||
stream.collect(new DeduplicationCollector<>(m -> m.getGroupId() + ":" + m.getArtifactId()));
|
||||
assertSize(1, result);
|
||||
assertEquals(MavenDependencyCompletionItem.Type.LOCAL, result.get(0).getType());
|
||||
}
|
||||
|
||||
public void testShowBothVersions() {
|
||||
MavenDependencyCompletionItem local = new MavenDependencyCompletionItem("group:artifact:1", MavenDependencyCompletionItem.Type.LOCAL);
|
||||
MavenDependencyCompletionItem remote = new MavenDependencyCompletionItem("group:artifact:2", MavenDependencyCompletionItem.Type.REMOTE);
|
||||
Stream<List<MavenDependencyCompletionItem>> stream = Arrays.stream(new List[]{
|
||||
asList(remote),
|
||||
asList(local)}
|
||||
);
|
||||
|
||||
List<MavenDependencyCompletionItem> result = stream.collect(new DeduplicationCollector<>(m -> m.getDisplayString()));
|
||||
assertSize(2, result);
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
// 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.onlinecompletion;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.idea.maven.MavenTestCase;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.MavenDependencyCompletionItem;
|
||||
import org.jetbrains.idea.maven.onlinecompletion.model.SearchParameters;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class LocalCompletionSearchTest extends MavenTestCase {
|
||||
private File myLocalRepo;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myLocalRepo = new File(myDir, ".m2/repository");
|
||||
createFile("org/apache/commons/commons-collections4/4.3/commons-collections4-4.3.pom");
|
||||
createFile("org/apache/commons/commons-collections4/4.2/commons-collections4-4.2.pom");
|
||||
createFile("org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.pom");
|
||||
createFile("xalan/xalan/2.6.0/xalan-2.6.0.pom");
|
||||
createFile("xalan/serializer/2.7.2/serializer-2.7.2.pom");
|
||||
FileUtil.ensureExists(myLocalRepo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindAllGroups() throws IOException {
|
||||
LocalCompletionSearch search = new LocalCompletionSearch(myLocalRepo);
|
||||
|
||||
List<MavenDependencyCompletionItem> items = search.findGroupCandidates(null, SearchParameters.DEFAULT);
|
||||
List<String> map = ContainerUtil.map(items, i -> i.getGroupId());
|
||||
assertUnorderedElementsAreEqual(map, "org.apache.commons",
|
||||
"xalan");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArtifacts() throws IOException {
|
||||
LocalCompletionSearch search = new LocalCompletionSearch(myLocalRepo);
|
||||
|
||||
List<MavenDependencyCompletionItem> items =
|
||||
search.findArtifactCandidates(new MavenDependencyCompletionItem("org.apache.commons"), SearchParameters.DEFAULT);
|
||||
List<String> map = ContainerUtil.map(items, i -> i.getArtifactId());
|
||||
assertUnorderedElementsAreEqual(map, "commons-collections4",
|
||||
"commons-lang3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersions() throws IOException {
|
||||
LocalCompletionSearch search = new LocalCompletionSearch(myLocalRepo);
|
||||
|
||||
List<MavenDependencyCompletionItem> items =
|
||||
search.findAllVersions(
|
||||
new MavenDependencyCompletionItem("org.apache.commons:commons-collections4"), SearchParameters.DEFAULT);
|
||||
List<String> map = ContainerUtil.map(items, i -> i.getVersion());
|
||||
assertUnorderedElementsAreEqual(map, "4.3",
|
||||
"4.2");
|
||||
}
|
||||
|
||||
private void createFile(String path) throws IOException {
|
||||
File file = new File(myLocalRepo, path);
|
||||
FileUtil.ensureCanCreateFile(file);
|
||||
file.createNewFile();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user