IFT-413 Add API for courses merging: concatenate modules or replace them

IJ-CR-104546

GitOrigin-RevId: b988bbaa939c0a439a460438186968fa4fea66b1
This commit is contained in:
Alexey Merkulov
2023-03-13 17:25:32 +00:00
committed by intellij-monorepo-bot
parent 18d4d34665
commit d0de39c5b1
3 changed files with 34 additions and 15 deletions
@@ -16,10 +16,7 @@ import com.intellij.util.KeyedLazyInstanceEP
import com.intellij.util.containers.MultiMap
import training.lang.LangManager
import training.lang.LangSupport
import training.learn.course.IftModule
import training.learn.course.LearningCourse
import training.learn.course.LearningCourseBase
import training.learn.course.Lesson
import training.learn.course.*
import training.learn.lesson.LessonManager
import training.statistic.LessonStartingWay
import training.util.*
@@ -79,10 +76,10 @@ class CourseManager internal constructor() : Disposable {
}
}
val currentCourse: LearningCourse?
val currentCourses: List<LearningCourse>
get() = LangManager.getInstance().getLanguageId()?.let { lang ->
COURSE_MODULES_EP.extensionList.find { lang.equals(it.language, ignoreCase = true) }?.instance
}
getLanguageEPs(getLanguageToEPs(), lang).map { it.instance }
} ?: emptyList()
override fun dispose() {
}
@@ -138,15 +135,28 @@ class CourseManager internal constructor() : Disposable {
}
private fun reloadLangModules() {
val extensions = COURSE_MODULES_EP.extensions.filter { courseCanBeUsed(it.language) }
for (e in extensions) {
val langSupport = LangManager.getInstance().getLangSupportById(e.language)
if (langSupport != null) {
val languageToEPs = getLanguageToEPs()
for (languageId in languageToEPs.keys) {
val langSupport = LangManager.getInstance().getLangSupportById(languageId) ?: continue
for (e in getLanguageEPs(languageToEPs, languageId)) {
languageCourses.putValues(langSupport, createModules(e.instance, e.pluginDescriptor))
}
}
}
private fun getLanguageToEPs(): Map<String, List<LanguageExtensionPoint<LearningCourseBase>>> {
return COURSE_MODULES_EP.extensions.groupBy { it.language }.filterKeys { courseCanBeUsed(it) }
}
private fun getLanguageEPs(map: Map<String, List<LanguageExtensionPoint<LearningCourseBase>>>, languageId: String): List<LanguageExtensionPoint<LearningCourseBase>> {
return map[languageId]?.let {
val replacingCourse = it.firstOrNull { extensionPoint ->
extensionPoint.instance.otherCoursesMergeStrategy() == LearningCoursesMergeStrategy.REPLACE_MODULES
}
if (replacingCourse != null) listOf(replacingCourse) else it
} ?: emptyList()
}
private fun reloadCommonModules() {
val commonCoursesExtensions = COMMON_COURSE_MODULES_EP.extensions
for (e in commonCoursesExtensions) {
@@ -1,11 +1,22 @@
// 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.
package training.learn.course
import org.jetbrains.annotations.ApiStatus
interface LearningCourse {
fun modules(): Collection<IftModule>
@ApiStatus.Internal
fun otherCoursesMergeStrategy(): LearningCoursesMergeStrategy = LearningCoursesMergeStrategy.ADD_MODULES
/**
* @return map of lesson id to the list of suitable [com.intellij.ide.util.TipAndTrickBean.getId]
*/
fun getLessonIdToTipsMap(): Map<String, List<String>> = emptyMap()
}
@ApiStatus.Internal
enum class LearningCoursesMergeStrategy {
ADD_MODULES,
REPLACE_MODULES
}
@@ -19,7 +19,6 @@ import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UIUtil
import training.learn.CourseManager
import training.learn.LearnBundle
import training.learn.course.LearningCourse
import training.statistic.LessonStartingWay
import training.statistic.StatisticBase
import training.util.enableLessonsAndPromoters
@@ -36,9 +35,8 @@ private class IftTipAndTrickPromoter : TipAndTrickPromotionFactory {
}
private fun findLessonIdForTip(tip: TipAndTrickBean): String? {
val course: LearningCourse = CourseManager.instance.currentCourse ?: return null
val lessonIdToTipsMap = course.getLessonIdToTipsMap()
val lessonIds = lessonIdToTipsMap.filterValues { it.contains(tip.id) }.keys
val lessonIdToTipsMaps = CourseManager.instance.currentCourses.map { it.getLessonIdToTipsMap() }
val lessonIds = lessonIdToTipsMaps.map { it.filterValues { tipIds -> tipIds.contains(tip.id) }.keys }.flatten()
if (lessonIds.isNotEmpty()) {
if (lessonIds.size > 1) {
thisLogger().warn("$tip declared as suitable in more than one lesson: $lessonIds")