diff --git a/java/compiler/impl/intellij.java.compiler.impl.iml b/java/compiler/impl/intellij.java.compiler.impl.iml index 9196878d9783..cb4d62302a70 100644 --- a/java/compiler/impl/intellij.java.compiler.impl.iml +++ b/java/compiler/impl/intellij.java.compiler.impl.iml @@ -42,7 +42,8 @@ - + + diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationSettings.kt b/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationSettings.kt index 0ac77fab3d0a..5ec74fa134a4 100644 --- a/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationSettings.kt +++ b/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationSettings.kt @@ -15,8 +15,13 @@ class CompilerConfigurationSettings : SimplePersistentStateComponent authHeaders = CompilerCacheServerAuthUtil.getRequestHeaders(project, true); if (authHeaders.isEmpty()) return null; - Pair commit = getCommitToDownload(project); + Pair commit = getCommitToDownload(project, serverUrl); if (commit == null) return null; CmdlineRemoteProto.Message.ControllerMessage.CacheDownloadSettings.Builder builder = @@ -52,8 +44,12 @@ public class CompilerCacheConfigurator { return builder.build(); } + public static boolean isServerUrlConfigured(@NotNull Project project) { + return getServerUrl(project) != null; + } + @Nullable - private Pair getCommitToDownload(@NotNull Project project) { + private static Pair getCommitToDownload(@NotNull Project project, @NotNull String serverUrl) { Map> availableCommitsPerRemote = CompilerCachesServerClient.getCacheKeysPerRemote(project, serverUrl); GitCommitsIterator commitsIterator = new GitCommitsIterator(project, INTELLIJ_REPO_NAME); String latestDownloadedCommit = GitRepositoryUtil.getLatestDownloadedCommit(); @@ -102,4 +98,8 @@ public class CompilerCacheConfigurator { } return Pair.create(commitToDownload, commitsCountBetweenCompilation); } + + private static @Nullable String getServerUrl(@NotNull Project project) { + return CompilerConfigurationSettings.Companion.getInstance(project).getCacheServerUrl(); + } } diff --git a/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheStartupActivity.java b/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheStartupActivity.java index d019395e39a4..75d4265b6977 100644 --- a/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheStartupActivity.java +++ b/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheStartupActivity.java @@ -2,8 +2,6 @@ package com.intellij.compiler.cache; import com.intellij.compiler.cache.client.JpsServerAuthExtension; import com.intellij.compiler.cache.git.GitRepositoryUtil; -import com.intellij.ide.browsers.BrowserLauncher; -import com.intellij.notification.NotificationAction; import com.intellij.notification.NotificationType; import com.intellij.openapi.Disposable; import com.intellij.openapi.compiler.JavaCompilerBundle; @@ -27,7 +25,7 @@ public final class CompilerCacheStartupActivity implements StartupActivity.Backg LOG.debug("JPS Caches registry key is not enabled"); return; } - if (!GitRepositoryUtil.isIntelliJRepository(project)) { + if (!CompilerCacheConfigurator.isServerUrlConfigured(project)) { LOG.debug("Not an Intellij project, JPS Caches will not be available"); return; } @@ -43,10 +41,8 @@ public final class CompilerCacheStartupActivity implements StartupActivity.Backg lineEndingsConfiguredCorrectly = false; ATTENTION .createNotification(JavaCompilerBundle.message("notification.title.git.crlf.config"), - JavaCompilerBundle.message("notification.content.git.crlf.config"), + JavaCompilerBundle.message("notification.content.git.crlf.config", "git config --global core.autocrlf input"), NotificationType.WARNING) - .addAction(NotificationAction.createSimple(JavaCompilerBundle.message("notification.action.git.crlf.config"), - () -> BrowserLauncher.getInstance().open("https://confluence.jetbrains.com/pages/viewpage.action?title=Git+Repository&spaceKey=IDEA"))) .notify(project); } } diff --git a/java/compiler/impl/src/com/intellij/compiler/cache/client/CompilerCachesServerClient.java b/java/compiler/impl/src/com/intellij/compiler/cache/client/CompilerCachesServerClient.java index 24f08f3daaba..d41073d92c58 100644 --- a/java/compiler/impl/src/com/intellij/compiler/cache/client/CompilerCachesServerClient.java +++ b/java/compiler/impl/src/com/intellij/compiler/cache/client/CompilerCachesServerClient.java @@ -1,7 +1,8 @@ package com.intellij.compiler.cache.client; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.StreamUtil; @@ -13,7 +14,6 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.lang.reflect.Type; import java.net.HttpURLConnection; import java.net.URLConnection; import java.nio.charset.StandardCharsets; @@ -22,7 +22,7 @@ import java.util.zip.GZIPInputStream; public final class CompilerCachesServerClient { private static final Logger LOG = Logger.getInstance(CompilerCachesServerClient.class); - private static final Type GSON_MAPPER = new TypeToken>>() {}.getType(); + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); @NotNull public static Map> getCacheKeysPerRemote(@NotNull Project project, @NotNull String serverUrl) { @@ -48,8 +48,8 @@ public final class CompilerCachesServerClient { if (connection instanceof HttpURLConnection) { HttpURLConnection httpConnection = (HttpURLConnection)connection; if (httpConnection.getResponseCode() == 200) { - Gson gson = new Gson(); - return gson.fromJson(new InputStreamReader(getInputStream(httpConnection), StandardCharsets.UTF_8) , GSON_MAPPER); + return OBJECT_MAPPER.readValue(getInputStream(httpConnection), new TypeReference<>() { + }); } else { String statusLine = httpConnection.getResponseCode() + ' ' + httpConnection.getRequestMethod(); diff --git a/java/compiler/impl/src/com/intellij/compiler/cache/client/JpsServerAuthExtension.java b/java/compiler/impl/src/com/intellij/compiler/cache/client/JpsServerAuthExtension.java index 64b4aa93856a..43f35cd1f214 100644 --- a/java/compiler/impl/src/com/intellij/compiler/cache/client/JpsServerAuthExtension.java +++ b/java/compiler/impl/src/com/intellij/compiler/cache/client/JpsServerAuthExtension.java @@ -40,11 +40,11 @@ public interface JpsServerAuthExtension { /** * The method provides HTTP authentication headers for the requests to the server. * It will be called in the background thread. The assertion that thread isn't EDT can - * be added to the implementation. If it's not possible to get the authentication headers, - * empty map or `null` can be return. - * @return + * be added to the implementation. + * @return Map with header name as key and token. If it's not possible to get the authentication + * headers, `null` will be returned. */ - Map getAuthHeader(boolean force); + @Nullable Map getAuthHeader(boolean force); @Nullable static JpsServerAuthExtension getInstance() { diff --git a/java/compiler/impl/src/com/intellij/compiler/cache/git/GitRepositoryUtil.java b/java/compiler/impl/src/com/intellij/compiler/cache/git/GitRepositoryUtil.java index c8fe28e623a3..b6cb4bf830b0 100644 --- a/java/compiler/impl/src/com/intellij/compiler/cache/git/GitRepositoryUtil.java +++ b/java/compiler/impl/src/com/intellij/compiler/cache/git/GitRepositoryUtil.java @@ -21,43 +21,10 @@ public final class GitRepositoryUtil { private static final Logger LOG = Logger.getInstance(GitRepositoryUtil.class); private static final String LATEST_COMMIT_ID = "JpsOutputLoaderManager.latestCommitId"; private static final String LATEST_BUILT_MASTER_COMMIT_ID = "JpsOutputLoaderManager.latestBuiltMasterCommitId"; - private static final String INTELLIJ_REPO_NAME = "intellij.git"; private static final int FETCH_SIZE = 100; private GitRepositoryUtil() {} - public static boolean isIntelliJRepository(@NotNull Project project) { - String projectBasePath = project.getBasePath(); - if (projectBasePath == null) return false; - GeneralCommandLine commandLine = new GeneralCommandLine() - .withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.CONSOLE) - .withWorkDirectory(projectBasePath) - .withExePath("git") - .withParameters("remote") - .withParameters("-v"); - - AtomicBoolean result = new AtomicBoolean(); - try { - OSProcessHandler handler = new OSProcessHandler(commandLine.withCharset(StandardCharsets.UTF_8)); - handler.addProcessListener(new CapturingProcessAdapter() { - @Override - public void processTerminated(@NotNull ProcessEvent event) { - if (event.getExitCode() != 0) { - LOG.warn("Couldn't fetch repository remote URL: " + getOutput().getStderr()); - } else { - result.set(getOutput().getStdout().contains(INTELLIJ_REPO_NAME)); - } - } - }); - handler.startNotify(); - handler.waitFor(); - } - catch (ExecutionException e) { - LOG.warn("Couldn't execute command for fetching remote URL", e); - } - return result.get(); - } - public static @NotNull List fetchRepositoryCommits(@NotNull Project project, @NotNull String latestCommit) { String projectBasePath = project.getBasePath(); if (projectBasePath == null) return Collections.emptyList(); diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 1dbc3dd577b1..622051fa7465 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -928,7 +928,7 @@ public final class BuildManager implements Disposable { } else { params = CmdlineProtoUtil.createBuildRequest(mappedProjectPath, scopes, isMake ? Collections.emptyList() : mappedPaths, userData, globals, currentFSChanges, - isMake ? CompilerCacheConfigurator.INSTANCE.getCacheDownloadSettings(project) : null); + isMake ? CompilerCacheConfigurator.getCacheDownloadSettings(project) : null); } if (!usingPreloadedProcess) { myMessageDispatcher.registerBuildMessageHandler(future, params); @@ -1410,7 +1410,7 @@ public final class BuildManager implements Disposable { // portable caches if (Registry.is("compiler.process.use.portable.caches") - && GitRepositoryUtil.isIntelliJRepository(project) + && CompilerCacheConfigurator.isServerUrlConfigured(project) && CompilerCacheStartupActivity.isLineEndingsConfiguredCorrectly()) { //cmdLine.addParameter("-Didea.resizeable.file.truncate.on.close=true"); //cmdLine.addParameter("-Dkotlin.jps.non.caching.storage=true"); diff --git a/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties b/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties index 4905b65719f6..8d1093e4804f 100644 --- a/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties +++ b/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties @@ -334,5 +334,4 @@ notification.title.jps.caches.downloader=Jps caches downloader notification.content.internal.authentication.plugin.required.for.correct.work=JetBrains Internal Authentication is required for the correct work of JPS Caches internal.authentication.plugin.missing.token=Unexpected state: jetbrains.team token is missing. Please report this exception and perform actions 'Logout from JetBrains.team' and 'Login to JetBrains.team' as a workaround notification.title.git.crlf.config=Wrong Git line-endings configuration -notification.content.git.crlf.config=Git line-endings not properly configured for the project. Portable JPS caches can't work correctly with such config. -notification.action.git.crlf.config=Open config description \ No newline at end of file +notification.content.git.crlf.config=To have working compiler caches you need to execute {0} command and force checkout the project \ No newline at end of file diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java index 015260097318..77f58c575ef6 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java @@ -61,7 +61,7 @@ public final class BuildRunner { myBuilderParams = builderParams != null? builderParams : Collections.emptyMap(); } - public @NotNull JpsProject getLoadedJpsProject() throws IOException { + public @NotNull JpsProject loadModelAndGetJpsProject() throws IOException { return myModelLoader.loadModel().getProject(); } @@ -140,7 +140,6 @@ public final class BuildRunner { MessageHandler msgHandler, BuildType buildType, List scopes, final boolean includeDependenciesToScope) throws Exception { - LOG.info("Got message with type: " + buildType); for (int attempt = 0; attempt < 2 && !cs.isCanceled(); attempt++) { final boolean forceClean = myForceCleanCaches && myFilePaths.isEmpty(); final CompileScope compileScope = createCompilationScope(pd, scopes, myFilePaths, forceClean, includeDependenciesToScope); diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java index 64a1a010ce64..a6ee7ed1b39d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -22,7 +22,6 @@ import org.jetbrains.jps.TimingLog; import org.jetbrains.jps.api.*; import org.jetbrains.jps.builders.*; import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType; -import org.jetbrains.jps.cache.client.JpsServerConnectionUtil; import org.jetbrains.jps.cache.loader.JpsOutputLoaderManager; import org.jetbrains.jps.incremental.*; import org.jetbrains.jps.incremental.fs.BuildFSState; @@ -167,7 +166,7 @@ final class BuildSession implements Runnable, CanceledStatus { myCacheLoadManager = null; if (ProjectStamps.PORTABLE_CACHES && myCacheDownloadSettings != null) { LOG.info("Trying to download JPS caches before build"); - myCacheLoadManager = new JpsOutputLoaderManager(myBuildRunner.getLoadedJpsProject(), this, myProjectPath, myChannel, + myCacheLoadManager = new JpsOutputLoaderManager(myBuildRunner.loadModelAndGetJpsProject(), this, myProjectPath, myChannel, mySessionId, myCacheDownloadSettings); myCacheLoadManager.load(myBuildRunner, true, myScopes); } diff --git a/plugins/jps-cache/resources/META-INF/plugin.xml b/plugins/jps-cache/resources/META-INF/plugin.xml index 383b6a542313..a83e78b99068 100644 --- a/plugins/jps-cache/resources/META-INF/plugin.xml +++ b/plugins/jps-cache/resources/META-INF/plugin.xml @@ -18,12 +18,6 @@ Git4Idea com.intellij.modules.java - - - - - - diff --git a/plugins/jps-cache/src/com/intellij/jps/cache/JpsCachesProjectStateListener.java b/plugins/jps-cache/src/com/intellij/jps/cache/JpsCachesProjectStateListener.java index b4df550a38db..62a7de96be8d 100644 --- a/plugins/jps-cache/src/com/intellij/jps/cache/JpsCachesProjectStateListener.java +++ b/plugins/jps-cache/src/com/intellij/jps/cache/JpsCachesProjectStateListener.java @@ -1,6 +1,6 @@ package com.intellij.jps.cache; -import com.intellij.jps.cache.client.JpsServerAuthExtension; +import com.intellij.jps.cache.client.JpsServerAuthUtil; import com.intellij.jps.cache.loader.JpsOutputLoaderManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.vcs.log.Hash; @@ -27,7 +27,7 @@ public class JpsCachesProjectStateListener implements GitRepositoryChangeListene previousCommitId = currentRevision; LOG.info("Remote repository commit changed to " + currentRevision); JpsOutputLoaderManager outputLoaderManager = JpsOutputLoaderManager.getInstance(repository.getProject()); - JpsServerAuthExtension.checkAuthenticatedInBackgroundThread(outputLoaderManager, repository.getProject(), - () -> outputLoaderManager.notifyAboutNearestCache()); + JpsServerAuthUtil.checkAuthenticatedInBackgroundThread(outputLoaderManager, repository.getProject(), + () -> outputLoaderManager.notifyAboutNearestCache()); } } diff --git a/plugins/jps-cache/src/com/intellij/jps/cache/action/JpsForceUpdateCachesAction.java b/plugins/jps-cache/src/com/intellij/jps/cache/action/JpsForceUpdateCachesAction.java index c4e36ebc6cd0..1d165cf83be0 100644 --- a/plugins/jps-cache/src/com/intellij/jps/cache/action/JpsForceUpdateCachesAction.java +++ b/plugins/jps-cache/src/com/intellij/jps/cache/action/JpsForceUpdateCachesAction.java @@ -1,6 +1,6 @@ package com.intellij.jps.cache.action; -import com.intellij.jps.cache.client.JpsServerAuthExtension; +import com.intellij.jps.cache.client.JpsServerAuthUtil; import com.intellij.jps.cache.loader.JpsOutputLoaderManager; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.DumbAwareAction; @@ -13,6 +13,6 @@ public class JpsForceUpdateCachesAction extends DumbAwareAction { Project project = actionEvent.getProject(); if (project == null) return; JpsOutputLoaderManager outputLoaderManager = JpsOutputLoaderManager.getInstance(project); - JpsServerAuthExtension.checkAuthenticatedInBackgroundThread(outputLoaderManager, project, () -> outputLoaderManager.load(true, true)); + JpsServerAuthUtil.checkAuthenticatedInBackgroundThread(outputLoaderManager, project, () -> outputLoaderManager.load(true, true)); } } diff --git a/plugins/jps-cache/src/com/intellij/jps/cache/action/JpsUpdateCachesAction.java b/plugins/jps-cache/src/com/intellij/jps/cache/action/JpsUpdateCachesAction.java index 8110e4f57c5c..eee8be52b879 100644 --- a/plugins/jps-cache/src/com/intellij/jps/cache/action/JpsUpdateCachesAction.java +++ b/plugins/jps-cache/src/com/intellij/jps/cache/action/JpsUpdateCachesAction.java @@ -1,6 +1,6 @@ package com.intellij.jps.cache.action; -import com.intellij.jps.cache.client.JpsServerAuthExtension; +import com.intellij.jps.cache.client.JpsServerAuthUtil; import com.intellij.jps.cache.loader.JpsOutputLoaderManager; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.DumbAwareAction; @@ -13,6 +13,6 @@ public class JpsUpdateCachesAction extends DumbAwareAction { Project project = actionEvent.getProject(); if (project == null) return; JpsOutputLoaderManager outputLoaderManager = JpsOutputLoaderManager.getInstance(project); - JpsServerAuthExtension.checkAuthenticatedInBackgroundThread(outputLoaderManager, project, () -> outputLoaderManager.load(false, true)); + JpsServerAuthUtil.checkAuthenticatedInBackgroundThread(outputLoaderManager, project, () -> outputLoaderManager.load(false, true)); } } \ No newline at end of file diff --git a/plugins/jps-cache/src/com/intellij/jps/cache/client/JpsServerAuthExtension.java b/plugins/jps-cache/src/com/intellij/jps/cache/client/JpsServerAuthExtension.java deleted file mode 100644 index 114d03316b57..000000000000 --- a/plugins/jps-cache/src/com/intellij/jps/cache/client/JpsServerAuthExtension.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.intellij.jps.cache.client; - -import com.intellij.jps.cache.JpsCacheBundle; -import com.intellij.notification.NotificationListener; -import com.intellij.notification.NotificationType; -import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Key; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Map; - -import static com.intellij.execution.process.ProcessIOExecutorService.INSTANCE; -import static com.intellij.jps.cache.ui.JpsLoaderNotifications.ATTENTION; - -/** - * Extension point which provides authentication data for requests to the JPS cache server - */ -public interface JpsServerAuthExtension { - Logger LOG = Logger.getInstance(JpsServerAuthExtension.class); - Key NOTIFICATION_SHOWN_KEY = Key.create("AUTH_NOTIFICATION_SHOWN"); - ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.jpsServerAuthExtension"); - - /** - * This method should check if the user was authenticated, if not it should do any needed actions to provide - * auth token for further requests. This method will be called outside of the EDT and should be asynchronous. - * If the user was authenticated the callback should be invoked. - * - * @param presentableReason reason for the token request - * @param parentDisposable controls the lifetime of the authentication - * @param onAuthCompleted callback on authentication complete, if token already exists it also should be invoked - */ - void checkAuthenticated(@NotNull String presentableReason, @NotNull Disposable parentDisposable, @NotNull Runnable onAuthCompleted); - - /** - * The method provides HTTP authentication headers for the requests to the server. - * It will be called in the background thread. The assertion that thread isn't EDT can - * be added to the implementation. If it's not possible to get the authentication headers, - * empty map or `null` can be return. - * @return - */ - Map getAuthHeader(); - - @Nullable - static JpsServerAuthExtension getInstance() { - return EP_NAME.extensions().findFirst().orElse(null); - } - - static void checkAuthenticatedInBackgroundThread(@NotNull Disposable parentDisposable, @NotNull Project project, @NotNull Runnable onAuthCompleted) { - Disposable disposable = Disposer.newDisposable(); - Disposer.register(parentDisposable, disposable); - JpsServerAuthExtension authExtension = getInstance(); - if (authExtension == null) { - Boolean userData = project.getUserData(NOTIFICATION_SHOWN_KEY); - if (userData == null) { - project.putUserData(NOTIFICATION_SHOWN_KEY, Boolean.TRUE); - ApplicationManager.getApplication().invokeLater(() -> { - ATTENTION - .createNotification(JpsCacheBundle.message("notification.title.jps.caches.downloader"), JpsCacheBundle.message("notification.content.internal.authentication.plugin.required.for.correct.work.plugin"), NotificationType.WARNING) - .setListener(NotificationListener.URL_OPENING_LISTENER) - .notify(project); - }); - } - LOG.warn("JetBrains Internal Authentication plugin is required for the correct work. Please enable it."); - return; - } - INSTANCE.execute(() -> { - authExtension.checkAuthenticated("Jps Caches Downloader", disposable, () -> { - Disposer.dispose(disposable); - onAuthCompleted.run(); - }); - }); - } -} diff --git a/plugins/jps-cache/src/com/intellij/jps/cache/client/JpsServerAuthUtil.java b/plugins/jps-cache/src/com/intellij/jps/cache/client/JpsServerAuthUtil.java index 2df3f25b15eb..1dff00da8a35 100644 --- a/plugins/jps-cache/src/com/intellij/jps/cache/client/JpsServerAuthUtil.java +++ b/plugins/jps-cache/src/com/intellij/jps/cache/client/JpsServerAuthUtil.java @@ -1,18 +1,61 @@ package com.intellij.jps.cache.client; +import com.intellij.compiler.cache.client.JpsServerAuthExtension; import com.intellij.jps.cache.JpsCacheBundle; +import com.intellij.notification.NotificationListener; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Key; import org.jetbrains.annotations.NotNull; import java.util.Map; -final class JpsServerAuthUtil { +import static com.intellij.execution.process.ProcessIOExecutorService.INSTANCE; +import static com.intellij.jps.cache.ui.JpsLoaderNotifications.ATTENTION; + +public final class JpsServerAuthUtil { + private static final Logger LOG = Logger.getInstance(JpsServerAuthUtil.class); + private static final Key NOTIFICATION_SHOWN_KEY = Key.create("AUTH_NOTIFICATION_SHOWN"); + + public static void checkAuthenticatedInBackgroundThread(@NotNull Disposable parentDisposable, + @NotNull Project project, + @NotNull Runnable onAuthCompleted) { + Disposable disposable = Disposer.newDisposable(); + Disposer.register(parentDisposable, disposable); + JpsServerAuthExtension authExtension = JpsServerAuthExtension.getInstance(); + if (authExtension == null) { + Boolean userData = project.getUserData(NOTIFICATION_SHOWN_KEY); + if (userData == null) { + project.putUserData(NOTIFICATION_SHOWN_KEY, Boolean.TRUE); + ApplicationManager.getApplication().invokeLater(() -> { + ATTENTION + .createNotification(JpsCacheBundle.message("notification.title.jps.caches.downloader"), JpsCacheBundle.message("notification.content.internal.authentication.plugin.required.for.correct.work.plugin"), NotificationType.WARNING) + .setListener(NotificationListener.URL_OPENING_LISTENER) + .notify(project); + }); + } + LOG.warn("JetBrains Internal Authentication plugin is required for the correct work. Please enable it."); + return; + } + INSTANCE.execute(() -> { + authExtension.checkAuthenticated("Jps Caches Downloader", disposable, () -> { + Disposer.dispose(disposable); + onAuthCompleted.run(); + }); + }); + } + static @NotNull Map getRequestHeaders() { JpsServerAuthExtension authExtension = JpsServerAuthExtension.getInstance(); if (authExtension == null) { String message = JpsCacheBundle.message("notification.content.internal.authentication.plugin.required.for.correct.work.plugin"); throw new RuntimeException(message); } - Map authHeader = authExtension.getAuthHeader(); + Map authHeader = authExtension.getAuthHeader(false); if (authHeader == null) { String message = JpsCacheBundle.message("internal.authentication.plugin.missing.token"); throw new RuntimeException(message);