class MyBatisJavaNavigationProvider : RelatedItemLineMarkerProvider()
{
override fun collectNavigationMarkers(
element: PsiElement, result: MutableCollection<in RelatedItemLineMarkerInfo<*>>
)
{
if (element is PsiClass)
{
val psiClass: PsiClass = element
println(psiClass.qualifiedName)
val allMethods = element.allMethods
if (psiClass.containingFile.virtualFile == null)
{
return
}
val targets: ArrayList<PsiElement> = ArrayList()
// 1. 查找与 class 类名同名的 xml 文件, 并追加到结果集合
val xmlFiles = FilenameIndex.getFilesByName(
psiClass.project, psiClass.name + ".xml", GlobalSearchScope.projectScope(psiClass.project)
).toList()
for (xmlFile in xmlFiles)
{
if(xmlFile is XmlFile)
{
var xml:XmlFile=xmlFile
println(xml.name)
val tag = xml.rootTag
if (tag != null)
{
println(tag.namespace)
if(tag.getAttributeValue("namespace") == psiClass.qualifiedName)
{
targets.add(tag)
}
}
}
}
if (targets.isEmpty())
{
println("结果为空")
return
} // 构建导航样式
val builder: NavigationGutterIconBuilder<PsiElement> =
NavigationGutterIconBuilder.create(AllIcons.FileTypes.Xml).setTargets(targets)
.setTooltipText("Navigate to Xml resource").setAlignment(GutterIconRenderer.Alignment.RIGHT)
.setCellRenderer(MyMapperCellRenderer())
if (null != psiClass.nameIdentifier)
{
result.add(builder.createLineMarkerInfo(psiClass.nameIdentifier!!))
}
if(!targets.isNullOrEmpty())
{
for (method in allMethods)
{
val methodTargets: ArrayList<PsiElement> = ArrayList()
val psiElement = targets.get(0)
if( psiElement is XmlTag)
{
var xmlFile:XmlTag= psiElement
val findXmlTagById = findXmlTagById(xmlFile, method.name)
if (findXmlTagById != null)
{
methodTargets.add(findXmlTagById)
val methodBuilder =
NavigationGutterIconBuilder.create(AllIcons.FileTypes.Xml).setTargets(methodTargets)
.setTooltipText("Navigate to Xml resource").setAlignment(GutterIconRenderer.Alignment.RIGHT)
.setCellRenderer(MyMapperCellRenderer())
result.add(methodBuilder.createLineMarkerInfo(method.nameIdentifier!!))
}
}
}
}
}
}
fun findXmlTagById(xmlTag: XmlTag, tagId: String): XmlTag? {
// 查找当前标签的 ID 属性
val idAttribute = xmlTag.getAttribute("id")
if (idAttribute != null && idAttribute.value == tagId) {
return xmlTag
}
// 递归查找子标签
for (childTag in xmlTag.subTags) {
val foundTag = findXmlTagById(childTag, tagId)
if (foundTag != null) {
return foundTag
}
}
return null
}
class MyMapperCellRenderer : DefaultPsiElementCellRenderer()
{
override fun getElementText(element: PsiElement): String
{
val prefix = StringBuilder()
if (element is JsonProperty)
{
prefix.append("Found XML! ")
}
return prefix.append(super.getElementText(element)).toString()
}
override fun getIcon(element: PsiElement): Icon
{
return AllIcons.FileTypes.Xml
}
}
}
Java文件跳转至XML文件
package com.atelier.plugin.provider
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder
import com.intellij.icons.AllIcons
import com.intellij.ide.util.DefaultPsiElementCellRenderer
import com.intellij.json.psi.JsonProperty
import com.intellij.openapi.editor.markup.GutterIconRenderer
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.search.FilenameIndex
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.xml.XmlFile
import com.intellij.sql.formatter.findSubSequence
import javax.swing.Icon
class MyBatisXMLNavigationProvider: RelatedItemLineMarkerProvider()
{
override fun collectNavigationMarkers(
element: PsiElement, result: MutableCollection<in RelatedItemLineMarkerInfo<*>>
)
{
if (element !is XmlFile) {
return
}
val xmlfile: XmlFile = element
val tag = xmlfile.rootTag
val xmlFileName = xmlfile.name
val className = xmlFileName.substringBeforeLast(".xml")
if (xmlfile.containingFile.virtualFile == null) {
return
}
val targets: ArrayList<PsiElement> = ArrayList()
// 1. 查找与 class 类名同名的 java 文件, 并追加到结果集合
val psiClasses = FilenameIndex.getFilesByName(
xmlfile.project, "$className.java", GlobalSearchScope.projectScope(xmlfile.project)
).toList()
JavaPsiFacade.getInstance(xmlfile.project).findClass("com.hyway.entity.Shop", element.resolveScope)
/** 构建样式 */
val builder: NavigationGutterIconBuilder<PsiElement> =
NavigationGutterIconBuilder.create(AllIcons.FileTypes.Java).setTargets(targets)
.setTooltipText("Navigate to Java resource").setAlignment(GutterIconRenderer.Alignment.RIGHT)
.setCellRenderer(MyJAVACellRenderer())
//构建根标签
for (psiClass in psiClasses)
{
if (psiClass is PsiJavaFile){
var javaFile: PsiJavaFile=psiClass
val javaClasses = javaFile.classes
val javaClass = javaClasses[0]
if (javaClass.qualifiedName!! == tag!!.getAttributeValue("namespace"))
{
targets.add(javaClass)
result.add(builder.createLineMarkerInfo(tag))
}
}
}
val subTags = tag!!.subTags
if (targets.isEmpty()){
println("未匹配到对应Java实体类")
return
}
for (subTag in subTags)
{
val methodTargets: ArrayList<PsiElement> = ArrayList()
val psiElement = targets[0]
if (psiElement is PsiClass)
{
var psiClass: PsiClass = psiElement
val idAttribute = subTag.getAttributeValue("id")
val methods = psiClass.findMethodsByName(idAttribute,false)
for (method in methods)
{
methodTargets.add(method)
}
if(!methods.isEmpty())
{
val tagBuilder: NavigationGutterIconBuilder<PsiElement> =
NavigationGutterIconBuilder.create(AllIcons.FileTypes.Java).setTargets(methodTargets)
.setTooltipText("Navigate to Java resource")
.setAlignment(GutterIconRenderer.Alignment.RIGHT).setCellRenderer(MyJAVACellRenderer())
result.add(tagBuilder.createLineMarkerInfo(subTag!!))
}
}
}
}
class MyJAVACellRenderer : DefaultPsiElementCellRenderer()
{
override fun getElementText(element: PsiElement): String
{
val prefix = StringBuilder()
if (element is JsonProperty)
{
prefix.append("Found Java! ")
}
return prefix.append(super.getElementText(element)).toString()
}
override fun getIcon(element: PsiElement): Icon
{
return AllIcons.FileTypes.Java
}
}
}