Skip to content

Commit 7d11733

Browse files
committed
Dynamically retrieve source and resource directory paths.
1 parent 3d3f1d6 commit 7d11733

File tree

10 files changed

+211
-93
lines changed

10 files changed

+211
-93
lines changed

src/main/kotlin/org/domaframework/doma/intellij/action/sql/JumpToDaoFromSQLAction.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ class JumpToDaoFromSQLAction : AnAction() {
5656
val project = e.project ?: return
5757
val daoFile = findDaoFile(project, file) ?: return
5858

59-
val nameWithoutExtension = file.virtualFile?.nameWithoutExtension ?: return
60-
jumpToDaoMethod(project, nameWithoutExtension, daoFile)
59+
val sqlFileName = file.virtualFile?.nameWithoutExtension ?: return
60+
jumpToDaoMethod(project, sqlFileName, daoFile)
6161
PluginLoggerUtil.countLoggingByAction(
6262
this::class.java.simpleName,
6363
"JumpToDao",

src/main/kotlin/org/domaframework/doma/intellij/common/CommonPathParameter.kt

Lines changed: 94 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,101 @@
1515
*/
1616
package org.domaframework.doma.intellij.common
1717

18-
open class CommonPathParameter {
19-
companion object {
20-
val SRC_MAIN_PATH: String
21-
get() = "/src/main"
18+
import com.intellij.openapi.module.Module
19+
import com.intellij.openapi.roots.ModuleRootManager
20+
import com.intellij.openapi.vfs.VirtualFile
21+
import org.jetbrains.jps.model.java.JavaResourceRootType
22+
import org.jetbrains.jps.model.java.JavaSourceRootType
2223

23-
val RESOURCES_PATH: String
24-
get() = "resources"
24+
val RESOURCES_META_INF_PATH: String
25+
get() = "META-INF"
2526

26-
val RESOURCES_META_INF_PATH: String
27-
get() = "META-INF"
27+
class CommonPathParameter(
28+
module: Module?,
29+
) {
30+
/**
31+
* module base path ex)Absolute path of "/src/main"
32+
*/
33+
var moduleBasePath: VirtualFile? = null
34+
35+
/**
36+
* module source directories ex) Absolute path of "/src/main/java","/src/main/kotlin"
37+
*/
38+
var moduleSourceDirectories: MutableList<VirtualFile> = mutableListOf()
39+
40+
/**
41+
* module resource directory ex) Absolute path of "/src/main/resources"
42+
*/
43+
var moduleResourceDirectories: MutableList<VirtualFile> = mutableListOf()
44+
45+
var moduleTestSourceDirectories: MutableList<VirtualFile> = mutableListOf()
46+
var moduleTestResourceDirectories: MutableList<VirtualFile> = mutableListOf()
47+
48+
init {
49+
setModuleSourcesFiles(module)
50+
}
51+
52+
private fun setModuleSourcesFiles(module: Module?) {
53+
if (module == null) return
54+
55+
val modulemanager = ModuleRootManager.getInstance(module)
56+
57+
moduleSourceDirectories.clear()
58+
modulemanager?.contentEntries?.firstOrNull()?.let { entry ->
59+
moduleBasePath = entry.file
60+
entry.sourceFolders.map { folder ->
61+
val file = folder.file
62+
if (file != null) {
63+
println("file:${file.name}")
64+
when (folder.rootType) {
65+
JavaSourceRootType.SOURCE -> {
66+
moduleSourceDirectories.add(file)
67+
println("moduleSourceDirectory:$file")
68+
}
69+
70+
JavaSourceRootType.TEST_SOURCE -> {
71+
moduleTestSourceDirectories.add(file)
72+
println("moduleTestSourceDirectory:$file")
73+
}
74+
75+
JavaResourceRootType.RESOURCE -> {
76+
moduleResourceDirectories.add(file)
77+
println("moduleResourceDirectory:$file")
78+
}
79+
80+
JavaResourceRootType.TEST_RESOURCE -> {
81+
moduleTestResourceDirectories.add(file)
82+
println("moduleTestResourceDirectory:$file")
83+
}
84+
}
85+
}
86+
}
87+
}
88+
}
89+
90+
fun isTest(file: VirtualFile): Boolean {
91+
val testSource =
92+
moduleTestSourceDirectories.firstOrNull { testSource ->
93+
file.path.contains(testSource.path)
94+
}
95+
if (testSource != null) return true
96+
97+
return moduleTestResourceDirectories.firstOrNull { testSource ->
98+
file.path.contains(testSource.path)
99+
} != null
28100
}
101+
102+
fun getResources(file: VirtualFile): MutableList<VirtualFile> =
103+
if (isTest(file)) {
104+
moduleTestResourceDirectories
105+
} else {
106+
moduleResourceDirectories
107+
}
108+
109+
fun getSources(file: VirtualFile): MutableList<VirtualFile> =
110+
if (isTest(file)) {
111+
moduleTestSourceDirectories
112+
} else {
113+
moduleSourceDirectories
114+
}
29115
}

src/main/kotlin/org/domaframework/doma/intellij/common/FileTypeCheck.kt

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
package org.domaframework.doma.intellij.common
1717

1818
import com.intellij.openapi.fileTypes.FileTypeManager
19-
import com.intellij.openapi.vfs.VirtualFile
2019
import com.intellij.psi.PsiFile
21-
import org.domaframework.doma.intellij.common.CommonPathParameter.Companion.SRC_MAIN_PATH
20+
21+
val sourceExtensionNames: List<String> = listOf("JAVA", "Kotlin", "CLASS")
2222

2323
/**
2424
* Get extension by file type identifier
@@ -66,36 +66,3 @@ fun isInjectionSqlFile(file: PsiFile): Boolean {
6666
} &&
6767
!(filePath.endsWith(".sql") || filePath.endsWith(".script"))
6868
}
69-
70-
/**
71-
* Dao file search for SQL files
72-
*/
73-
fun searchDaoFile(
74-
contentRoot: VirtualFile?,
75-
originFilePath: String,
76-
relativeDaoFilePath: String,
77-
): VirtualFile? {
78-
val projectRootPath = contentRoot?.path ?: return null
79-
if (projectRootPath.endsWith(SRC_MAIN_PATH)) {
80-
return contentRoot.findFileByRelativePath(relativeDaoFilePath)
81-
}
82-
83-
if (projectRootPath.length > originFilePath.length) {
84-
return null
85-
}
86-
87-
// TODO Dynamically build the source directory path and retrieve subproject info
88-
// by inspecting file metadata instead of using string manipulation.
89-
val index = originFilePath.indexOf(SRC_MAIN_PATH)
90-
val projectRootPathBefore = projectRootPath.substringBefore(SRC_MAIN_PATH)
91-
if (index < 0 || projectRootPathBefore.length < index) return null
92-
val subProjectName =
93-
originFilePath.substring(projectRootPathBefore.length, index)
94-
95-
val daoFile =
96-
contentRoot
97-
.findFileByRelativePath(subProjectName)
98-
?.findFileByRelativePath(relativeDaoFilePath)
99-
100-
return daoFile
101-
}

src/main/kotlin/org/domaframework/doma/intellij/common/JarFileSearch.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package org.domaframework.doma.intellij.common
1818
import com.intellij.openapi.vfs.StandardFileSystems
1919
import com.intellij.openapi.vfs.VirtualFile
2020
import com.intellij.psi.PsiFile
21-
import org.domaframework.doma.intellij.common.CommonPathParameter.Companion.RESOURCES_META_INF_PATH
2221

2322
fun getJarRoot(
2423
virtualFile: VirtualFile,

src/main/kotlin/org/domaframework/doma/intellij/common/dao/DaoMethodUtil.kt

Lines changed: 85 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,19 @@ import com.intellij.psi.PsiManager
2727
import com.intellij.psi.PsiMethod
2828
import com.intellij.psi.search.GlobalSearchScope
2929
import com.intellij.psi.util.PsiTreeUtil
30-
import org.domaframework.doma.intellij.common.CommonPathParameter.Companion.RESOURCES_META_INF_PATH
31-
import org.domaframework.doma.intellij.common.CommonPathParameter.Companion.RESOURCES_PATH
30+
import org.domaframework.doma.intellij.common.CommonPathParameter
31+
import org.domaframework.doma.intellij.common.RESOURCES_META_INF_PATH
3232
import org.domaframework.doma.intellij.common.getExtension
3333
import org.domaframework.doma.intellij.common.getJarRoot
3434
import org.domaframework.doma.intellij.common.getMethodDaoFilePath
3535
import org.domaframework.doma.intellij.common.isInjectionSqlFile
3636
import org.domaframework.doma.intellij.common.isSupportFileType
37-
import org.domaframework.doma.intellij.common.searchDaoFile
37+
import org.domaframework.doma.intellij.common.sourceExtensionNames
3838
import org.domaframework.doma.intellij.extension.findFile
3939
import org.domaframework.doma.intellij.extension.getContentRoot
4040
import org.domaframework.doma.intellij.extension.getJavaClazz
4141
import org.domaframework.doma.intellij.extension.getModule
42+
import org.jetbrains.kotlin.idea.base.util.module
4243

4344
/**
4445
* Get Dao method corresponding to SQL file
@@ -57,28 +58,27 @@ fun findDaoMethod(
5758
}
5859
} else if (isSupportFileType(originalFile)) {
5960
// TODO: Add Support Kotlin
60-
val fileTypeName = "JAVA"
6161
val methodName = virtualFile.nameWithoutExtension
6262
val daoFile = daoFile ?: findDaoFile(project, originalFile) ?: return null
6363
if (module != null) {
6464
val relativePath =
65-
formatDaoPathFromSqlFilePath(
65+
getDaoPathFromSqlFilePath(
6666
originalFile,
6767
project.getContentRoot(virtualFile)?.path ?: "",
68-
fileTypeName,
6968
)
7069
// get ClassPath with package name
7170
val daoClassName: String =
7271
relativePath
7372
.substringBefore(".")
7473
.replace("/", ".")
7574
.replace("\\", ".")
76-
.substringAfter(".${getExtension(fileTypeName)}")
7775
.replace("..", ".")
7876
.trim('.')
77+
7978
val daoJavaFile = project.findFile(daoFile)
8079
findDaoClass(module, daoClassName)?.let { daoClass ->
8180
val daoMethod =
81+
// TODO Support Kotlin Project
8282
when (daoJavaFile) {
8383
is PsiJavaFile -> findUseSqlDaoMethod(daoJavaFile, methodName)
8484
else -> null
@@ -130,10 +130,36 @@ fun findDaoFile(
130130
if (contentRoot == null) {
131131
return getJarRoot(virtualFile, sqlFile)
132132
}
133+
return searchDaoFile(sqlFile.module, contentRoot, sqlFile)
134+
}
135+
136+
/**
137+
* Dao file search for SQL file
138+
*/
139+
private fun searchDaoFile(
140+
module: Module?,
141+
contentRoot: VirtualFile?,
142+
sqlFile: PsiFile,
143+
): VirtualFile? {
144+
val contentRootPath = contentRoot?.path ?: return null
145+
val pathParams = CommonPathParameter(module)
146+
val moduleBaseName = pathParams.moduleBasePath?.nameWithoutExtension ?: ""
133147
// TODO: Add Support Kotlin
134-
val relativeFilePath =
135-
formatDaoPathFromSqlFilePath(sqlFile, contentRoot.path, "JAVA")
136-
return searchDaoFile(contentRoot, virtualFile.path, relativeFilePath)
148+
val relativeDaoFilePaths =
149+
getDaoPathFromSqlFilePath(sqlFile, contentRoot.path)
150+
val sources = pathParams.getSources(sqlFile.virtualFile)
151+
152+
if (contentRootPath.endsWith(moduleBaseName) == true) {
153+
sources.forEach { source ->
154+
sourceExtensionNames.forEach { extension ->
155+
val fileExtension = getExtension(extension)
156+
val findDaoFile =
157+
contentRoot.findFileByRelativePath("${source.nameWithoutExtension}$relativeDaoFilePaths.$fileExtension")
158+
if (findDaoFile != null) return findDaoFile
159+
}
160+
}
161+
}
162+
return null
137163
}
138164

139165
private fun findDaoClass(
@@ -143,40 +169,70 @@ private fun findDaoClass(
143169

144170
/**
145171
* Generate Dao deployment path from SQL file path
172+
* @param sqlFile SQL File
173+
* @param projectRootPath project content Root Path
174+
* @return
146175
*/
147-
fun formatDaoPathFromSqlFilePath(
148-
relativeBaseSqlFile: PsiFile,
176+
private fun getDaoPathFromSqlFilePath(
177+
sqlFile: PsiFile,
149178
projectRootPath: String,
150-
extension: String,
151179
): String {
152-
if (isInjectionSqlFile(relativeBaseSqlFile)) {
180+
if (isInjectionSqlFile(sqlFile)) {
153181
return ""
154182
}
155-
val sqlPath = relativeBaseSqlFile.virtualFile?.path ?: return ""
183+
val module = sqlFile.module
184+
val sqlPath = sqlFile.virtualFile?.path ?: return ""
156185
var relativeFilePath = sqlPath.substring(projectRootPath.length)
157186
if (!relativeFilePath.startsWith("/")) {
158187
relativeFilePath = "/$relativeFilePath"
159188
}
160-
val extensionType = getExtension(extension.uppercase())
161-
return relativeFilePath
162-
.replace("/$RESOURCES_PATH", "")
163-
.replace(RESOURCES_META_INF_PATH, extension.lowercase())
164-
.replace("/${relativeBaseSqlFile.name}", "")
165-
.plus(".$extensionType")
189+
val pathParams = CommonPathParameter(module)
190+
val resources = pathParams.getResources(sqlFile.virtualFile)
191+
192+
return resources
193+
.firstOrNull { resource ->
194+
relativeFilePath.startsWith("/" + resource.nameWithoutExtension)
195+
}?.let { resource ->
196+
relativeFilePath
197+
.replace("${resource.nameWithoutExtension}/$RESOURCES_META_INF_PATH/", "")
198+
.replace("/${sqlFile.name}", "")
199+
} ?: ""
166200
}
167201

168202
/**
169203
* Generate SqlFile path from Dao file path
204+
* @param daoFile Dao File
205+
* @param module The module to which the Dao file belongs
206+
* @return SqlFile path ex) META-INF/package/dao/DaoClassName/
170207
*/
171-
fun formatSqlPathFromDaoPath(
172-
contentRootPath: String,
208+
fun getRelativeSqlFilePathFromDaoFilePath(
173209
daoFile: VirtualFile,
210+
module: Module?,
174211
): String {
175-
val fileType = daoFile.fileType.name
212+
if (module == null) return ""
176213
val extension = daoFile.fileType.defaultExtension
177-
val daoFilePath = daoFile.path
178-
return daoFilePath
179-
.replace(contentRootPath, RESOURCES_META_INF_PATH)
180-
.replace("/${fileType.lowercase()}/", "/")
181-
.replace(".$extension", "")
214+
val pathParams = CommonPathParameter(module)
215+
var relativeSqlFilePath =
216+
daoFile.path
217+
.replace(pathParams.moduleBasePath?.path ?: "", "")
218+
.replace(".$extension", "")
219+
val isTest = pathParams.moduleTestSourceDirectories.firstOrNull { dir -> daoFile.path.contains(dir.path) } != null
220+
if (isTest) {
221+
pathParams.moduleTestSourceDirectories.forEach { source ->
222+
relativeSqlFilePath =
223+
relativeSqlFilePath.replace(
224+
"/" + source.nameWithoutExtension,
225+
RESOURCES_META_INF_PATH,
226+
)
227+
}
228+
} else {
229+
pathParams.moduleSourceDirectories.forEach { source ->
230+
relativeSqlFilePath =
231+
relativeSqlFilePath.replace(
232+
"/" + source.nameWithoutExtension,
233+
RESOURCES_META_INF_PATH,
234+
)
235+
}
236+
}
237+
return relativeSqlFilePath
182238
}

src/main/kotlin/org/domaframework/doma/intellij/common/dao/JumpActionFunctions.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ fun jumpToDaoMethod(
4545
}
4646
}
4747

48+
// TODO Support Kotlin Project
4849
private fun getKotlinFunctions(
4950
file: KtFile,
5051
targetMethodName: String,

0 commit comments

Comments
 (0)