blob: b5f93e5cc8cfe21a6953fca44b102cd0f46cce91 [file]
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.plugins.grails;
import com.intellij.jarFinder.AbstractAttachSourceProvider;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.roots.LibraryOrderEntry;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.concurrency.ThreadingAssertions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.grails.config.GrailsConfigUtils;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
final class GrailsAttachSourcesProvider extends AbstractAttachSourceProvider {
private static final Logger LOG = Logger.getInstance(GrailsAttachSourcesProvider.class);
@Override
public @NotNull Collection<? extends AttachSourcesAction> getActions(@NotNull List<? extends LibraryOrderEntry> orderEntries,
@NotNull PsiFile psiFile) {
VirtualFile jar = getJarByPsiFile(psiFile);
if (jar == null) return List.of();
final Library library = getLibraryFromOrderEntriesList(orderEntries);
if (library == null) return List.of();
VirtualFile[] files = library.getFiles(OrderRootType.CLASSES);
VirtualFile grailsHome = GrailsConfigUtils.getGrailsLibraryHome(files);
if (grailsHome == null) return List.of();
final String grailsVersion = GrailsConfigUtils.getGrailsVersion(files);
if (StringUtil.isEmpty(grailsVersion) || "1.4".compareTo(grailsVersion) > 0) return List.of();
final String jarNameWithoutExt = jar.getNameWithoutExtension();
if (!jarNameWithoutExt.endsWith(grailsVersion)) {
LOG.warn("Grails JAR name don't end of version [jar:" + jar + ", version: " + grailsVersion + "]");
return List.of();
}
String pluginNameWith_ = StringUtil.trimEnd(jarNameWithoutExt, grailsVersion);
if (!pluginNameWith_.endsWith("-")) {
LOG.warn("Grails JAR name don't end of version [jar:" + jar + ", version: " + grailsVersion + "]");
return List.of();
}
final String pluginName = StringUtil.trimEnd(pluginNameWith_, "-").trim();
final String sourceFileName = jarNameWithoutExt + "-sources.jar";
ThreadingAssertions.assertEventDispatchThread();
grailsHome.refresh(false, false);
final VirtualFile grailsHomeSrc = grailsHome.findChild("src");
if (grailsHomeSrc == null) {
LOG.warn("Grails home don't contains 'scr' folder");
return List.of();
}
grailsHomeSrc.refresh(false, false);
VirtualFile srcFile = grailsHomeSrc.findChild(sourceFileName);
if (srcFile != null) {
// File already downloaded.
VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(srcFile);
if (jarRoot == null || ArrayUtil.contains(jarRoot, library.getFiles(OrderRootType.SOURCES))) {
return List.of(); // Sources already attached.
}
return List.of(
new AttachExistingSourceAction(
jarRoot,
library,
GrailsBundle.message("attache.source.from.grails.action.title", "$GRAILS_HOME/src/"))
);
}
final String url = "https://repo.grails.org/grails/libs-releases-local/org/grails/" + pluginName + '/' + grailsVersion + '/' + sourceFileName;
return List.of(new DownloadSourcesAction(psiFile.getProject(), "Downloading Grails Sources", url) {
@Override
protected void storeFile(byte[] content) {
try {
VirtualFile srcFile = grailsHomeSrc.createChildData(this, sourceFileName);
srcFile.setBinaryContent(content);
addSourceFile(JarFileSystem.getInstance().getJarRootForLocalFile(srcFile), library);
}
catch (IOException e) {
new Notification(myMessageGroupId,
GrailsBundle.message("notification.title.io.error"),
GrailsBundle.message("notification.content.failed.to.save.0.1", grailsHomeSrc.getPath(), sourceFileName),
NotificationType.ERROR)
.notify(myProject);
LOG.warn(e);
}
}
});
}
}