com.jetbrains.plugin.structure.edu.EduPluginManager.kt Maven / Gradle / Ivy
/*
* Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package com.jetbrains.plugin.structure.edu
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.jetbrains.plugin.structure.base.decompress.DecompressorSizeLimitExceededException
import com.jetbrains.plugin.structure.base.plugin.*
import com.jetbrains.plugin.structure.base.problems.PluginDescriptorIsNotFound
import com.jetbrains.plugin.structure.base.problems.PluginFileSizeIsTooLarge
import com.jetbrains.plugin.structure.base.problems.UnableToExtractZip
import com.jetbrains.plugin.structure.base.problems.UnableToReadDescriptor
import com.jetbrains.plugin.structure.base.utils.*
import com.jetbrains.plugin.structure.edu.bean.EduPluginDescriptor
import com.jetbrains.plugin.structure.edu.problems.createIncorrectEduPluginFile
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
class EduPluginManager private constructor(private val extractDirectory: Path) : PluginManager {
companion object {
const val DESCRIPTOR_NAME = "course.json"
const val COURSE_ICON_NAME = "courseIcon.svg"
private val LOG: Logger = LoggerFactory.getLogger(EduPluginManager::class.java)
fun createManager(
extractDirectory: Path = Paths.get(Settings.EXTRACT_DIRECTORY.get())
): EduPluginManager {
extractDirectory.createDir()
return EduPluginManager(extractDirectory)
}
}
override fun createPlugin(pluginFile: Path): PluginCreationResult {
require(pluginFile.exists()) { "Plugin file $pluginFile does not exist" }
return when {
pluginFile.isZip() -> loadDescriptorFromZip(pluginFile)
else -> PluginCreationFail(createIncorrectEduPluginFile(pluginFile.simpleName))
}
}
private fun loadDescriptorFromZip(pluginFile: Path): PluginCreationResult {
val sizeLimit = Settings.EDU_PLUGIN_SIZE_LIMIT.getAsLong()
if (Files.size(pluginFile) > sizeLimit) {
return PluginCreationFail(UnableToExtractZip())
}
val tempDirectory = Files.createTempDirectory(extractDirectory, "plugin_")
return try {
extractZip(pluginFile, tempDirectory, sizeLimit)
loadPluginInfoFromDirectory(tempDirectory)
} catch (e: DecompressorSizeLimitExceededException) {
return PluginCreationFail(PluginFileSizeIsTooLarge(e.sizeLimit))
} finally {
tempDirectory.deleteLogged()
}
}
private fun loadPluginInfoFromDirectory(pluginDirectory: Path): PluginCreationResult {
val descriptorFile = pluginDirectory.resolve(DESCRIPTOR_NAME)
if (!descriptorFile.exists()) {
return PluginCreationFail(PluginDescriptorIsNotFound(DESCRIPTOR_NAME))
}
val descriptorContent = descriptorFile.readText()
val mapper = jacksonObjectMapper()
val descriptor = mapper.readValue(descriptorContent, EduPluginDescriptor::class.java)
val icon = loadIconFromDir(pluginDirectory)
return createPlugin(descriptor, icon)
}
private fun loadIconFromDir(pluginDirectory: Path): PluginIcon? {
val iconFile = pluginDirectory.resolve(COURSE_ICON_NAME)
if (iconFile.exists()) {
val iconContent = Files.readAllBytes(iconFile)
return PluginIcon(IconTheme.DEFAULT, iconContent, iconFile.fileName.toString())
}
return null
}
private fun createPlugin(descriptor: EduPluginDescriptor, icon: PluginIcon?): PluginCreationResult {
try {
val beanValidationResult = validateEduPluginBean(descriptor)
if (beanValidationResult.any { it.level == PluginProblem.Level.ERROR }) {
return PluginCreationFail(beanValidationResult)
}
val plugin = with(descriptor) {
EduPlugin(
pluginName = this.title,
description = this.summary,
vendor = this.vendor?.name,
vendorUrl = this.vendor?.vendorUrl,
vendorEmail = this.vendor?.vendorEmail,
descriptorVersion = this.descriptorVersion,
pluginVersion = this.pluginVersion,
language = this.language,
programmingLanguage = this.programmingLanguage,
environment = this.environment,
isPrivate = this.isPrivate ?: false,
eduStat = EduStat.fromDescriptor(this),
icons = if (icon != null) listOf(icon) else emptyList(),
pluginId = "${this.title}_${this.vendor?.name}_${this.programmingLanguage}"
)
}
return PluginCreationSuccess(plugin, beanValidationResult)
} catch (e: Exception) {
e.rethrowIfInterrupted()
LOG.info("Unable to read plugin descriptor $DESCRIPTOR_NAME", e)
return PluginCreationFail(UnableToReadDescriptor(DESCRIPTOR_NAME, e.localizedMessage))
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy