Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
*/
package org.domaframework.doma.intellij.common

import com.intellij.compiler.CompilerConfiguration
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.jps.model.java.JavaResourceRootType
Expand All @@ -32,14 +34,12 @@ object CommonPathParameterUtil {
/**
* Holds directory information for a module.
*
* @property moduleBasePath The base path of the module.
* @property moduleSourceDirectories List of source directories.
* @property moduleResourceDirectories List of resource directories.
* @property moduleTestSourceDirectories List of test source directories.
* @property moduleTestResourceDirectories List of test resource directories.
*/
data class ModulePaths(
val moduleBasePath: VirtualFile?,
val moduleSourceDirectories: List<VirtualFile>,
val moduleResourceDirectories: List<VirtualFile>,
val moduleTestSourceDirectories: List<VirtualFile>,
Expand All @@ -51,12 +51,30 @@ object CommonPathParameterUtil {

/**
* Returns the directory information for the specified module (uses cache if available).
* If the module's directory structure has changed, call [refreshModulePaths] to update the cache.
*
* @param module The module to retrieve directory information for.
* @return The cached or newly computed ModulePaths.
*/
fun getModulePaths(module: Module): ModulePaths = modulePathCache[module] ?: refreshModulePaths(module)
fun getModulePaths(module: Module): ModulePaths? = modulePathCache[module]

/**
* Checks if a given path is a generated directory based on annotation processor settings.
*
* @param module The module to check.
* @param path The path to check.
* @return True if the path is a generated directory, false otherwise.
*/
private fun isGeneratedDirectory(
module: Module,
path: String,
): Boolean {
val project: Project = module.project
val compilerConfiguration = CompilerConfiguration.getInstance(project).getAnnotationProcessingConfiguration(module)
val annotationProcessingConfiguration = compilerConfiguration.getGeneratedSourcesDirectoryName(false)

// Check if the path matches any of the generated source directories
return path.contains("/build/$annotationProcessingConfiguration/")
}

/**
* Refreshes the directory information for the specified module and updates the cache.
Expand All @@ -65,38 +83,53 @@ object CommonPathParameterUtil {
* @param module The module to refresh.
* @return The updated ModulePaths.
*/
fun refreshModulePaths(module: Module): ModulePaths {
var basePath: VirtualFile? = null
fun refreshModulePaths(module: Module) {
val sourceDirs = mutableListOf<VirtualFile>()
val resourceDirs = mutableListOf<VirtualFile>()
val testSourceDirs = mutableListOf<VirtualFile>()
val testResourceDirs = mutableListOf<VirtualFile>()

val moduleManager = ModuleRootManager.getInstance(module)
moduleManager.contentEntries.firstOrNull()?.let { entry ->
basePath = entry.file
entry.sourceFolders.forEach { folder ->
val file = folder.file
if (file != null) {
when (folder.rootType) {
JavaSourceRootType.SOURCE -> sourceDirs.add(file)
JavaSourceRootType.TEST_SOURCE -> testSourceDirs.add(file)
JavaResourceRootType.RESOURCE -> resourceDirs.add(file)
JavaResourceRootType.TEST_RESOURCE -> testResourceDirs.add(file)
moduleManager.contentEntries.forEach { entry ->
val entryFile = entry.file
if (entryFile != null && !isGeneratedDirectory(module, entryFile.path)) {
entry.sourceFolders.forEach { folder ->
val file = folder.file
if (file != null) {
when (folder.rootType) {
JavaSourceRootType.SOURCE ->
if (!sourceDirs.contains(file)) {
sourceDirs.add(file)
}

JavaSourceRootType.TEST_SOURCE ->
if (!testSourceDirs.contains(file)) {
testSourceDirs.add(file)
}

JavaResourceRootType.RESOURCE ->
if (!resourceDirs.contains(file)) {
resourceDirs.add(file)
}

JavaResourceRootType.TEST_RESOURCE ->
if (!testResourceDirs.contains(file)) {
testResourceDirs.add(file)
}
}
}
}
}
}

val paths =
ModulePaths(
basePath,
sourceDirs,
resourceDirs,
testSourceDirs,
testResourceDirs,
)
modulePathCache[module] = paths
return paths
}

/**
Expand All @@ -110,7 +143,7 @@ object CommonPathParameterUtil {
module: Module,
file: VirtualFile,
): Boolean {
val paths = getModulePaths(module)
val paths = getModulePaths(module) ?: return false
if (paths.moduleTestSourceDirectories.any { file.path.contains(it.path) }) return true
if (paths.moduleTestResourceDirectories.any { file.path.contains(it.path) }) return true
return false
Expand All @@ -127,30 +160,14 @@ object CommonPathParameterUtil {
fun getResources(
module: Module,
file: VirtualFile,
): List<VirtualFile> =
if (isTest(module, file)) {
getModulePaths(module).moduleTestResourceDirectories
} else {
getModulePaths(module).moduleResourceDirectories
}

/**
* Returns the source directories for the given file in the specified module.
* If the file is in a test directory, test source directories are returned.
*
* @param module The module to check.
* @param file The file to check.
* @return List of source directories.
*/
fun getSources(
module: Module,
file: VirtualFile,
): List<VirtualFile> =
if (isTest(module, file)) {
getModulePaths(module).moduleTestSourceDirectories
): List<VirtualFile> {
val modulePaths = getModulePaths(module) ?: return emptyList()
return if (isTest(module, file)) {
modulePaths.moduleTestResourceDirectories
} else {
getModulePaths(module).moduleSourceDirectories
modulePaths.moduleResourceDirectories
}
}

/**
* Clears the module directory cache. Call this if the module structure changes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
*/
package org.domaframework.doma.intellij.common.config

import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import org.domaframework.doma.intellij.common.CommonPathParameterUtil
import com.intellij.openapi.module.Module
import org.domaframework.doma.intellij.extension.getResourcesFile
import java.util.concurrent.ConcurrentHashMap

object DomaCompileConfigUtil {
Expand All @@ -30,40 +29,34 @@ object DomaCompileConfigUtil {

/**
* Get the value of the specified key from doma.compile.config
* @param project active project
* @param resourcePaths the path to the resource directories
* @param module the module to retrieve the configuration from
* @param isTest true if the configuration is for test sources, false for main sources
* @param key the key to retrieve the value for
* @return the value associated with the key, or null if not found
*/
fun getConfigValue(
project: Project,
resourcePaths: List<VirtualFile>,
module: Module,
isTest: Boolean,
key: String,
): String? {
resourcePaths.forEach { resourcePath ->
if (resourcePath.isValid) {
val configVFile = resourcePath.findChild("doma.compile.config")
val cacheKey = "${project.basePath}/${resourcePath.path}/doma.compile.config"
val lastModified = configVFile?.timeStamp ?: 0L
val cached = configCache[cacheKey]
val settingFileName = "doma.compile.config"
val settingFile = module.getResourcesFile(settingFileName, isTest)
val cacheKey = "${settingFile?.path}/$settingFileName"
val lastModified = settingFile?.timeStamp ?: 0L
val cached = configCache[cacheKey]

val props =
if (cached == null || cached.second != lastModified) {
val loadedProps =
configVFile?.inputStream?.use { input ->
java.util.Properties().apply { load(input) }
} ?: java.util.Properties()
configCache[cacheKey] = loadedProps to lastModified
loadedProps
} else {
cached.first
}
val propProperty = props.getProperty(key)
if (propProperty != null) return propProperty
val props =
if (cached == null || cached.second != lastModified) {
val loadedProps =
settingFile?.inputStream?.use { input ->
java.util.Properties().apply { load(input) }
} ?: java.util.Properties()
configCache[cacheKey] = loadedProps to lastModified
loadedProps
} else {
CommonPathParameterUtil.clearCache()
cached.first
}
}
return null
val propProperty = props.getProperty(key)
return propProperty
}
}
Loading
Loading