mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[maven][IDEA-382043] reading plugin model build by maven-plugin-tools 4.0
Merge-request: IJ-MR-182407 Merged-by: Aleksandr Bubenchikov <alexander.bubenchikov@jetbrains.com> GitOrigin-RevId: 5d6f1dad86988fd8b80ba4ee753d7379890b5c73
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a6337bdc13
commit
388d08b91c
+48
-15
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.maven.dom;
|
||||
|
||||
import com.intellij.openapi.util.IntellijInternalApi;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -16,6 +17,7 @@ import com.intellij.util.xml.XmlName;
|
||||
import com.intellij.util.xml.reflect.DomExtender;
|
||||
import com.intellij.util.xml.reflect.DomExtension;
|
||||
import com.intellij.util.xml.reflect.DomExtensionsRegistrar;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.maven.dom.converters.MavenDomConvertersRegistry;
|
||||
@@ -29,18 +31,30 @@ import org.jetbrains.idea.maven.dom.plugin.MavenDomPluginModel;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class MavenPluginConfigurationDomExtender extends DomExtender<MavenDomConfiguration> {
|
||||
public static final Key<ParameterData> PLUGIN_PARAMETER_KEY = Key.create("MavenPluginConfigurationDomExtender.PLUGIN_PARAMETER_KEY");
|
||||
|
||||
private static final Set<String> COLLECTIONS_TYPE_NAMES = Set.of("java.util.Collection", CommonClassNames.JAVA_UTIL_SET,
|
||||
CommonClassNames.JAVA_UTIL_LIST,
|
||||
"java.util.ArrayList", "java.util.HashSet",
|
||||
CommonClassNames.JAVA_UTIL_LINKED_LIST);
|
||||
CommonClassNames.JAVA_UTIL_LIST,
|
||||
"java.util.ArrayList", "java.util.HashSet",
|
||||
CommonClassNames.JAVA_UTIL_LINKED_LIST);
|
||||
private final Function<@NotNull MavenDomConfiguration, @Nullable MavenDomPluginModel> myRetriever;
|
||||
|
||||
@IntellijInternalApi
|
||||
@ApiStatus.Internal
|
||||
public MavenPluginConfigurationDomExtender(Function<@NotNull MavenDomConfiguration, @Nullable MavenDomPluginModel> modelRetriever) {
|
||||
myRetriever = modelRetriever;
|
||||
}
|
||||
|
||||
public MavenPluginConfigurationDomExtender() {
|
||||
this(MavenPluginDomUtil::getMavenPluginModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerExtensions(@NotNull MavenDomConfiguration config, @NotNull DomExtensionsRegistrar r) {
|
||||
MavenDomPluginModel pluginModel = MavenPluginDomUtil.getMavenPluginModel(config);
|
||||
MavenDomPluginModel pluginModel = myRetriever.apply(config);
|
||||
if (pluginModel == null) {
|
||||
r.registerCustomChildrenExtension(MavenDomConfigurationParameter.class);
|
||||
return;
|
||||
@@ -68,6 +82,7 @@ public final class MavenPluginConfigurationDomExtender extends DomExtender<Maven
|
||||
return pluginManagementTag instanceof XmlTag && "pluginManagement".equals(((XmlTag)pluginManagementTag).getName());
|
||||
}
|
||||
|
||||
|
||||
private static Collection<ParameterData> collectParameters(MavenDomPluginModel pluginModel, MavenDomConfiguration config) {
|
||||
List<String> selectedGoals = null;
|
||||
|
||||
@@ -94,12 +109,13 @@ public final class MavenPluginConfigurationDomExtender extends DomExtender<Maven
|
||||
if (goal == null) continue;
|
||||
|
||||
if (selectedGoals == null || selectedGoals.contains(goal)) {
|
||||
var mojoConfig = getMojoConfigurationAsMap(eachMojo);
|
||||
for (MavenDomParameter eachParameter : eachMojo.getParameters().getParameters()) {
|
||||
String name = eachParameter.getName().getStringValue();
|
||||
if (name == null) continue;
|
||||
|
||||
ParameterData data = new ParameterData(eachParameter);
|
||||
fillParameterData(name, data, eachMojo);
|
||||
fillParameterData(name, data, mojoConfig);
|
||||
|
||||
ParameterData oldParameter = namesWithParameters.get(name);
|
||||
if (oldParameter == null || hasMorePriority(data, oldParameter, executionElement != null)) {
|
||||
@@ -122,17 +138,31 @@ public final class MavenPluginConfigurationDomExtender extends DomExtender<Maven
|
||||
return d1.getRequiringLevel() > d2.getRequiringLevel();
|
||||
}
|
||||
|
||||
private static void fillParameterData(String name, ParameterData data, MavenDomMojo mojo) {
|
||||
XmlTag config = mojo.getConfiguration().getXmlTag();
|
||||
if (config == null) return;
|
||||
|
||||
private static Map<String, XmlTag> getMojoConfigurationAsMap(MavenDomMojo mojo) {
|
||||
if (mojo == null) return Collections.emptyMap();
|
||||
var config = mojo.getConfiguration().getXmlTag();
|
||||
if (config == null) return Collections.emptyMap();
|
||||
Map<String, XmlTag> result = new HashMap<>();
|
||||
for (XmlTag each : config.getSubTags()) {
|
||||
if (!name.equals(each.getName())) continue;
|
||||
data.defaultValue = each.getAttributeValue("default-value");
|
||||
data.expression = each.getValue().getTrimmedText();
|
||||
result.put(each.getName(), each);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void fillParameterData(String name, ParameterData data, Map<String, XmlTag> mojoConfig) {
|
||||
XmlTag configForMaven3 = mojoConfig.get(name);
|
||||
if (configForMaven3 != null) {
|
||||
data.defaultValue = configForMaven3.getAttributeValue("default-value");
|
||||
data.expression = configForMaven3.getValue().getTrimmedText();
|
||||
}
|
||||
else {
|
||||
data.defaultValue = data.parameter.getDefaultValue().getStringValue();
|
||||
data.expression = data.parameter.getExpression().getStringValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void registerPluginParameter(boolean isInPluginManagement, DomExtensionsRegistrar r, final ParameterData parameter) {
|
||||
String paramName = parameter.parameter.getName().getStringValue();
|
||||
String alias = parameter.parameter.getAlias().getStringValue();
|
||||
@@ -141,7 +171,10 @@ public final class MavenPluginConfigurationDomExtender extends DomExtender<Maven
|
||||
if (alias != null) registerPluginParameter(isInPluginManagement, r, parameter, alias);
|
||||
}
|
||||
|
||||
private static void registerPluginParameter(boolean isInPluginManagement, DomExtensionsRegistrar r, final ParameterData data, final String parameterName) {
|
||||
private static void registerPluginParameter(boolean isInPluginManagement,
|
||||
DomExtensionsRegistrar r,
|
||||
final ParameterData data,
|
||||
final String parameterName) {
|
||||
DomExtension e = r.registerFixedNumberChildExtension(new XmlName(parameterName), MavenDomConfigurationParameter.class);
|
||||
|
||||
if (isCollection(data.parameter)) {
|
||||
@@ -178,7 +211,7 @@ public final class MavenPluginConfigurationDomExtender extends DomExtender<Maven
|
||||
if (Boolean.parseBoolean(data.parameter.getRequired().getStringValue())
|
||||
&& StringUtil.isEmptyOrSpaces(data.defaultValue)
|
||||
&& StringUtil.isEmptyOrSpaces(data.expression)) {
|
||||
e.addCustomAnnotation(new Required(){
|
||||
e.addCustomAnnotation(new Required() {
|
||||
@Override
|
||||
public boolean value() {
|
||||
return true;
|
||||
@@ -193,9 +226,10 @@ public final class MavenPluginConfigurationDomExtender extends DomExtender<Maven
|
||||
public boolean identifier() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return Required.class;
|
||||
return Required.class;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -243,5 +277,4 @@ public final class MavenPluginConfigurationDomExtender extends DomExtender<Maven
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
@@ -35,5 +35,17 @@ public interface MavenDomParameter extends MavenDomElement {
|
||||
@NotNull
|
||||
GenericDomValue<String> getDescription();
|
||||
|
||||
/**
|
||||
* since maven-plugin-tools 4.0
|
||||
*/
|
||||
@NotNull
|
||||
GenericDomValue<String> getDefaultValue();
|
||||
|
||||
/**
|
||||
* since maven-plugin-tools 4.0
|
||||
*/
|
||||
@NotNull
|
||||
GenericDomValue<String> getExpression();
|
||||
|
||||
GenericDomValue<Boolean> getRequired();
|
||||
}
|
||||
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.maven.dom
|
||||
|
||||
import com.intellij.maven.testFramework.MavenDomTestCase
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.io.StreamUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.ResourceUtil
|
||||
import com.intellij.util.xml.Converter
|
||||
import com.intellij.util.xml.DomElement
|
||||
import com.intellij.util.xml.Required
|
||||
import com.intellij.util.xml.XmlName
|
||||
import com.intellij.util.xml.reflect.CustomDomChildrenDescription
|
||||
import com.intellij.util.xml.reflect.DomExtender
|
||||
import com.intellij.util.xml.reflect.DomExtension
|
||||
import com.intellij.util.xml.reflect.DomExtensionsRegistrar
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.idea.maven.dom.plugin.MavenDomPluginModel
|
||||
import org.junit.Test
|
||||
import java.lang.reflect.Type
|
||||
import java.util.function.Supplier
|
||||
|
||||
class MavenPluginConfigurationDomExtenderTest : MavenDomTestCase() {
|
||||
|
||||
@Test
|
||||
fun testShouldCorrectlyAddTagsForMaven3Plugin() = runBlocking {
|
||||
assumeMaven3()
|
||||
doTestWith(pluginModelFileName = "compiler-3-14-1.xml")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testShouldCorrectlyAddTagsForMaven4Plugin() = runBlocking {
|
||||
assumeMaven4()
|
||||
doTestWith(pluginModelFileName = "compiler-4-0-beta3.xml")
|
||||
}
|
||||
|
||||
private suspend fun doTestWith(pluginModelFileName: String) {
|
||||
importProjectAsync("""
|
||||
<groupId>test</groupId>
|
||||
<artifactId>test</artifactId>
|
||||
<version>1</version>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<compilerArgs>
|
||||
<arg>-some-arg</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
"""
|
||||
)
|
||||
|
||||
val pluginFile = createFromFile(pluginModelFileName, "plugin-test/$pluginModelFileName")
|
||||
readAction {
|
||||
val dom = MavenDomUtil.getMavenDomProjectModel(project, projectPom)!!
|
||||
val compilerConfiguration = dom
|
||||
.build
|
||||
.plugins
|
||||
.plugins
|
||||
.single { it.artifactId.stringValue == "maven-compiler-plugin" }
|
||||
.configuration
|
||||
|
||||
val pluginFileModel = MavenDomUtil.getMavenDomModel(project, pluginFile, MavenDomPluginModel::class.java)
|
||||
val extender = MavenPluginConfigurationDomExtender {
|
||||
pluginFileModel
|
||||
}
|
||||
val registeredExtensions = ArrayList<MyDomExtention>()
|
||||
val registrar = MyRegistrar(registeredExtensions)
|
||||
|
||||
extender.registerExtensions(compilerConfiguration, registrar)
|
||||
val basedir2ForTest = registeredExtensions.singleOrNull() { it.xmlName.localName == "basedir2ForTest" }
|
||||
assertNotNull(basedir2ForTest)
|
||||
assertEquals(1, basedir2ForTest!!.customAnnotations.size)
|
||||
assertTrue(basedir2ForTest.customAnnotations[0] is Required)
|
||||
|
||||
val basedir = registeredExtensions.singleOrNull() { it.xmlName.localName == "basedir" }
|
||||
assertNotNull(basedir)
|
||||
assertEmpty(basedir!!.customAnnotations)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFromFile(file: String, resourceName: String): VirtualFile {
|
||||
val result = ResourceUtil.getResourceAsStream(this::class.java.classLoader, "org/jetbrains/maven/", resourceName).use {
|
||||
StreamUtil.readBytes(it).toString(Charsets.UTF_8)
|
||||
}
|
||||
return createProjectSubFile(file, result)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class MyDomExtention(val xmlName: XmlName, private val type: Type) : DomExtension {
|
||||
var declaringElement: DomElement? = null
|
||||
var declaringElementFinder: Supplier<out DomElement?>? = null
|
||||
var declaringPsiElement: PsiElement? = null
|
||||
var converter: Converter<*>? = null
|
||||
var isSoft: Boolean = false
|
||||
val customAnnotations: MutableList<Annotation> = ArrayList()
|
||||
val userData: MutableMap<Key<*>, Any?> = HashMap()
|
||||
val extenders: MutableList<DomExtender<*>> = ArrayList()
|
||||
|
||||
override fun getType(): Type {
|
||||
return type
|
||||
}
|
||||
|
||||
override fun setDeclaringElement(declaringElement: DomElement): DomExtension {
|
||||
this.declaringElement = declaringElement
|
||||
return this
|
||||
}
|
||||
|
||||
override fun setDeclaringDomElement(declarationFinder: Supplier<out DomElement?>): DomExtension {
|
||||
this.declaringElementFinder = declarationFinder
|
||||
return this
|
||||
}
|
||||
|
||||
override fun setDeclaringElement(declaringElement: PsiElement): DomExtension {
|
||||
this.declaringPsiElement = declaringElement
|
||||
return this
|
||||
}
|
||||
|
||||
override fun setConverter(converter: Converter<*>): DomExtension {
|
||||
this.converter = converter
|
||||
return this
|
||||
}
|
||||
|
||||
override fun setConverter(converter: Converter<*>, soft: Boolean): DomExtension {
|
||||
this.converter = converter
|
||||
this.isSoft = soft
|
||||
return this
|
||||
}
|
||||
|
||||
override fun addCustomAnnotation(anno: Annotation): DomExtension {
|
||||
customAnnotations.add(anno)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun <T : Any?> putUserData(key: Key<T?>?, value: T?) {
|
||||
if (key != null) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(userData as MutableMap<Key<T?>, T?>)[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
override fun addExtender(extender: DomExtender<*>?): DomExtension {
|
||||
if (extender != null) {
|
||||
extenders.add(extender)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class MyRegistrar(val registeredExtensions: MutableList<MyDomExtention>) : DomExtensionsRegistrar {
|
||||
override fun registerFixedNumberChildExtension(name: XmlName, type: Type): DomExtension {
|
||||
return MyDomExtention(name, type).also { registeredExtensions.add(it) }
|
||||
}
|
||||
|
||||
override fun registerCollectionChildrenExtension(name: XmlName, type: Type): DomExtension {
|
||||
return MyDomExtention(name, type).also { registeredExtensions.add(it) }
|
||||
}
|
||||
|
||||
override fun registerGenericAttributeValueChildExtension(name: XmlName, parameterType: Type?): DomExtension {
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun registerAttributeChildExtension(name: XmlName, type: Type): DomExtension {
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun registerCustomChildrenExtension(type: Type): DomExtension {
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun registerCustomChildrenExtension(type: Type, descriptor: CustomDomChildrenDescription.TagNameDescriptor): DomExtension {
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun registerCustomChildrenExtension(type: Type, attributeDescriptor: CustomDomChildrenDescription.AttributeDescriptor): DomExtension {
|
||||
TODO()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+1423
File diff suppressed because it is too large
Load Diff
+1313
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user