• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

torand / openapi2java / 18478813446

13 Oct 2025 09:33PM UTC coverage: 83.031% (+1.2%) from 81.86%
18478813446

push

github

torand
test: add test case for additionalProperties

557 of 785 branches covered (70.96%)

Branch coverage included in aggregate %.

3 of 6 new or added lines in 2 files covered. (50.0%)

1640 of 1861 relevant lines covered (88.12%)

5.16 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.48
/src/main/java/io/github/torand/openapi2java/collectors/PojoInfoCollector.java
1
/*
2
 * Copyright (c) 2024-2025 Tore Eide Andersen
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
 *      http://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 io.github.torand.openapi2java.collectors;
17

18
import io.github.torand.openapi2java.generators.Options;
19
import io.github.torand.openapi2java.model.AnnotationInfo;
20
import io.github.torand.openapi2java.model.PojoInfo;
21
import io.github.torand.openapi2java.model.PropertyInfo;
22
import io.swagger.v3.oas.models.media.Schema;
23

24
import java.util.ArrayList;
25
import java.util.List;
26
import java.util.Optional;
27

28
import static io.github.torand.javacommons.collection.CollectionHelper.nonEmpty;
29
import static io.github.torand.javacommons.lang.StringHelper.nonBlank;
30
import static io.github.torand.openapi2java.collectors.Extensions.EXT_MODEL_SUBDIR;
31
import static io.github.torand.openapi2java.collectors.Extensions.extensions;
32
import static io.github.torand.openapi2java.utils.StringUtils.joinCsv;
33
import static java.lang.Boolean.TRUE;
34

35
/**
36
 * Collects information about a pojo from a schema.
37
 */
38
public class PojoInfoCollector extends BaseCollector {
39
    private final PropertyInfoCollector propertyInfoCollector;
40
    private final SchemaResolver schemaResolver;
41

42
    public PojoInfoCollector(SchemaResolver schemaResolver, Options opts) {
43
        super(opts);
3✔
44
        this.propertyInfoCollector = new PropertyInfoCollector(schemaResolver, opts);
7✔
45
        this.schemaResolver = schemaResolver;
3✔
46
    }
1✔
47

48
    public PojoInfo getPojoInfo(String name, Schema<?> schema) {
49
        PojoInfo pojoInfo = new PojoInfo(name);
5✔
50

51
        Optional<String> maybeModelSubdir = extensions(schema.getExtensions()).getString(EXT_MODEL_SUBDIR);
6✔
52
        pojoInfo = pojoInfo.withModelSubdir(maybeModelSubdir.orElse(null))
9✔
53
            .withModelSubpackage(maybeModelSubdir.map(this::dirPath2PackagePath).orElse(null));
6✔
54

55
        if (opts.addMpOpenApiAnnotations()) {
4!
56
            pojoInfo = pojoInfo.withAddedAnnotation(getSchemaAnnotation(name, schema));
7✔
57
        }
58

59
        if (TRUE.equals(schema.getDeprecated())) {
5!
60
            pojoInfo = pojoInfo.withDeprecationMessage(formatDeprecationMessage(schema.getExtensions()));
×
61
        }
62

63
        pojoInfo = pojoInfo.withAddedProperties(getSchemaProperties(schema));
6✔
64

65
        if (schema.getAdditionalProperties() instanceof Schema) {
4✔
66
            throw new IllegalStateException("Schema-based 'additionalProperties' not supported for Pojos. Please specify this inside a property schema instead.");
5✔
67
        }
68

69
        return pojoInfo;
2✔
70
    }
71

72
    private AnnotationInfo getSchemaAnnotation(String name, Schema<?> pojo) {
73
        List<String> schemaParams = new ArrayList<>();
4✔
74

75
        schemaParams.add("name = \"%s\"".formatted(modelName2SchemaName(name)));
13✔
76
        schemaParams.add("description = \"%s\"".formatted(normalizeDescription(pojo.getDescription())));
14✔
77
        if (TRUE.equals(pojo.getDeprecated())) {
5!
78
            schemaParams.add("deprecated = true");
×
79
        }
80

81
        return new AnnotationInfo(
9✔
82
            "@Schema(%s)".formatted(joinCsv(schemaParams)),
5✔
83
            "org.eclipse.microprofile.openapi.annotations.media.Schema"
84
        );
85
    }
86

87
    private List<PropertyInfo> getSchemaProperties(Schema<?> schema) {
88
        List<PropertyInfo> props = new ArrayList<>();
4✔
89

90
        if (nonEmpty(schema.getAllOf())) {
4✔
91
            schema.getAllOf().forEach(subSchema -> props.addAll(getSchemaProperties(subSchema)));
14✔
92
        } else if (nonBlank(schema.get$ref())) {
4✔
93
            Schema<?> refSchema = schemaResolver.getOrThrow(schema.get$ref());
6✔
94
            return getSchemaProperties(refSchema);
4✔
95
        } else {
96
            schema.getProperties().forEach((propName, propSchema) ->
7✔
97
                props.add(propertyInfoCollector.getPropertyInfo(propName, propSchema, isRequired(schema, propName)))
13✔
98
            );
99
        }
100

101
        return props;
2✔
102
    }
103

104
    private PropertyInfo getAdditionalProperties(Schema<?> additionalProperties) {
NEW
105
        if (!schemaResolver.isPrimitiveType(additionalProperties)) {
×
NEW
106
            throw new IllegalStateException("Expected primitive type, but got: %s".formatted(additionalProperties.toString()));
×
107
        }
108

NEW
109
        return propertyInfoCollector.getPropertyInfo("additionalProperties", additionalProperties, false);
×
110
    }
111

112
    private boolean isRequired(Schema<?> schema, String propName) {
113
        return nonEmpty(schema.getRequired()) && schema.getRequired().contains(propName);
13✔
114
    }
115
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc