IDEA-274004 bump cmake.presets version after changes in RoundedInt
[idea/community.git] / platform / analysis-impl / src / com / intellij / codeInspection / ex / ApplicationInspectionProfileManagerBase.kt
1 // Copyright 2000-2021 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.codeInspection.ex
3
4 import com.intellij.configurationStore.BundledSchemeEP
5 import com.intellij.configurationStore.SchemeDataHolder
6 import com.intellij.ide.DataManager
7 import com.intellij.openapi.actionSystem.CommonDataKeys
8 import com.intellij.openapi.application.ApplicationManager
9 import com.intellij.openapi.components.service
10 import com.intellij.openapi.extensions.ExtensionPointName
11 import com.intellij.openapi.options.SchemeManagerFactory
12 import com.intellij.openapi.project.Project
13 import com.intellij.openapi.project.ProjectManager
14 import com.intellij.openapi.project.ProjectManagerListener
15 import com.intellij.profile.ProfileChangeAdapter
16 import com.intellij.profile.codeInspection.BaseInspectionProfileManager
17 import com.intellij.profile.codeInspection.InspectionProfileLoadUtil
18 import com.intellij.profile.codeInspection.InspectionProfileManager
19 import com.intellij.profile.codeInspection.InspectionProfileProcessor
20 import com.intellij.psi.search.scope.packageSet.NamedScopeManager
21 import com.intellij.psi.search.scope.packageSet.NamedScopesHolder
22 import com.intellij.serviceContainer.NonInjectable
23 import org.jdom.JDOMException
24 import org.jetbrains.annotations.TestOnly
25 import java.io.IOException
26 import java.nio.file.Files
27 import java.nio.file.Paths
28 import java.util.*
29 import java.util.function.BiConsumer
30 import java.util.function.Function
31
32 open class ApplicationInspectionProfileManagerBase @TestOnly @NonInjectable constructor(schemeManagerFactory: SchemeManagerFactory) :
33   BaseInspectionProfileManager(ApplicationManager.getApplication().messageBus) {
34
35   init {
36     val app = ApplicationManager.getApplication()
37     app.messageBus.connect().subscribe(ProjectManager.TOPIC, object : ProjectManagerListener {
38       override fun projectOpened(project: Project) {
39         val appScopeListener = NamedScopesHolder.ScopeListener {
40           profiles.forEach { it.scopesChanged() }
41         }
42         NamedScopeManager.getInstance(project).addScopeListener(appScopeListener, project)
43       }
44     })
45   }
46
47   override val schemeManager = schemeManagerFactory.create(InspectionProfileManager.INSPECTION_DIR, object : InspectionProfileProcessor() {
48     override fun getSchemeKey(attributeProvider: Function<String, String?>, fileNameWithoutExtension: String) = fileNameWithoutExtension
49
50     override fun createScheme(dataHolder: SchemeDataHolder<InspectionProfileImpl>,
51                               name: String,
52                               attributeProvider: Function<in String, String?>,
53                               isBundled: Boolean): InspectionProfileImpl {
54       return InspectionProfileImpl(name,
55                                    InspectionToolRegistrar.getInstance(),
56                                    this@ApplicationInspectionProfileManagerBase,
57                                    dataHolder)
58     }
59
60     override fun onSchemeAdded(scheme: InspectionProfileImpl) {
61       fireProfileChanged(scheme)
62     }
63
64     override fun onCurrentSchemeSwitched(oldScheme: InspectionProfileImpl?,
65                                          newScheme: InspectionProfileImpl?,
66                                          processChangeSynchronously: Boolean) {
67       DataManager.getInstance().dataContextFromFocusAsync.onSuccess {
68         CommonDataKeys.PROJECT.getData(it)?.messageBus?.syncPublisher(ProfileChangeAdapter.TOPIC)?.profileActivated(oldScheme, newScheme)
69       }
70     }
71   })
72
73   protected val profilesAreInitialized by lazy {
74     val app = ApplicationManager.getApplication()
75     if (!(app.isUnitTestMode || app.isHeadlessEnvironment)) {
76       BUNDLED_EP_NAME.processWithPluginDescriptor(BiConsumer { ep, pluginDescriptor ->
77         schemeManager.loadBundledScheme(ep.path!! + ".xml", null, pluginDescriptor)
78       })
79     }
80     schemeManager.loadSchemes()
81
82     if (schemeManager.isEmpty) {
83       schemeManager.addScheme(InspectionProfileImpl(
84         DEFAULT_PROFILE_NAME,
85         InspectionToolRegistrar.getInstance(), this))
86     }
87   }
88
89   @Volatile
90   protected var LOAD_PROFILES = !ApplicationManager.getApplication().isUnitTestMode
91
92   override fun getProfiles(): Collection<InspectionProfileImpl> {
93     initProfiles()
94     return Collections.unmodifiableList(schemeManager.allSchemes)
95   }
96
97   fun initProfiles() {
98     if (LOAD_PROFILES) {
99       profilesAreInitialized
100     }
101   }
102
103   @Throws(JDOMException::class, IOException::class)
104   open fun loadProfile(path: String): InspectionProfileImpl? {
105     val file = Paths.get(path)
106     if (Files.isRegularFile(file)) {
107       return InspectionProfileLoadUtil.load(file, InspectionToolRegistrar.getInstance(), this)
108     }
109     return getProfile(path, false)
110   }
111
112   override fun setRootProfile(profileName: String?) {
113     schemeManager.setCurrentSchemeName(profileName, true)
114   }
115
116   override fun getProfile(name: String, returnRootProfileIfNamedIsAbsent: Boolean): InspectionProfileImpl? {
117     val found = schemeManager.findSchemeByName(name)
118     if (found != null) {
119       return found
120     }
121
122     // profile was deleted
123     return if (returnRootProfileIfNamedIsAbsent) currentProfile else null
124   }
125
126   override fun getCurrentProfile(): InspectionProfileImpl {
127     initProfiles()
128
129     val current = schemeManager.activeScheme
130     if (current != null) {
131       return current
132     }
133
134     // use default as base, not random custom profile
135     val result = schemeManager.findSchemeByName(DEFAULT_PROFILE_NAME)
136     if (result == null) {
137       val profile = InspectionProfileImpl(DEFAULT_PROFILE_NAME)
138       addProfile(profile)
139       return profile
140     }
141     return result
142   }
143
144   override fun fireProfileChanged(profile: InspectionProfileImpl) {
145   }
146
147   companion object {
148     private val BUNDLED_EP_NAME = ExtensionPointName<BundledSchemeEP>("com.intellij.bundledInspectionProfile")
149
150
151       @JvmStatic
152       fun getInstanceBase() = service<InspectionProfileManager>() as ApplicationInspectionProfileManagerBase
153   }
154 }