Skip to content

Commit 4997abf

Browse files
committed
fix: application.properties: Unrecognized property 'quarkus.log.level',
it is not referenced in any Java files microprofile (unknown) See redhat-developer/intellij-quarkus#1480 Signed-off-by: azerr <[email protected]>
1 parent 429543f commit 4997abf

File tree

4 files changed

+73
-35
lines changed

4 files changed

+73
-35
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.acme.classes;
2+
3+
import java.util.Map;
4+
5+
import io.smallrye.config.ConfigMapping;
6+
import java.util.logging.Level;
7+
8+
@ConfigMapping(prefix = "server.classes")
9+
public interface ServerClass {
10+
11+
Level level();
12+
}

quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/config-mapping/src/main/java/org/acme/map/Server.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@
33
import java.util.Map;
44

55
import io.smallrye.config.ConfigMapping;
6+
import io.smallrye.config.WithName;
7+
import java.util.logging.Level;
68

79
@ConfigMapping(prefix = "server.map")
810
public interface Server {
911

10-
String host();
12+
String host();
1113

12-
int port();
14+
int port();
1315

14-
Map<String, String> form();
16+
Map<String, String> form();
17+
18+
@WithName("category")
19+
Map<String, CategoryConfig> categories();
20+
21+
interface CategoryConfig {
22+
Level level();
23+
}
1524
}

quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/src/main/java/com/redhat/microprofile/jdt/quarkus/configmapping/QuarkusConfigMappingTest.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ public void configMapping() throws Exception {
6666
p(null, "server.map.port", "int", null, false, "org.acme.map.Server", null, "port()I", 0, null),
6767
p(null, "server.map.form.{*}", "java.util.Map", null, false, "org.acme.map.Server", null,
6868
"form()QMap<QString;QString;>;", 0, null),
69+
p(null, "server.map.category.{*}.level", "java.util.logging.Level", null, false, "org.acme.map.Server$CategoryConfig", null,
70+
"level()QLevel;", 0, null),
6971

7072
// 3) Naming strategy
7173

@@ -150,7 +152,21 @@ public void configMapping() throws Exception {
150152
p(null, "server.withparentname.port", "int", null, false, "org.acme.withparentname.ServerHostAndPort",
151153
null, "port()I", 0, null),
152154
p(null, "server.withparentname.name", "java.lang.String", null, false,
153-
"org.acme.withparentname.ServerInfo", null, "name()QString;", 0, null)
155+
"org.acme.withparentname.ServerInfo", null, "name()QString;", 0, null),
156+
157+
// 9) Class
158+
// import java.util.logging.Level;
159+
//
160+
// @ConfigMapping(prefix = "server.classes")
161+
// public interface Server {
162+
//
163+
// Level level;
164+
//}
165+
//}
166+
167+
p(null, "server.classes.level", "java.util.logging.Level", null, false, "org.acme.classes.ServerClass", null,
168+
"level()QLevel;", 0, null)
169+
154170

155171
);
156172

quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/core/properties/QuarkusConfigMappingProvider.java

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
import static org.eclipse.lsp4mp.jdt.core.utils.JDTTypeUtils.getSourceMethod;
3232
import static org.eclipse.lsp4mp.jdt.core.utils.JDTTypeUtils.getSourceType;
3333
import static org.eclipse.lsp4mp.jdt.core.utils.JDTTypeUtils.isOptional;
34-
import static org.eclipse.lsp4mp.jdt.core.utils.JDTTypeUtils.isPrimitiveType;
3534

3635
import java.util.ArrayList;
3736
import java.util.Arrays;
37+
import java.util.Collections;
3838
import java.util.HashSet;
3939
import java.util.List;
4040
import java.util.Set;
@@ -111,17 +111,27 @@ private void processConfigMapping(IJavaElement javaElement, IAnnotation configMa
111111
return;
112112
}
113113
// @ConfigMapping(prefix="server") case
114-
List<IType> allInterfaces = new ArrayList<>(Arrays.asList(findInterfaces(configMappingType, monitor)));
115-
allInterfaces.add(0, configMappingType);
114+
// @ConfigMapping(prefix="server") case
115+
Set<IType> allInterfaces = findInterfaces(configMappingType, monitor);
116116
for (IType configMappingInterface : allInterfaces) {
117117
populateConfigObject(configMappingInterface, prefix, extensionName, new HashSet<>(),
118118
configMappingAnnotation, collector, monitor);
119119
}
120120
}
121121

122-
private static IType[] findInterfaces(IType type, IProgressMonitor progressMonitor) throws JavaModelException {
122+
private static Set<IType> findInterfaces(IType type, IProgressMonitor progressMonitor) throws JavaModelException {
123+
// No reason to use a JDK interface to generate a config class? Primarily to fix the java.nio.file.Path case.
124+
// see https://github.com/smallrye/smallrye-config/blob/22635f24dc7634706867cc52e28d5bd82d15f54e/implementation/src/main/java/io/smallrye/config/ConfigMappingInterface.java#L782C9-L783C58
125+
if (type.getFullyQualifiedName() == null || type.getFullyQualifiedName().startsWith("java")) {
126+
return Collections.emptySet();
127+
}
128+
Set<IType> result = new HashSet<>();
129+
result.add(type);
130+
123131
ITypeHierarchy typeHierarchy = type.newSupertypeHierarchy(progressMonitor);
124-
return typeHierarchy.getAllSuperInterfaces(type);
132+
IType[] allSuperInterfaces = typeHierarchy.getAllSuperInterfaces(type);
133+
result.addAll(Arrays.asList(allSuperInterfaces));
134+
return result;
125135
}
126136

127137
private void populateConfigObject(IType configMappingType, String prefixStr, String extensionName,
@@ -156,22 +166,7 @@ private void populateConfigObject(IType configMappingType, String prefixStr, Str
156166
}
157167

158168
IType returnType = findType(method.getJavaProject(), resolvedTypeSignature);
159-
boolean simpleType = isSimpleType(resolvedTypeSignature, returnType);
160-
if (!simpleType) {
161-
if (returnType != null && !returnType.isInterface()) {
162-
// When type is not an interface, it requires Converters
163-
// ex :
164-
// interface Server {Log log; class Log {}}
165-
// throw the error;
166-
// java.lang.IllegalArgumentException: SRCFG00013: No Converter registered for
167-
// class org.acme.Server2$Log
168-
// at
169-
// io.smallrye.config.SmallRyeConfig.requireConverter(SmallRyeConfig.java:466)
170-
// at
171-
// io.smallrye.config.ConfigMappingContext.getConverter(ConfigMappingContext.java:113)
172-
continue;
173-
}
174-
}
169+
boolean leafType = isLeafType(returnType);
175170

176171
String defaultValue = getWithDefault(method);
177172
String propertyName = getPropertyName(method, prefixStr, configMappingAnnotation);
@@ -190,27 +185,26 @@ private void populateConfigObject(IType configMappingType, String prefixStr, Str
190185
IType enclosedType = getEnclosedType(returnType, resolvedTypeSignature, method.getJavaProject());
191186
super.updateHint(collector, enclosedType);
192187

193-
if (!simpleType) {
188+
if (!leafType) {
194189
if (isMap(returnType, resolvedTypeSignature)) {
195190
// Map<String, String>
196191
propertyName += ".{*}";
197-
simpleType = true;
192+
leafType = true;
198193
} else if (isCollection(returnType, resolvedTypeSignature)) {
199194
// List<String>, List<App>
200195
propertyName += "[*]"; // Generate indexed property.
201-
String[] typeArguments = org.eclipse.jdt.core.Signature
202-
.getTypeArguments(returnTypeSignature);
196+
String[] typeArguments = org.eclipse.jdt.core.Signature.getTypeArguments(returnTypeSignature);
203197
if (typeArguments.length < 1) {
204198
continue;
205199
}
206200
String genericTypeName = typeArguments[0];
207201
resolvedTypeSignature = JavaModelUtil.getResolvedTypeName(genericTypeName, configMappingType);
208202
returnType = findType(method.getJavaProject(), resolvedTypeSignature);
209-
simpleType = isSimpleType(resolvedTypeSignature, returnType);
203+
leafType = isLeafType(returnType);
210204
}
211205
}
212206

213-
if (simpleType) {
207+
if (leafType) {
214208
// String, int, etc
215209
ItemMetadata metadata = super.addItemMetadata(collector, propertyName, type, description,
216210
sourceType, null, sourceMethod, defaultValue, extensionName, method.isBinary());
@@ -224,8 +218,15 @@ private void populateConfigObject(IType configMappingType, String prefixStr, Str
224218
}
225219
}
226220

227-
private boolean isSimpleType(String resolvedTypeSignature, IType returnType) {
228-
return returnType == null || isPrimitiveType(resolvedTypeSignature);
221+
/**
222+
* Returns true if the given return type should be treated as a leaf in the
223+
* configuration tree, i.e. it is null or not an interface, and therefore not
224+
* recursively visited.
225+
*
226+
* @throws JavaModelException
227+
*/
228+
private static boolean isLeafType(IType returnType) throws JavaModelException {
229+
return returnType == null || !returnType.isInterface();
229230
}
230231

231232
private static boolean isMap(IType type, String typeName) {
@@ -276,7 +277,7 @@ private static String convertName(IMember member, IAnnotation configMappingAnnot
276277
// public interface ServerVerbatimNamingStrategy
277278
// --> See https://quarkus.io/guides/config-mappings#namingstrategy
278279
NamingStrategy namingStrategy = getNamingStrategy(configMappingAnnotation);
279-
if (namingStrategy != null) {
280+
if (namingStrategy != null) {
280281
switch (namingStrategy) {
281282
case VERBATIM:
282283
// The method name is used as is to map the configuration property.
@@ -321,7 +322,7 @@ private static NamingStrategy getNamingStrategy(IAnnotation configMappingAnnotat
321322
}
322323
return null;
323324
}
324-
325+
325326
/**
326327
* Returns the value of @WithDefault("a value") and null otherwise.
327328
*

0 commit comments

Comments
 (0)