source searcher: use groupId for maven sources search;

related issue: IDEA-135073 IDEA can't download source but it exists in a remote repository
This commit is contained in:
Vladislav.Soroka
2015-02-20 19:05:08 +03:00
parent 3e00dcb78a
commit fa361fdc54
4 changed files with 76 additions and 8 deletions
@@ -67,7 +67,7 @@ public class InternetAttachSourceProvider implements AttachSourcesProvider {
@NotNull
@Override
public Collection<AttachSourcesAction> getActions(List<LibraryOrderEntry> orderEntries, final PsiFile psiFile) {
VirtualFile jar = getJarByPsiFile(psiFile);
final VirtualFile jar = getJarByPsiFile(psiFile);
if (jar == null) return Collections.emptyList();
final String jarName = jar.getNameWithoutExtension();
@@ -145,7 +145,7 @@ public class InternetAttachSourceProvider implements AttachSourcesProvider {
SourceSearcher[] searchers = {new MavenCentralSourceSearcher(), new SonatypeSourceSearcher()};
for (SourceSearcher searcher : searchers) {
try {
artifactUrl = searcher.findSourceJar(indicator, artifactId, version);
artifactUrl = searcher.findSourceJar(indicator, artifactId, version, jar);
}
catch (SourceSearchException e) {
LOG.warn(e);
@@ -2,6 +2,7 @@ package com.intellij.jarFinder;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.vfs.VirtualFile;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.xpath.XPath;
@@ -21,13 +22,19 @@ public class MavenCentralSourceSearcher extends SourceSearcher {
@Override
protected String findSourceJar(@NotNull ProgressIndicator indicator,
@NotNull String artifactId,
@NotNull String version) throws SourceSearchException {
@NotNull String version,
@NotNull VirtualFile classesJar) throws SourceSearchException {
try {
indicator.setText("Connecting to https://search.maven.org");
indicator.checkCanceled();
String url = "https://search.maven.org/solrsearch/select?rows=3&wt=xml&q=a:%22" + artifactId + "%22%20AND%20v:%22" + version + "%22%20AND%20l:%22sources%22";
String url = "https://search.maven.org/solrsearch/select?rows=3&wt=xml&q=";
final String groupId = findMavenGroupId(classesJar, artifactId);
if (groupId != null) {
url += "g:%22" + groupId + "%22%20AND%20";
}
url += "a:%22" + artifactId + "%22%20AND%20v:%22" + version + "%22%20AND%20l:%22sources%22";
@SuppressWarnings("unchecked")
List<Element> artifactList = (List<Element>)XPath.newInstance("/response/result/doc/str[@name='g']").selectNodes(readDocumentCancelable(indicator, url));
if (artifactList.isEmpty()) {
@@ -2,6 +2,7 @@ package com.intellij.jarFinder;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.vfs.VirtualFile;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.xpath.XPath;
@@ -19,7 +20,10 @@ public class SonatypeSourceSearcher extends SourceSearcher {
@Nullable
@Override
public String findSourceJar(@NotNull final ProgressIndicator indicator, @NotNull String artifactId, @NotNull String version)
public String findSourceJar(@NotNull final ProgressIndicator indicator,
@NotNull String artifactId,
@NotNull String version,
@NotNull VirtualFile classesJar)
throws SourceSearchException {
try {
indicator.setIndeterminate(true);
@@ -28,6 +32,11 @@ public class SonatypeSourceSearcher extends SourceSearcher {
indicator.checkCanceled();
String url = "https://oss.sonatype.org/service/local/lucene/search?collapseresults=true&c=sources&a=" + artifactId + "&v=" + version;
String groupId = findMavenGroupId(classesJar, artifactId);
if(groupId != null) {
url += ("&g=" + groupId);
}
List<Element> artifactList = (List<Element>)XPath.newInstance("/searchNGResponse/data/artifact").selectNodes(readDocumentCancelable(indicator, url));
if (artifactList.isEmpty()) {
return null;
@@ -50,7 +59,7 @@ public class SonatypeSourceSearcher extends SourceSearcher {
return null;
}
String groupId = element.getChildTextTrim("groupId");
groupId = element.getChildTextTrim("groupId");
String repositoryId = artifactHintList.get(0).getChildTextTrim("repositoryId");
return "https://oss.sonatype.org/service/local/artifact/maven/redirect?r=" +
@@ -2,6 +2,10 @@ package com.intellij.jarFinder;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.io.HttpRequests;
import org.jdom.Document;
import org.jdom.JDOMException;
@@ -9,19 +13,43 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* @author Sergey Evdokimov
*/
public abstract class SourceSearcher {
private static final String MAVEN_POM_ENTRY_PREFIX = "META-INF/maven/";
/**
* @param indicator
* @param artifactId
* @param version
* @return groupId of found artifact and url.
* @return url of found artifact
*/
@Nullable
protected abstract String findSourceJar(@NotNull final ProgressIndicator indicator, @NotNull String artifactId, @NotNull String version) throws SourceSearchException;
protected String findSourceJar(@NotNull final ProgressIndicator indicator, @NotNull String artifactId, @NotNull String version)
throws SourceSearchException {
return null;
}
/**
* @param indicator
* @param artifactId
* @param version
* @param classesJar classes jar
* @return url of found artifact
*/
@Nullable
protected String findSourceJar(@NotNull final ProgressIndicator indicator,
@NotNull String artifactId,
@NotNull String version,
@NotNull VirtualFile classesJar) throws SourceSearchException {
return findSourceJar(indicator, artifactId, version);
}
@NotNull
protected static Document readDocumentCancelable(final ProgressIndicator indicator, String url) throws IOException {
@@ -39,6 +67,30 @@ public abstract class SourceSearcher {
}
});
}
@Nullable
protected static String findMavenGroupId(@NotNull VirtualFile classesJar, String artifactId) {
try {
JarFile jarFile = new JarFile(VfsUtilCore.virtualToIoFile(classesJar));
try {
final Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
final String name = entry.getName();
if (StringUtil.startsWith(name, MAVEN_POM_ENTRY_PREFIX) && StringUtil.endsWith(name, "/" + artifactId + "/pom.xml")) {
final int index = name.indexOf('/', MAVEN_POM_ENTRY_PREFIX.length());
return index != -1 ? name.substring(MAVEN_POM_ENTRY_PREFIX.length(), index) : null;
}
}
}
finally {
StreamUtil.closeStream(jarFile);
}
}
catch (IOException ignore) {
}
return null;
}
}
class SourceSearchException extends Exception {