Skip to content

Commit ff2ad95

Browse files
authored
Merge pull request #452 from domaframework/fix/duplicate-registration-error-for-intention-actions
Fix Multiple Registration Error for SQL File to Annotation Conversion Actions
2 parents 26dc021 + 0dcf1b6 commit ff2ad95

File tree

12 files changed

+156
-98
lines changed

12 files changed

+156
-98
lines changed

src/main/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlFileToAnnotationAction.kt renamed to src/main/kotlin/org/domaframework/doma/intellij/action/dao/AbstractConvertSqlFileToAnnotationAction.kt

Lines changed: 21 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -22,55 +22,40 @@ import com.intellij.openapi.editor.Editor
2222
import com.intellij.openapi.project.Project
2323
import com.intellij.psi.PsiElement
2424
import com.intellij.psi.PsiMethod
25-
import com.intellij.psi.util.PsiTreeUtil
26-
import org.domaframework.doma.intellij.bundle.MessageBundle
27-
import org.domaframework.doma.intellij.common.dao.findDaoMethod
28-
import org.domaframework.doma.intellij.common.dao.getDaoClass
29-
import org.domaframework.doma.intellij.common.isJavaOrKotlinFileType
30-
import org.domaframework.doma.intellij.common.isSupportFileType
3125
import org.domaframework.doma.intellij.common.psi.PsiDaoMethod
3226
import org.domaframework.doma.intellij.common.util.PluginLoggerUtil
3327

3428
/**
35-
* Intention action to convert SQL file to @Sql annotation
29+
* Abstract base class for converting SQL file to @Sql annotation
3630
*/
37-
class ConvertSqlFileToAnnotationAction : PsiElementBaseIntentionAction() {
38-
override fun getFamilyName(): String = MessageBundle.message("convert.sql.file.to.annotation.family")
39-
40-
override fun getText(): String = MessageBundle.message("convert.sql.file.to.annotation.text")
41-
31+
abstract class AbstractConvertSqlFileToAnnotationAction : PsiElementBaseIntentionAction() {
4232
override fun isAvailable(
4333
project: Project,
4434
editor: Editor?,
4535
element: PsiElement,
4636
): Boolean {
47-
val file = element.containingFile ?: return false
48-
if (isJavaOrKotlinFileType(file) && getDaoClass(file) != null) {
49-
return checkOnMethod(element, project)
50-
}
51-
52-
if (isSupportFileType(file)) {
53-
return checkOnSqlFile(element, project)
37+
if (!isTargetFile(element)) {
38+
return false
5439
}
5540

56-
return false
57-
}
58-
59-
private fun checkOnMethod(
60-
element: PsiElement,
61-
project: Project,
62-
): Boolean {
63-
val daoMethod = PsiTreeUtil.getParentOfType(element, PsiMethod::class.java) ?: return false
41+
val daoMethod = getDaoMethod(element) ?: return false
6442
return checkAvailable(project, daoMethod)
6543
}
6644

67-
private fun checkOnSqlFile(
68-
element: PsiElement,
69-
project: Project,
70-
): Boolean {
71-
val daoMethod = findDaoMethod(element.containingFile) ?: return false
72-
return checkAvailable(project, daoMethod)
73-
}
45+
/**
46+
* Check if the element is in a target file type for this action
47+
*/
48+
protected abstract fun isTargetFile(element: PsiElement): Boolean
49+
50+
/**
51+
* Get the DAO method from the element
52+
*/
53+
protected abstract fun getDaoMethod(element: PsiElement): PsiMethod?
54+
55+
/**
56+
* Get the action name for logging
57+
*/
58+
protected abstract fun getActionName(): String
7459

7560
private fun checkAvailable(
7661
project: Project,
@@ -101,42 +86,7 @@ class ConvertSqlFileToAnnotationAction : PsiElementBaseIntentionAction() {
10186
// Do nothing when previewing
10287
if (IntentionPreviewUtils.isIntentionPreviewActive()) return
10388

104-
val file = element.containingFile
105-
if (isJavaOrKotlinFileType(file)) {
106-
return processOnMethod(element, project)
107-
}
108-
109-
// Process if the file type is SQL
110-
if (isSupportFileType(file)) {
111-
return processOnSqlFile(element, project)
112-
}
113-
}
114-
115-
private fun processOnMethod(
116-
element: PsiElement,
117-
project: Project,
118-
) {
119-
val daoMethod = PsiTreeUtil.getParentOfType(element, PsiMethod::class.java) ?: return
120-
121-
val startTime = System.nanoTime()
122-
val converter = SqlAnnotationConverter(project, daoMethod)
123-
WriteCommandAction.runWriteCommandAction(project) {
124-
converter.convertToSqlAnnotation()
125-
}
126-
127-
PluginLoggerUtil.countLogging(
128-
className = this::class.java.simpleName,
129-
actionName = "convertSqlFileToAnnotationOnMethod",
130-
inputName = "IntentionAction",
131-
start = startTime,
132-
)
133-
}
134-
135-
private fun processOnSqlFile(
136-
element: PsiElement,
137-
project: Project,
138-
) {
139-
val daoMethod = findDaoMethod(element.containingFile) ?: return
89+
val daoMethod = getDaoMethod(element) ?: return
14090

14191
val startTime = System.nanoTime()
14292
val converter = SqlAnnotationConverter(project, daoMethod)
@@ -146,7 +96,7 @@ class ConvertSqlFileToAnnotationAction : PsiElementBaseIntentionAction() {
14696

14797
PluginLoggerUtil.countLogging(
14898
className = this::class.java.simpleName,
149-
actionName = "convertSqlFileToAnnotationOnSQL",
99+
actionName = getActionName(),
150100
inputName = "IntentionAction",
151101
start = startTime,
152102
)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright Doma Tools Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.domaframework.doma.intellij.action.dao
17+
18+
import com.intellij.psi.PsiElement
19+
import com.intellij.psi.PsiMethod
20+
import com.intellij.psi.util.PsiTreeUtil
21+
import org.domaframework.doma.intellij.bundle.MessageBundle
22+
import org.domaframework.doma.intellij.common.dao.getDaoClass
23+
import org.domaframework.doma.intellij.common.isJavaOrKotlinFileType
24+
25+
/**
26+
* Intention action to convert SQL file to @Sql annotation from DAO files
27+
*/
28+
class ConvertSqlFileToAnnotationFromDaoAction : AbstractConvertSqlFileToAnnotationAction() {
29+
override fun getFamilyName(): String = MessageBundle.message("convert.sql.file.to.annotation.from.dao.family")
30+
31+
override fun getText(): String = MessageBundle.message("convert.sql.file.to.annotation.from.dao.text")
32+
33+
override fun isTargetFile(element: PsiElement): Boolean {
34+
val file = element.containingFile ?: return false
35+
return isJavaOrKotlinFileType(file) && getDaoClass(file) != null
36+
}
37+
38+
override fun getDaoMethod(element: PsiElement): PsiMethod? = PsiTreeUtil.getParentOfType(element, PsiMethod::class.java)
39+
40+
override fun getActionName(): String = "convertSqlFileToAnnotationFromDao"
41+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright Doma Tools Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.domaframework.doma.intellij.action.sql
17+
18+
import com.intellij.psi.PsiElement
19+
import com.intellij.psi.PsiMethod
20+
import org.domaframework.doma.intellij.action.dao.AbstractConvertSqlFileToAnnotationAction
21+
import org.domaframework.doma.intellij.bundle.MessageBundle
22+
import org.domaframework.doma.intellij.common.dao.findDaoMethod
23+
import org.domaframework.doma.intellij.common.isSupportFileType
24+
25+
/**
26+
* Intention action to convert SQL file to @Sql annotation from SQL files
27+
*/
28+
class ConvertSqlFileToAnnotationFromSqlAction : AbstractConvertSqlFileToAnnotationAction() {
29+
override fun getFamilyName(): String = MessageBundle.message("convert.sql.file.to.annotation.from.sql.family")
30+
31+
override fun getText(): String = MessageBundle.message("convert.sql.file.to.annotation.from.sql.text")
32+
33+
override fun isTargetFile(element: PsiElement): Boolean {
34+
val file = element.containingFile ?: return false
35+
return isSupportFileType(file)
36+
}
37+
38+
override fun getDaoMethod(element: PsiElement): PsiMethod? = findDaoMethod(element.containingFile)
39+
40+
override fun getActionName(): String = "convertSqlFileToAnnotationFromSql"
41+
}

src/main/resources/META-INF/plugin.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,13 @@
102102
</intentionAction>
103103
<intentionAction>
104104
<language>DomaSql</language>
105-
<className>org.domaframework.doma.intellij.action.dao.ConvertSqlFileToAnnotationAction</className>
105+
<className>org.domaframework.doma.intellij.action.sql.ConvertSqlFileToAnnotationFromSqlAction</className>
106106
<category>Doma tools</category>
107107
<skipBeforeAfter>true</skipBeforeAfter>
108108
</intentionAction>
109109
<intentionAction>
110110
<language>JAVA</language>
111-
<className>org.domaframework.doma.intellij.action.dao.ConvertSqlFileToAnnotationAction</className>
111+
<className>org.domaframework.doma.intellij.action.dao.ConvertSqlFileToAnnotationFromDaoAction</className>
112112
<category>Doma tools</category>
113113
<skipBeforeAfter>true</skipBeforeAfter>
114114
</intentionAction>

src/main/resources/intentionDescriptions/ConvertSqlFileToAnnotationAction/description.html

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<html lang="en">
2+
<body>
3+
<p>
4+
This action converts SQL statements from SQL files into Sql annotations for DAO methods.<br>
5+
By selecting a DAO method and executing the action, the corresponding SQL will be embedded as an annotation in the appropriate DAO method.<br>
6+
This makes it easier to manage SQL directly within the source code and improves code readability and maintainability.
7+
</p>
8+
</body>
9+
</html>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<html lang="en">
2+
<body>
3+
<p>
4+
This action converts SQL statements from SQL files into Sql annotations for DAO methods.<br>
5+
By selecting an SQL file and executing the action, the corresponding SQL will be embedded as an annotation in the appropriate DAO method.<br>
6+
This makes it easier to manage SQL directly within the source code and improves code readability and maintainability.
7+
</p>
8+
</body>
9+
</html>

src/main/resources/messages/DomaToolsBundle.properties

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ inspection.invalid.dao.annotation.option.embeddable=Field [{0}] specified in [{1
4141
inspection.invalid.dao.annotation.option.primitive=Field path [{0}] specified in [{2}] option is invalid. Field [{1}] is a primitive type and does not have nested properties
4242
convert.sql.annotation.to.file.family=Convert @Sql annotation to SQL file
4343
convert.sql.annotation.to.file.text=Convert to SQL file (set sqlFile=true)
44-
convert.sql.file.to.annotation.family=Convert SQL file to @Sql annotation
45-
convert.sql.file.to.annotation.text=Convert to @Sql annotation (set sqlFile=false)
44+
convert.sql.file.to.annotation.from.dao.family=Convert SQL file to @Sql annotation
45+
convert.sql.file.to.annotation.from.dao.text=Convert SQL file to @Sql annotation
46+
convert.sql.file.to.annotation.from.sql.family=Convert to @Sql annotation
47+
convert.sql.file.to.annotation.from.sql.text=Convert to @Sql annotation in DAO method
4648
inspection.invalid.sql.function.call.parameter.count=Function {0} definition with {1} parameters not found
4749
inspection.invalid.sql.function.call.parameter.type.mismatch=<html>Function {0} parameter type mismatch. Actual types: ({1})<br><small>Definition candidates:</small><br>{2}</html>

src/main/resources/messages/DomaToolsBundle_ja.properties

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ inspection.invalid.dao.annotation.option.embeddable=[{1}]\u30AA\u30D7\u30B7\u30E
4141
inspection.invalid.dao.annotation.option.primitive=[{2}]\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u6307\u5B9A\u3055\u308C\u305F\u30D5\u30A3\u30FC\u30EB\u30C9\u30D1\u30B9[{0}]\u306F\u7121\u52B9\u3067\u3059\u3002\u30D5\u30A3\u30FC\u30EB\u30C9[{1}]\u306F\u30D7\u30EA\u30DF\u30C6\u30A3\u30D6\u578B\u3067\u3042\u308A\u3001\u30CD\u30B9\u30C8\u3055\u308C\u305F\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u6301\u3061\u307E\u305B\u3093
4242
convert.sql.annotation.to.file.family=@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u3092SQL\u30D5\u30A1\u30A4\u30EB\u306B\u5909\u63DB
4343
convert.sql.annotation.to.file.text=SQL\u30D5\u30A1\u30A4\u30EB\u306B\u5909\u63DB (sqlFile=true\u306B\u8A2D\u5B9A)
44-
convert.sql.file.to.annotation.family=SQL\u30D5\u30A1\u30A4\u30EB\u3092@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB
45-
convert.sql.file.to.annotation.text=@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB (sqlFile=false\u306B\u8A2D\u5B9A)
44+
convert.sql.file.to.annotation.from.dao.family=SQL\u30D5\u30A1\u30A4\u30EB\u3092@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB
45+
convert.sql.file.to.annotation.from.dao.text=@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB (sqlFile=false\u306B\u8A2D\u5B9A)
46+
convert.sql.file.to.annotation.from.sql.family=SQL\u30D5\u30A1\u30A4\u30EB\u3092@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB
47+
convert.sql.file.to.annotation.from.sql.text=@Sql\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u5909\u63DB (sqlFile=false\u306B\u8A2D\u5B9A)
4648
inspection.invalid.sql.function.call.parameter.count=\u95a2\u6570{0}\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u6570\u304c{1}\u306e\u5b9a\u7fa9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
4749
inspection.invalid.sql.function.call.parameter.type.mismatch=<html>\u95a2\u6570{0}\u306e\u5f15\u6570\u306e\u578b\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002\u5b9f\u969b\u306e\u578b: ({1})<br><small>\u5b9a\u7fa9\u5019\u88dc:</small><br>{2}</html>

src/test/kotlin/org/domaframework/doma/intellij/action/dao/ConvertSqlActionTest.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
1919
import com.intellij.openapi.fileEditor.FileEditorManager
2020
import com.intellij.psi.PsiDocumentManager
2121
import org.domaframework.doma.intellij.DomaSqlTest
22+
import kotlin.reflect.KClass
2223

2324
abstract class ConvertSqlActionTest : DomaSqlTest() {
2425
protected fun doConvertAction(
@@ -45,17 +46,18 @@ abstract class ConvertSqlActionTest : DomaSqlTest() {
4546
myFixture.checkResultByFile("java/doma/example/dao/$sqlConversionPackage/$daoName.after.java")
4647
}
4748

48-
protected fun doConvertActionTest(
49+
protected fun <T : AbstractConvertSqlFileToAnnotationAction> doConvertActionTest(
4950
daoName: String,
5051
sqlToAnnotationPackage: String,
5152
convertFamilyName: String,
53+
convertActionClass: KClass<T>,
5254
) {
5355
addDaoJavaFile("$sqlToAnnotationPackage/$daoName.java")
5456
val daoClass = findDaoClass("$sqlToAnnotationPackage.$daoName")
5557
myFixture.configureFromExistingVirtualFile(daoClass.containingFile.virtualFile)
5658

5759
val intentions = myFixture.availableIntentions
58-
val convertIntention = intentions.find { it is ConvertSqlFileToAnnotationAction }
60+
val convertIntention = intentions.find { convertActionClass.java.isInstance(it) }
5961

6062
assertNull("$convertFamilyName intention should NOT be available without @Sql annotation", convertIntention)
6163
}

0 commit comments

Comments
 (0)