{"results":{"result":{"added-files":{"code-health":9.758586501510505,"old-code-health":0.0,"files":[{"file":"jsonschema-module-microprofile-openapi-3/src/main/java/com/github/victools/jsonschema/module/microprofile/openapi3/ExternalRefCustomDefinitionProvider.java","loc":31,"code-health":10.0},{"file":"jsonschema-module-microprofile-openapi-3/src/main/java/com/github/victools/jsonschema/module/microprofile/openapi3/MicroProfileOpenApi3AnyOfResolver.java","loc":22,"code-health":10.0},{"file":"jsonschema-module-microprofile-openapi-3/src/main/java/com/github/victools/jsonschema/module/microprofile/openapi3/MicroProfileOpenApi3Module.java","loc":295,"code-health":9.6882083290695},{"file":"jsonschema-module-microprofile-openapi-3/src/main/java/com/github/victools/jsonschema/module/microprofile/openapi3/MicroProfileOpenApi3SchemaDefinitionNamingStrategy.java","loc":33,"code-health":10.0}]},"external-review-url":"https://github.com/victools/jsonschema-generator/pull/483","old-code-health":9.6882083290695,"modified-files":{"code-health":9.6882083290695,"old-code-health":9.6882083290695,"files":[{"file":"jsonschema-maven-plugin/src/main/java/com/github/victools/jsonschema/plugin/maven/SchemaGeneratorMojo.java","loc":347,"old-loc":341,"code-health":9.6882083290695,"old-code-health":9.6882083290695}]},"removed-files":{"code-health":0.0,"old-code-health":0.0,"files":[]},"external-review-id":"483","analysis-time":"2024-10-12T20:41:15Z","negative-impact-count":1,"suppressions":{"number-of-types":0,"number-of-files-touched":0,"findings":[]},"affected-hotspots":1,"commits":["7db58312a4e8618c6c41992e0263b28e4cdc5dc3","dcfbc92fae8ba1a6232ae8c776c710c53bcf1b76","0a2f8583bd6c3e96ef5a4faba0b205848d11c185","84ae8195d2bca090f59102bf937f98131401e6be"],"is-negative-review":false,"negative-findings":{"number-of-types":1,"number-of-files-touched":1,"findings":[{"method":"overrideInstanceAttributes","why-it-occurs":"A Complex Method has a high cyclomatic complexity. The recommended threshold for the Java language is a cyclomatic complexity lower than 9.","name":"Complex Method","file":"jsonschema-module-microprofile-openapi-3/src/main/java/com/github/victools/jsonschema/module/microprofile/openapi3/MicroProfileOpenApi3Module.java","refactoring-examples":[{"architectural-component-id":null,"author-name":"Carsten Wickner","training-data":{"loc-added":"3","loc-deleted":"8","delta-cc-mean":"0.0","delta-cc-total":"0","delta-penalties":"1.0","delta-n-functions":"0","current-file-score":"10.0"},"author-email":"11309681+CarstenWickner@users.noreply.github.com","commit-full-message":"","commit-date":"2023-11-19T23:52:45Z","current-rev":"41c991f","filename":"jsonschema-generator/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/AdditionalPropertiesModule.java","previous-rev":"581a4ac","commit-title":"chore: further code health refactoring (#414)","language":"Java","id":"e8ec0d5edf110d645a00d287c6f619c3449ca933","model-score":0.77,"author-id":null,"project-id":42616,"delta-file-score":0.31179166,"diff":"diff --git a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/AdditionalPropertiesModule.java b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/AdditionalPropertiesModule.java\nindex 0467373..8d04c6d 100644\n--- a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/AdditionalPropertiesModule.java\n+++ b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/AdditionalPropertiesModule.java\n@@ -66,10 +66,5 @@ public class AdditionalPropertiesModule implements Module {\n         }\n-        MemberScope<?, ?> mapValueScope = member.asFakeContainerItemScope(Map.class, 1);\n-        if (mapValueScope instanceof FieldScope) {\n-            return context.createStandardDefinitionReference((FieldScope) mapValueScope, null);\n-        }\n-        if (mapValueScope instanceof MethodScope) {\n-            return context.createStandardDefinitionReference((MethodScope) mapValueScope, null);\n-        }\n-        throw new IllegalStateException(\"Unsupported member scope type: \" + member.getClass());\n+        return member.getContext().performActionOnMember(member.asFakeContainerItemScope(Map.class, 1),\n+                field -> context.createStandardDefinitionReference(field, null),\n+                method -> context.createStandardDefinitionReference(method, null));\n     }\n","improvement-type":"Complex Method"},{"architectural-component-id":null,"author-name":"Carsten Wickner","training-data":{"loc-added":"14","loc-deleted":"8","delta-cc-mean":"0.0","delta-cc-total":"0","delta-penalties":"1.0","delta-n-functions":"0","current-file-score":"9.6882083290695"},"author-email":"11309681+CarstenWickner@users.noreply.github.com","commit-full-message":"* chore: further refactor maven plugin\r\n\r\n* chore: refactoring of generation context\r\n\r\n* feat: add cache for types with members\r\n\r\n* chore: reduce GlobHandler complexity","commit-date":"2023-11-15T20:54:31Z","current-rev":"0daa090","filename":"jsonschema-generator/jsonschema-module-jackson/src/main/java/com/github/victools/jsonschema/module/jackson/JacksonModule.java","previous-rev":"c1744cf","commit-title":"chore: further refactoring for code health improvement (#406)","language":"Java","id":"22651b6ee33e53be4c4777007a9f8003b95323b6","model-score":0.64,"author-id":null,"project-id":42616,"delta-file-score":0.3009901,"diff":"diff --git a/jsonschema-module-jackson/src/main/java/com/github/victools/jsonschema/module/jackson/JacksonModule.java b/jsonschema-module-jackson/src/main/java/com/github/victools/jsonschema/module/jackson/JacksonModule.java\nindex 0a4852e..1d88760 100644\n--- a/jsonschema-module-jackson/src/main/java/com/github/victools/jsonschema/module/jackson/JacksonModule.java\n+++ b/jsonschema-module-jackson/src/main/java/com/github/victools/jsonschema/module/jackson/JacksonModule.java\n@@ -114,17 +114,3 @@ public class JacksonModule implements Module {\n \n-        boolean lookUpSubtypes = !this.options.contains(JacksonOption.SKIP_SUBTYPE_LOOKUP);\n-        boolean includeTypeInfoTransform = !this.options.contains(JacksonOption.IGNORE_TYPE_INFO_TRANSFORM);\n-        if (lookUpSubtypes || includeTypeInfoTransform) {\n-            JsonSubTypesResolver subtypeResolver = new JsonSubTypesResolver(this.options);\n-            if (lookUpSubtypes) {\n-                generalConfigPart.withSubtypeResolver(subtypeResolver);\n-                fieldConfigPart.withTargetTypeOverridesResolver(subtypeResolver::findTargetTypeOverrides);\n-                methodConfigPart.withTargetTypeOverridesResolver(subtypeResolver::findTargetTypeOverrides);\n-            }\n-            if (includeTypeInfoTransform) {\n-                generalConfigPart.withCustomDefinitionProvider(subtypeResolver);\n-                fieldConfigPart.withCustomDefinitionProvider(subtypeResolver::provideCustomPropertySchemaDefinition);\n-                methodConfigPart.withCustomDefinitionProvider(subtypeResolver::provideCustomPropertySchemaDefinition);\n-            }\n-        }\n+        applySubtypeResolverToConfigBuilder(generalConfigPart, fieldConfigPart, methodConfigPart);\n \n@@ -133,2 +119,22 @@ public class JacksonModule implements Module {\n \n+    private void applySubtypeResolverToConfigBuilder(SchemaGeneratorGeneralConfigPart generalConfigPart,\n+            SchemaGeneratorConfigPart<FieldScope> fieldConfigPart, SchemaGeneratorConfigPart<MethodScope> methodConfigPart) {\n+        boolean skipLookUpSubtypes = this.options.contains(JacksonOption.SKIP_SUBTYPE_LOOKUP);\n+        boolean skipTypeInfoTransform = this.options.contains(JacksonOption.IGNORE_TYPE_INFO_TRANSFORM);\n+        if (skipLookUpSubtypes && skipTypeInfoTransform) {\n+            return;\n+        }\n+        JsonSubTypesResolver subtypeResolver = new JsonSubTypesResolver(this.options);\n+        if (!skipLookUpSubtypes) {\n+            generalConfigPart.withSubtypeResolver(subtypeResolver);\n+            fieldConfigPart.withTargetTypeOverridesResolver(subtypeResolver::findTargetTypeOverrides);\n+            methodConfigPart.withTargetTypeOverridesResolver(subtypeResolver::findTargetTypeOverrides);\n+        }\n+        if (!skipTypeInfoTransform) {\n+            generalConfigPart.withCustomDefinitionProvider(subtypeResolver);\n+            fieldConfigPart.withCustomDefinitionProvider(subtypeResolver::provideCustomPropertySchemaDefinition);\n+            methodConfigPart.withCustomDefinitionProvider(subtypeResolver::provideCustomPropertySchemaDefinition);\n+        }\n+    }\n+\n     /**\n","improvement-type":"Complex Method"},{"architectural-component-id":null,"author-name":"Carsten Wickner","training-data":{"loc-added":"21","loc-deleted":"13","delta-cc-mean":"0.0","delta-cc-total":"0","delta-penalties":"1.0","delta-n-functions":"0","current-file-score":"9.387218218812514"},"author-email":"11309681+CarstenWickner@users.noreply.github.com","commit-full-message":"* chore: further refactor maven plugin\r\n\r\n* chore: refactoring of generation context\r\n\r\n* feat: add cache for types with members\r\n\r\n* chore: reduce GlobHandler complexity","commit-date":"2023-11-15T20:54:31Z","current-rev":"0daa090","filename":"jsonschema-generator/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/MethodScope.java","previous-rev":"c1744cf","commit-title":"chore: further refactoring for code health improvement (#406)","language":"Java","id":"29c3f5e0e0d63197451e080cc3a9282e0347d4b0","model-score":0.49,"author-id":null,"project-id":42616,"delta-file-score":0.43204725,"diff":"diff --git a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/MethodScope.java b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/MethodScope.java\nindex 0d92bdf..1a027a8 100644\n--- a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/MethodScope.java\n+++ b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/MethodScope.java\n@@ -135,21 +135,5 @@ public class MethodScope extends MemberScope<ResolvedMethod, Method> {\n         if (methodName.startsWith(\"get\")) {\n-            if (methodName.length() > 3 && Character.isUpperCase(methodName.charAt(3))) {\n-                // ensure that the variable starts with a lower-case letter\n-                possibleFieldNames.add(methodName.substring(3, 4).toLowerCase() + methodName.substring(4));\n-            }\n-            // @since 4.32.0 - conforming with JavaBeans API specification edge case when second character in field name is in uppercase\n-            if (methodName.length() > 4 && Character.isUpperCase(methodName.charAt(4))) {\n-                possibleFieldNames.add(methodName.substring(3));\n-            }\n+            getPossibleFieldNamesStartingWithGet(methodName, possibleFieldNames);\n         } else if (methodName.startsWith(\"is\")) {\n-            if (methodName.length() > 2 && Character.isUpperCase(methodName.charAt(2))) {\n-                // ensure that the variable starts with a lower-case letter\n-                possibleFieldNames.add(methodName.substring(2, 3).toLowerCase() + methodName.substring(3));\n-                // since 4.32.0: a method \"isBool()\" is considered a possible getter for a field \"isBool\" as well as for \"bool\"\n-                possibleFieldNames.add(methodName);\n-            }\n-            // @since 4.32.0 - conforming with JavaBeans API specification edge case when second character in field name is in uppercase\n-            if (methodName.length() > 3 && Character.isUpperCase(methodName.charAt(3))) {\n-                possibleFieldNames.add(methodName.substring(2));\n-            }\n+            getPossibleFieldNamesStartingWithIs(methodName, possibleFieldNames);\n         }\n@@ -168,2 +152,26 @@ public class MethodScope extends MemberScope<ResolvedMethod, Method> {\n \n+    private static void getPossibleFieldNamesStartingWithGet(String methodName, Set<String> possibleFieldNames) {\n+        if (methodName.length() > 3 && Character.isUpperCase(methodName.charAt(3))) {\n+            // ensure that the variable starts with a lower-case letter\n+            possibleFieldNames.add(methodName.substring(3, 4).toLowerCase() + methodName.substring(4));\n+        }\n+        // @since 4.32.0 - conforming with JavaBeans API specification edge case when second character in field name is in uppercase\n+        if (methodName.length() > 4 && Character.isUpperCase(methodName.charAt(4))) {\n+            possibleFieldNames.add(methodName.substring(3));\n+        }\n+    }\n+\n+    private static void getPossibleFieldNamesStartingWithIs(String methodName, Set<String> possibleFieldNames) {\n+        if (methodName.length() > 2 && Character.isUpperCase(methodName.charAt(2))) {\n+            // ensure that the variable starts with a lower-case letter\n+            possibleFieldNames.add(methodName.substring(2, 3).toLowerCase() + methodName.substring(3));\n+            // since 4.32.0: a method \"isBool()\" is considered a possible getter for a field \"isBool\" as well as for \"bool\"\n+            possibleFieldNames.add(methodName);\n+        }\n+        // @since 4.32.0 - conforming with JavaBeans API specification edge case when second character in field name is in uppercase\n+        if (methodName.length() > 3 && Character.isUpperCase(methodName.charAt(3))) {\n+            possibleFieldNames.add(methodName.substring(2));\n+        }\n+    }\n+\n     /**\n","improvement-type":"Complex Method"},{"architectural-component-id":null,"author-name":"Carsten Wickner","training-data":{"loc-added":"17","loc-deleted":"13","delta-cc-mean":"0.0","delta-cc-total":"0","delta-penalties":"1.0","delta-n-functions":"0","current-file-score":"8.031638343271364"},"author-email":"11309681+CarstenWickner@users.noreply.github.com","commit-full-message":"* chore: further refactor maven plugin\r\n\r\n* chore: refactoring of generation context\r\n\r\n* feat: add cache for types with members\r\n\r\n* chore: reduce GlobHandler complexity","commit-date":"2023-11-15T20:54:31Z","current-rev":"0daa090","filename":"jsonschema-generator/jsonschema-module-jakarta-validation/src/main/java/com/github/victools/jsonschema/module/jakarta/validation/JakartaValidationModule.java","previous-rev":"c1744cf","commit-title":"chore: further refactoring for code health improvement (#406)","language":"Java","id":"c7c74bb397b669b53fa7f5fdc53a981504043b78","model-score":0.31,"author-id":null,"project-id":42616,"delta-file-score":0.81631774,"diff":"diff --git a/jsonschema-module-jakarta-validation/src/main/java/com/github/victools/jsonschema/module/jakarta/validation/JakartaValidationModule.java b/jsonschema-module-jakarta-validation/src/main/java/com/github/victools/jsonschema/module/jakarta/validation/JakartaValidationModule.java\nindex 4e1889b..3bfc257 100644\n--- a/jsonschema-module-jakarta-validation/src/main/java/com/github/victools/jsonschema/module/jakarta/validation/JakartaValidationModule.java\n+++ b/jsonschema-module-jakarta-validation/src/main/java/com/github/victools/jsonschema/module/jakarta/validation/JakartaValidationModule.java\n@@ -52,4 +52,6 @@ import java.util.Map;\n import java.util.Set;\n+import java.util.function.BiPredicate;\n import java.util.function.Function;\n import java.util.function.Predicate;\n+import java.util.function.ToIntBiFunction;\n import java.util.stream.Stream;\n@@ -513,17 +515,19 @@ public class JakartaValidationModule implements Module {\n         }\n-        Integer mapMinEntries = this.resolveMapMinEntries(member);\n-        if (mapMinEntries != null) {\n-            String minPropertiesAttribute = context.getKeyword(SchemaKeyword.TAG_PROPERTIES_MIN);\n-            JsonNode existingValue = memberAttributes.get(minPropertiesAttribute);\n-            if (existingValue == null || (existingValue.isNumber() && existingValue.asInt() < mapMinEntries)) {\n-                memberAttributes.put(minPropertiesAttribute, mapMinEntries);\n-            }\n+        this.overrideMapPropertyCountAttribute(memberAttributes, context.getKeyword(SchemaKeyword.TAG_PROPERTIES_MIN),\n+                this.resolveMapMinEntries(member), Math::min);\n+        this.overrideMapPropertyCountAttribute(memberAttributes, context.getKeyword(SchemaKeyword.TAG_PROPERTIES_MAX),\n+                this.resolveMapMaxEntries(member), Math::max);\n+    }\n+\n+    private void overrideMapPropertyCountAttribute(ObjectNode memberAttributes, String attribute, Integer newValue,\n+            ToIntBiFunction<Integer, Integer> getStricterValue) {\n+        if (newValue == null) {\n+            return;\n         }\n-        Integer mapMaxEntries = this.resolveMapMaxEntries(member);\n-        if (mapMaxEntries != null) {\n-            String maxPropertiesAttribute = context.getKeyword(SchemaKeyword.TAG_PROPERTIES_MAX);\n-            JsonNode existingValue = memberAttributes.get(maxPropertiesAttribute);\n-            if (existingValue == null || (existingValue.isNumber() && existingValue.asInt() > mapMaxEntries)) {\n-                memberAttributes.put(maxPropertiesAttribute, mapMaxEntries);\n-            }\n+        JsonNode existingValue = memberAttributes.get(attribute);\n+        boolean shouldSetNewValue = existingValue == null\n+                || !existingValue.isNumber()\n+                || newValue == getStricterValue.applyAsInt(newValue, existingValue.asInt());\n+        if (shouldSetNewValue) {\n+            memberAttributes.put(attribute, newValue);\n         }\n","improvement-type":"Complex Method"},{"architectural-component-id":null,"author-name":"Carsten Wickner","training-data":{"loc-added":"29","loc-deleted":"58","delta-cc-mean":"0.0","delta-cc-total":"0","delta-penalties":"1.0","delta-n-functions":"0","current-file-score":"9.6882083290695"},"author-email":"11309681+CarstenWickner@users.noreply.github.com","commit-full-message":"* chore: further refactor maven plugin\r\n\r\n* chore: refactoring of generation context\r\n\r\n* feat: add cache for types with members\r\n\r\n* chore: reduce GlobHandler complexity","commit-date":"2023-11-15T20:54:31Z","current-rev":"0daa090","filename":"jsonschema-generator/jsonschema-maven-plugin/src/main/java/com/github/victools/jsonschema/plugin/maven/SchemaGeneratorMojo.java","previous-rev":"c1744cf","commit-title":"chore: further refactoring for code health improvement (#406)","language":"Java","id":"913b9b0c93d2aef52bbff036031618d17ec6c54b","model-score":0.29,"author-id":null,"project-id":42616,"delta-file-score":1.27468,"diff":"diff --git a/jsonschema-maven-plugin/src/main/java/com/github/victools/jsonschema/plugin/maven/SchemaGeneratorMojo.java b/jsonschema-maven-plugin/src/main/java/com/github/victools/jsonschema/plugin/maven/SchemaGeneratorMojo.java\nindex 0b1610b..64a05f7 100644\n--- a/jsonschema-maven-plugin/src/main/java/com/github/victools/jsonschema/plugin/maven/SchemaGeneratorMojo.java\n+++ b/jsonschema-maven-plugin/src/main/java/com/github/victools/jsonschema/plugin/maven/SchemaGeneratorMojo.java\n@@ -21,3 +21,2 @@ import com.fasterxml.jackson.databind.ObjectMapper;\n import com.github.victools.jsonschema.generator.Module;\n-import com.github.victools.jsonschema.generator.Option;\n import com.github.victools.jsonschema.generator.OptionPreset;\n@@ -27,2 +26,3 @@ import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;\n import com.github.victools.jsonschema.generator.SchemaVersion;\n+import com.github.victools.jsonschema.generator.impl.Util;\n import com.github.victools.jsonschema.module.jackson.JacksonModule;\n@@ -58,3 +58,2 @@ import java.util.Set;\n import java.util.function.Function;\n-import java.util.function.IntFunction;\n import java.util.function.Predicate;\n@@ -184,20 +183,11 @@ public class SchemaGeneratorMojo extends AbstractMojo {\n \n-        if (this.classNames != null) {\n-            for (String className : this.classNames) {\n-                this.getLog().info(\"Generating JSON Schema for <className>\" + className + \"</className>\");\n-                this.generateSchema(className, false);\n-            }\n+        for (String className : Util.nullSafe(this.classNames)) {\n+            this.getLog().info(\"Generating JSON Schema for <className>\" + className + \"</className>\");\n+            this.generateSchema(className, false);\n         }\n-\n-        if (this.packageNames != null) {\n-            for (String packageName : this.packageNames) {\n-                this.getLog().info(\"Generating JSON Schema for <packageName>\" + packageName + \"</packageName>\");\n-                this.generateSchema(packageName, true);\n-            }\n+        for (String packageName : Util.nullSafe(this.packageNames)) {\n+            this.getLog().info(\"Generating JSON Schema for <packageName>\" + packageName + \"</packageName>\");\n+            this.generateSchema(packageName, true);\n         }\n-\n-        boolean classAndPackageEmpty = (this.classNames == null || this.classNames.length == 0)\n-                && (this.packageNames == null || this.packageNames.length == 0);\n-\n-        if (classAndPackageEmpty && this.annotations != null && !this.annotations.isEmpty()) {\n+        if (Util.isNullOrEmpty(this.classNames) && Util.isNullOrEmpty(this.packageNames) && !Util.isNullOrEmpty(this.annotations)) {\n             this.getLog().info(\"Generating JSON Schema for all annotated classes\");\n@@ -231,12 +221,3 @@ public class SchemaGeneratorMojo extends AbstractMojo {\n         if (matchingClasses.isEmpty()) {\n-            StringBuilder message = new StringBuilder(\"No matching class found for \\\"\")\n-                    .append(classOrPackageName)\n-                    .append(\"\\\" on classpath\");\n-            if (this.excludeClassNames != null && this.excludeClassNames.length > 0) {\n-                message.append(\" that wasn't excluded\");\n-            }\n-            if (this.failIfNoClassesMatch) {\n-                throw new MojoExecutionException(message.toString());\n-            }\n-            this.getLog().warn(message.toString());\n+            this.logForNoClassesMatchingFilter(classOrPackageName);\n         }\n@@ -257,2 +238,16 @@ public class SchemaGeneratorMojo extends AbstractMojo {\n \n+    private void logForNoClassesMatchingFilter(String classOrPackageName) throws MojoExecutionException {\n+        StringBuilder message = new StringBuilder(\"No matching class found for \\\"\")\n+                .append(classOrPackageName)\n+                .append(\"\\\" on classpath\");\n+        if (!Util.isNullOrEmpty(this.excludeClassNames)) {\n+            message.append(\" that wasn't excluded\");\n+        }\n+        if (this.failIfNoClassesMatch) {\n+            message.append(\".\\nYou can change this error to a warning by setting: <failIfNoClassesMatch>false</failIfNoClassesMatch>\");\n+            throw new MojoExecutionException(message.toString());\n+        }\n+        this.getLog().warn(message.toString());\n+    }\n+\n     /**\n@@ -297,10 +292,5 @@ public class SchemaGeneratorMojo extends AbstractMojo {\n     private ClassInfoList.ClassInfoFilter createClassInfoFilter(boolean considerAnnotations) {\n-        Set<Predicate<String>> exclusions;\n-        if (this.excludeClassNames == null || this.excludeClassNames.length == 0) {\n-            exclusions = Collections.emptySet();\n-        } else {\n-            exclusions = Stream.of(this.excludeClassNames)\n-                    .map(excludeEntry -> GlobHandler.createClassOrPackageNameFilter(excludeEntry, false))\n-                    .collect(Collectors.toSet());\n-        }\n+        Set<Predicate<String>> exclusions = Util.nullSafe(this.excludeClassNames).stream()\n+                .map(excludeEntry -> GlobHandler.createClassOrPackageNameFilter(excludeEntry, false))\n+                .collect(Collectors.toSet());\n         Set<Predicate<String>> inclusions;\n@@ -310,12 +300,8 @@ public class SchemaGeneratorMojo extends AbstractMojo {\n             inclusions = new HashSet<>();\n-            if (this.classNames != null) {\n-                Stream.of(this.classNames)\n-                        .map(className -> GlobHandler.createClassOrPackageNameFilter(className, false))\n-                        .forEach(inclusions::add);\n-            }\n-            if (this.packageNames != null) {\n-                Stream.of(this.packageNames)\n-                        .map(packageName -> GlobHandler.createClassOrPackageNameFilter(packageName, true))\n-                        .forEach(inclusions::add);\n-            }\n+            Util.nullSafe(this.classNames).stream()\n+                    .map(className -> GlobHandler.createClassOrPackageNameFilter(className, false))\n+                    .forEach(inclusions::add);\n+            Util.nullSafe(this.packageNames).stream()\n+                    .map(packageName -> GlobHandler.createClassOrPackageNameFilter(packageName, true))\n+                    .forEach(inclusions::add);\n         }\n@@ -430,17 +416,7 @@ public class SchemaGeneratorMojo extends AbstractMojo {\n     private void setOptions(SchemaGeneratorConfigBuilder configBuilder) {\n-        if (this.options == null) {\n-            return;\n-        }\n-        // Enable all the configured options\n-        if (this.options.enabled != null) {\n-            for (Option option : this.options.enabled) {\n-                configBuilder.with(option);\n-            }\n-        }\n-\n-        // Disable all the configured options\n-        if (this.options.disabled != null) {\n-            for (Option option : this.options.disabled) {\n-                configBuilder.without(option);\n-            }\n+        if (this.options != null) {\n+            // Enable all the configured options\n+            Util.nullSafe(this.options.enabled).forEach(configBuilder::with);\n+            // Disable all the configured options\n+            Util.nullSafe(this.options.disabled).forEach(configBuilder::without);\n         }\n@@ -456,9 +432,6 @@ public class SchemaGeneratorMojo extends AbstractMojo {\n     private void setModules(SchemaGeneratorConfigBuilder configBuilder) throws MojoExecutionException {\n-        if (this.modules == null) {\n-            return;\n-        }\n-        for (GeneratorModule module : this.modules) {\n-            if (module.className != null && !module.className.isEmpty()) {\n+        for (GeneratorModule module : Util.nullSafe(this.modules)) {\n+            if (!Util.isNullOrEmpty(module.className)) {\n                 this.addCustomModule(module.className, configBuilder);\n-            } else if (module.name != null) {\n+            } else if (!Util.isNullOrEmpty(module.name)) {\n                 this.addStandardModule(module, configBuilder);\n@@ -536,9 +509,7 @@ public class SchemaGeneratorMojo extends AbstractMojo {\n         Stream.Builder<T> optionStream = Stream.builder();\n-        if (module.options != null && module.options.length > 0) {\n-            for (String optionName : module.options) {\n-                try {\n-                    optionStream.add(Enum.valueOf(optionType, optionName));\n-                } catch (IllegalArgumentException e) {\n-                    throw new MojoExecutionException(\"Error: Unknown \" + module.name + \" option \" + optionName, e);\n-                }\n+        for (String optionName : Util.nullSafe(module.options)) {\n+            try {\n+                optionStream.add(Enum.valueOf(optionType, optionName));\n+            } catch (IllegalArgumentException e) {\n+                throw new MojoExecutionException(\"Error: Unknown \" + module.name + \" option \" + optionName, e);\n             }\n","improvement-type":"Complex Method"},{"architectural-component-id":null,"author-name":"Carsten Wickner","training-data":{"loc-added":"72","loc-deleted":"71","delta-cc-mean":"0.0","delta-cc-total":"0","delta-penalties":"2.43","delta-n-functions":"0","current-file-score":"10.0"},"author-email":"11309681+CarstenWickner@users.noreply.github.com","commit-full-message":"","commit-date":"2023-11-12T09:04:36Z","current-rev":"c1744cf","filename":"jsonschema-generator/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/AttributeCollector.java","previous-rev":"81470da","commit-title":"chore: refactor to improve code health (#405)","language":"Java","id":"7e4a9968c480c12c4346579a834d11c3669ef617","model-score":0.23,"author-id":null,"project-id":42616,"delta-file-score":2.7693207,"diff":"diff --git a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/AttributeCollector.java b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/AttributeCollector.java\nindex a2e2f71..5f09377 100644\n--- a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/AttributeCollector.java\n+++ b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/AttributeCollector.java\n@@ -38,2 +38,3 @@ import java.util.Set;\n import java.util.stream.Collectors;\n+import java.util.stream.Stream;\n import org.slf4j.Logger;\n@@ -150,3 +151,3 @@ public class AttributeCollector {\n         collector.setEnum(node, config.resolveEnumForType(scope), generationContext);\n-        if (allowedSchemaTypes.isEmpty() || allowedSchemaTypes.contains(config.getKeyword(SchemaKeyword.TAG_TYPE_OBJECT))) {\n+        if (isListEmptyOrContainingAtLeastOne(allowedSchemaTypes, config, SchemaKeyword.TAG_TYPE_OBJECT)) {\n             collector.setAdditionalProperties(node, config.resolveAdditionalPropertiesForType(scope, generationContext), generationContext);\n@@ -154,3 +155,3 @@ public class AttributeCollector {\n         }\n-        if (allowedSchemaTypes.isEmpty() || allowedSchemaTypes.contains(config.getKeyword(SchemaKeyword.TAG_TYPE_STRING))) {\n+        if (isListEmptyOrContainingAtLeastOne(allowedSchemaTypes, config, SchemaKeyword.TAG_TYPE_STRING)) {\n             collector.setStringMinLength(node, config.resolveStringMinLengthForType(scope), generationContext);\n@@ -160,4 +161,3 @@ public class AttributeCollector {\n         }\n-        if (allowedSchemaTypes.isEmpty() || allowedSchemaTypes.contains(config.getKeyword(SchemaKeyword.TAG_TYPE_INTEGER))\n-                || allowedSchemaTypes.contains(config.getKeyword(SchemaKeyword.TAG_TYPE_NUMBER))) {\n+        if (isListEmptyOrContainingAtLeastOne(allowedSchemaTypes, config, SchemaKeyword.TAG_TYPE_INTEGER, SchemaKeyword.TAG_TYPE_NUMBER)) {\n             collector.setNumberInclusiveMinimum(node, config.resolveNumberInclusiveMinimumForType(scope), generationContext);\n@@ -168,3 +168,3 @@ public class AttributeCollector {\n         }\n-        if (allowedSchemaTypes.isEmpty() || allowedSchemaTypes.contains(config.getKeyword(SchemaKeyword.TAG_TYPE_ARRAY))) {\n+        if (isListEmptyOrContainingAtLeastOne(allowedSchemaTypes, config, SchemaKeyword.TAG_TYPE_ARRAY)) {\n             collector.setArrayMinItems(node, config.resolveArrayMinItemsForType(scope), generationContext);\n@@ -176,2 +176,8 @@ public class AttributeCollector {\n \n+    private static boolean isListEmptyOrContainingAtLeastOne(Set<String> values, SchemaGeneratorConfig config, SchemaKeyword... keywords) {\n+        return values.isEmpty() || Stream.of(keywords)\n+                .map(config::getKeyword)\n+                .anyMatch(values::contains);\n+    }\n+\n     /**\n@@ -299,21 +305,3 @@ public class AttributeCollector {\n             final String defaultTag = SchemaKeyword.TAG_DEFAULT.forVersion(SchemaVersion.DRAFT_7);\n-            // need to specifically add simple/primitive values by type\n-            if (defaultValue instanceof String) {\n-                node.put(defaultTag, (String) defaultValue);\n-            } else if (defaultValue instanceof BigDecimal) {\n-                node.put(defaultTag, (BigDecimal) defaultValue);\n-            } else if (defaultValue instanceof BigInteger) {\n-                node.put(defaultTag, (BigInteger) defaultValue);\n-            } else if (defaultValue instanceof Boolean) {\n-                node.put(defaultTag, (Boolean) defaultValue);\n-            } else if (defaultValue instanceof Double) {\n-                node.put(defaultTag, (Double) defaultValue);\n-            } else if (defaultValue instanceof Float) {\n-                node.put(defaultTag, (Float) defaultValue);\n-            } else if (defaultValue instanceof Integer) {\n-                node.put(defaultTag, (Integer) defaultValue);\n-            } else {\n-                // everything else is simply forwarded as-is to the JSON Schema, it's up to the configurator to ensure the value's correctness\n-                node.putPOJO(defaultTag, defaultValue);\n-            }\n+            this.addRawPropertyValue(node, defaultTag, defaultValue);\n         }\n@@ -333,21 +321,3 @@ public class AttributeCollector {\n             final String defaultTag = generationContext.getKeyword(SchemaKeyword.TAG_DEFAULT);\n-            // need to specifically add simple/primitive values by type\n-            if (defaultValue instanceof String) {\n-                node.put(defaultTag, (String) defaultValue);\n-            } else if (defaultValue instanceof BigDecimal) {\n-                node.put(defaultTag, (BigDecimal) defaultValue);\n-            } else if (defaultValue instanceof BigInteger) {\n-                node.put(defaultTag, (BigInteger) defaultValue);\n-            } else if (defaultValue instanceof Boolean) {\n-                node.put(defaultTag, (Boolean) defaultValue);\n-            } else if (defaultValue instanceof Double) {\n-                node.put(defaultTag, (Double) defaultValue);\n-            } else if (defaultValue instanceof Float) {\n-                node.put(defaultTag, (Float) defaultValue);\n-            } else if (defaultValue instanceof Integer) {\n-                node.put(defaultTag, (Integer) defaultValue);\n-            } else {\n-                // everything else is simply forwarded as-is to the JSON Schema, it's up to the configurator to ensure the value's correctness\n-                node.putPOJO(defaultTag, defaultValue);\n-            }\n+            this.addRawPropertyValue(node, defaultTag, defaultValue);\n         }\n@@ -373,17 +343,6 @@ public class AttributeCollector {\n             if (values.size() == 1) {\n-                Object singleValue = values.get(0);\n-                if (singleValue instanceof String) {\n-                    node.put(SchemaKeyword.TAG_CONST.forVersion(schemaVersion), (String) singleValue);\n-                } else {\n-                    node.putPOJO(SchemaKeyword.TAG_CONST.forVersion(schemaVersion), singleValue);\n-                }\n+                this.addRawPropertyValue(node, SchemaKeyword.TAG_CONST.forVersion(schemaVersion), values.get(0));\n             } else if (!values.isEmpty()) {\n                 ArrayNode array = node.arrayNode();\n-                for (Object singleValue : values) {\n-                    if (singleValue instanceof String) {\n-                        array.add((String) singleValue);\n-                    } else {\n-                        array.addPOJO(singleValue);\n-                    }\n-                }\n+                values.forEach(singleValue -> this.addRawArrayItem(array, singleValue));\n                 node.set(SchemaKeyword.TAG_ENUM.forVersion(schemaVersion), array);\n@@ -403,27 +362,63 @@ public class AttributeCollector {\n     public AttributeCollector setEnum(ObjectNode node, Collection<?> enumValues, SchemaGenerationContext generationContext) {\n-        if (enumValues != null) {\n-            List<Object> values = enumValues.stream()\n-                    .filter(this::isSupportedEnumValue)\n-                    .filter(this::canBeConvertedToString)\n-                    .collect(Collectors.toList());\n-            if (values.size() == 1 && generationContext.getGeneratorConfig().shouldRepresentSingleAllowedValueAsConst()) {\n-                Object singleValue = values.get(0);\n-                if (singleValue instanceof String) {\n-                    node.put(generationContext.getKeyword(SchemaKeyword.TAG_CONST), (String) singleValue);\n-                } else {\n-                    node.putPOJO(generationContext.getKeyword(SchemaKeyword.TAG_CONST), singleValue);\n-                }\n-            } else if (!values.isEmpty()) {\n-                ArrayNode array = node.arrayNode();\n-                for (Object singleValue : values) {\n-                    if (singleValue instanceof String) {\n-                        array.add((String) singleValue);\n-                    } else {\n-                        array.addPOJO(singleValue);\n-                    }\n-                }\n-                node.set(generationContext.getKeyword(SchemaKeyword.TAG_ENUM), array);\n-            }\n+        if (enumValues == null) {\n+            return this;\n+        }\n+        List<Object> values = enumValues.stream()\n+                .filter(this::isSupportedEnumValue)\n+                .filter(this::canBeConvertedToString)\n+                .collect(Collectors.toList());\n+        if (values.size() == 1 && generationContext.getGeneratorConfig().shouldRepresentSingleAllowedValueAsConst()) {\n+            this.addRawPropertyValue(node, generationContext.getKeyword(SchemaKeyword.TAG_CONST), values.get(0));\n+        } else if (!values.isEmpty()) {\n+            ArrayNode array = node.arrayNode();\n+            values.forEach(singleValue -> this.addRawArrayItem(array, singleValue));\n+            node.set(generationContext.getKeyword(SchemaKeyword.TAG_ENUM), array);\n+        }\n+        return this;\n+    }\n+\n+    private void addRawPropertyValue(ObjectNode node, String propertyName, Object value) {\n+        // need to specifically add simple/primitive values by type\n+        if (value instanceof String) {\n+            // explicit inclusion as string results in wrapping quote symbols\n+            node.put(propertyName, (String) value);\n+        } else if (value instanceof BigDecimal) {\n+            node.put(propertyName, (BigDecimal) value);\n+        } else if (value instanceof BigInteger) {\n+            node.put(propertyName, (BigInteger) value);\n+        } else if (value instanceof Boolean) {\n+            node.put(propertyName, (Boolean) value);\n+        } else if (value instanceof Double) {\n+            node.put(propertyName, (Double) value);\n+        } else if (value instanceof Float) {\n+            node.put(propertyName, (Float) value);\n+        } else if (value instanceof Integer) {\n+            node.put(propertyName, (Integer) value);\n+        } else {\n+            // everything else is simply forwarded as-is to the JSON Schema, it's up to the configurator to ensure the value's correctness\n+            node.putPOJO(propertyName, value);\n+        }\n+    }\n+\n+    private void addRawArrayItem(ArrayNode node, Object value) {\n+        // need to specifically add simple/primitive values by type\n+        if (value instanceof String) {\n+            // explicit inclusion as string results in wrapping quote symbols\n+            node.add((String) value);\n+        } else if (value instanceof BigDecimal) {\n+            node.add((BigDecimal) value);\n+        } else if (value instanceof BigInteger) {\n+            node.add((BigInteger) value);\n+        } else if (value instanceof Boolean) {\n+            node.add((Boolean) value);\n+        } else if (value instanceof Double) {\n+            node.add((Double) value);\n+        } else if (value instanceof Float) {\n+            node.add((Float) value);\n+        } else if (value instanceof Integer) {\n+            node.add((Integer) value);\n+        } else {\n+            // everything else is simply forwarded as-is to the JSON Schema, it's up to the configurator to ensure the value's correctness\n+            node.addPOJO(value);\n         }\n-        return this;\n     }\n@@ -501,3 +496,3 @@ public class AttributeCollector {\n     public AttributeCollector setAdditionalProperties(ObjectNode node, JsonNode additionalProperties, SchemaGenerationContext generationContext) {\n-        if (additionalProperties != null && (!additionalProperties.isBoolean() || !additionalProperties.asBoolean())) {\n+        if (!this.isNullOrTrue(additionalProperties)) {\n             node.set(generationContext.getKeyword(SchemaKeyword.TAG_ADDITIONAL_PROPERTIES), additionalProperties);\n@@ -507,2 +502,8 @@ public class AttributeCollector {\n \n+    private boolean isNullOrTrue(JsonNode nodeToCheck) {\n+        return nodeToCheck == null\n+               || nodeToCheck.isNull()\n+               || nodeToCheck.isBoolean() && nodeToCheck.asBoolean();\n+    }\n+\n     /**\n","improvement-type":"Complex Method"}],"change-level":"warning","is-hotspot?":false,"line":459,"what-changed":"overrideInstanceAttributes has a cyclomatic complexity of 11, threshold = 9","how-to-fix":"There are many reasons for Complex Method. Sometimes, another design approach is beneficial such as a) modeling state using an explicit state machine rather than conditionals, or b) using table lookup rather than long chains of logic. In other scenarios, the function can be split using [EXTRACT FUNCTION](https://refactoring.com/catalog/extractFunction.html). Just make sure you extract natural and cohesive functions. Complex Methods can also be addressed by identifying complex conditional expressions and then using the [DECOMPOSE CONDITIONAL](https://refactoring.com/catalog/decomposeConditional.html) refactoring.","change-type":"introduced"}]},"positive-impact-count":0,"repo":"jsonschema-generator","code-health":9.725040861624477,"version":"3.0","authors":["damien"],"directives":{"added":[],"removed":[]},"positive-findings":{"number-of-types":0,"number-of-files-touched":0,"findings":[]},"notices":{"number-of-types":0,"number-of-files-touched":0,"findings":[]},"external-review-provider":"GitHub"},"analysistime":"2024-10-12T20:41:15.000Z","project-name":"jsonschema-generator","repository":"https://github.com/victools/jsonschema-generator.git"}}