11c66c36871f16eb4c24ed1503c1173baf2234e3
[idea/community.git] / platform / projectModel-api / src / com / intellij / openapi / projectRoots / ProjectJdkTable.java
1 // 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.
2 package com.intellij.openapi.projectRoots;
3
4 import com.intellij.openapi.Disposable;
5 import com.intellij.openapi.application.WriteAction;
6 import com.intellij.openapi.components.ServiceManager;
7 import com.intellij.openapi.util.Comparing;
8 import com.intellij.openapi.util.Condition;
9 import com.intellij.openapi.util.Disposer;
10 import com.intellij.util.messages.Topic;
11 import org.jetbrains.annotations.ApiStatus;
12 import org.jetbrains.annotations.NotNull;
13 import org.jetbrains.annotations.Nullable;
14 import org.jetbrains.annotations.TestOnly;
15
16 import java.util.EventListener;
17 import java.util.List;
18
19 @ApiStatus.NonExtendable
20 public abstract class ProjectJdkTable {
21   public static ProjectJdkTable getInstance() {
22     return ServiceManager.getService(ProjectJdkTable.class);
23   }
24
25   @Nullable
26   public abstract Sdk findJdk(@NotNull String name);
27
28   @Nullable
29   public abstract Sdk findJdk(@NotNull String name, @NotNull String type);
30
31   public abstract Sdk @NotNull [] getAllJdks();
32
33   @NotNull
34   public abstract List<Sdk> getSdksOfType(@NotNull SdkTypeId type);
35
36   @Nullable
37   public Sdk findMostRecentSdkOfType(@NotNull SdkTypeId type) {
38     return getSdksOfType(type).stream().max(type.versionComparator()).orElse(null);
39   }
40
41   /** @deprecated comparing version strings across SDK types makes no sense; use {@link #findMostRecentSdkOfType} */
42   @Deprecated
43   @ApiStatus.ScheduledForRemoval(inVersion = "2020.3")
44   public Sdk findMostRecentSdk(@NotNull Condition<? super Sdk> condition) {
45     Sdk found = null;
46     for (Sdk each : getAllJdks()) {
47       if (condition.value(each) &&
48           (found == null || Comparing.compare(each.getVersionString(), found.getVersionString()) > 0)) {
49         found = each;
50       }
51     }
52     return found;
53   }
54
55   public abstract void addJdk(@NotNull Sdk jdk);
56
57   @TestOnly
58   public void addJdk(@NotNull Sdk jdk, @NotNull Disposable parentDisposable) {
59     addJdk(jdk);
60     Disposer.register(parentDisposable, () -> WriteAction.runAndWait(()-> removeJdk(jdk)));
61   }
62
63   public abstract void removeJdk(@NotNull Sdk jdk);
64
65   public abstract void updateJdk(@NotNull Sdk originalJdk, @NotNull Sdk modifiedJdk);
66
67   public interface Listener extends EventListener {
68     void jdkAdded(@NotNull Sdk jdk);
69     void jdkRemoved(@NotNull Sdk jdk);
70     void jdkNameChanged(@NotNull Sdk jdk, @NotNull String previousName);
71   }
72
73   public static class Adapter implements Listener {
74     @Override public void jdkAdded(@NotNull Sdk jdk) { }
75     @Override public void jdkRemoved(@NotNull Sdk jdk) { }
76     @Override public void jdkNameChanged(@NotNull Sdk jdk, @NotNull String previousName) { }
77   }
78
79   @NotNull
80   public abstract SdkTypeId getDefaultSdkType();
81
82   @NotNull
83   public abstract SdkTypeId getSdkTypeByName(@NotNull String name);
84
85   @NotNull
86   public abstract Sdk createSdk(@NotNull String name, @NotNull SdkTypeId sdkType);
87
88   /**
89    * This method may automatically detect Sdk if none are configured.
90    */
91   public void preconfigure() {
92     
93   }
94
95   public static final Topic<Listener> JDK_TABLE_TOPIC = Topic.create("Project JDK table", Listener.class);
96 }