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

leeonky / test-charm-java / 296

15 Sep 2025 02:01PM UTC coverage: 74.593% (+0.4%) from 74.22%
296

push

circleci

leeonky
checking during consistency merge

89 of 94 new or added lines in 6 files covered. (94.68%)

11 existing lines in 6 files now uncovered.

8435 of 11308 relevant lines covered (74.59%)

0.75 hits per line

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

94.2
/jfactory/src/main/java/com/github/leeonky/jfactory/KeyValue.java
1
package com.github.leeonky.jfactory;
2

3
import com.github.leeonky.util.BeanClass;
4
import com.github.leeonky.util.GenericBeanClass;
5
import com.github.leeonky.util.Property;
6

7
import java.util.List;
8
import java.util.Objects;
9
import java.util.Optional;
10
import java.util.regex.Matcher;
11
import java.util.regex.Pattern;
12

13
import static java.lang.Integer.parseInt;
14

15
//TODO use a parser to parse this
16
class KeyValue {
17
    private static final String PATTERN_PROPERTY = "([^.(!\\[]+)";
18
    private static final String PATTERN_COLLECTION_INDEX = "(\\[(-?\\d+)])?";
19
    private static final String PATTERN_SPEC_TRAIT_WORD = "[^, )]";
20
    private static final String PATTERN_TRAIT = "((" + PATTERN_SPEC_TRAIT_WORD + "+[, ])(" + PATTERN_SPEC_TRAIT_WORD + "+[, ])*)?";
21
    private static final String PATTERN_SPEC = "(" + PATTERN_SPEC_TRAIT_WORD + "+)";
22
    private static final String PATTERN_TRAIT_SPEC = "(\\(" + PATTERN_TRAIT + PATTERN_SPEC + "\\))?";
23
    private static final String PATTERN_CLAUSE = "(\\." + "(.+)" + ")?";
24
    private static final String PATTERN_INTENTLY = "(!)?";
25
    private static final int GROUP_PROPERTY = 1;
26

27
    private static final int GROUP_TRAIT = 3;
28
    private static final int GROUP_SPEC = 6;
29

30
    private static final int GROUP_COLLECTION_INDEX = 3 + 5;
31
    private static final int GROUP_ELEMENT_TRAIT = 5 + 5;
32
    private static final int GROUP_ELEMENT_SPEC = 8 + 5;
33
    private static final int GROUP_INTENTLY = 9 + 5;
34
    private static final int GROUP_CLAUSE = 11 + 5;
35
    private final String key;
36
    private final Object value;
37
    private final FactorySet factorySet;
38

39
    public KeyValue(String key, Object value, FactorySet factorySet) {
1✔
40
        this.key = key;
1✔
41
        this.value = value;
1✔
42
        this.factorySet = factorySet;
1✔
43
    }
1✔
44

45
    public <T> Expression<T> createExpression(BeanClass<T> beanClass, ObjectFactory<T> objectFactory, Producer<T> producer, boolean forQuery) {
46
        Matcher matcher = parse(beanClass);
1✔
47
        String propertyName = matcher.group(GROUP_PROPERTY);
1✔
48
        Property<T> property = beanClass.getProperty(propertyName);
1✔
49
        TraitsSpec traitsSpec = new TraitsSpec(matcher.group(GROUP_TRAIT) != null ?
1✔
50
                matcher.group(GROUP_TRAIT).split(", |,| ") : new String[0], matcher.group(GROUP_SPEC));
1✔
51
        Producer<?> subProducer;
52
        if (traitsSpec.isCollectionSpec() && producer instanceof ObjectProducer && property.getWriterType().is(Object.class)) {
1✔
53
            SpecClassFactory<T> specFactory = objectFactory.getFactorySet().querySpecClassFactory(traitsSpec.spec());
1✔
54
            GenericBeanClass<T> newType = GenericBeanClass.create(List.class, specFactory.getType().getGenericType());
1✔
55
            property = property.decorateWriterType(newType).decorateReaderType(newType);
1✔
56
            subProducer = ((ObjectProducer) producer).childOrDefaultCollection(property.getWriter(), true);
1✔
57
            if (subProducer instanceof CollectionProducer)
1✔
58
                ((CollectionProducer<?, ?>) subProducer).changeElementDefaultValueProducerFactory(i ->
1✔
59
                        traitsSpec.toBuilder(((ObjectProducer) producer).jFactory(), specFactory.getType()).createProducer());
1✔
60
            if (subProducer == null)
1✔
UNCOV
61
                subProducer = Producer.PLACE_HOLDER;
×
62
        } else if (traitsSpec.isCollectionSpec() && producer instanceof ObjectProducer && property.getWriterType().isCollection()) {
1✔
63
            SpecClassFactory<T> specFactory = objectFactory.getFactorySet().querySpecClassFactory(traitsSpec.spec());
1✔
64
            subProducer = ((ObjectProducer) producer).childOrDefaultCollection(property.getWriter(), false);
1✔
65
            if (subProducer instanceof CollectionProducer)
1✔
66
                ((CollectionProducer<?, ?>) subProducer).changeElementDefaultValueProducerFactory(i ->
1✔
67
                        traitsSpec.toBuilder(((ObjectProducer) producer).jFactory(), specFactory.getType()).createProducer());
1✔
68
            if (subProducer == null)
1✔
UNCOV
69
                subProducer = Producer.PLACE_HOLDER;
×
70
        } else {
1✔
71
            subProducer = producer.child(propertyName).orElse(Producer.PLACE_HOLDER);
1✔
72
            if (subProducer instanceof ObjectProducer ||
1✔
73
                    subProducer instanceof CollectionProducer && property.getWriterType().is(Object.class)) {
1✔
74
                BeanClass<? extends T> type = (BeanClass<? extends T>) subProducer.getType();
1✔
75
                property = property.decorateWriterType(type).decorateReaderType(type);
1✔
76
            }
77
        }
78
        Property<T> finalSubProperty = property;
1✔
79
        Producer<T> finalSubProducer = (Producer<T>) subProducer;
1✔
80
        return hasIndex(matcher).map(index -> createCollectionExpression(matcher, finalSubProperty, index, objectFactory, finalSubProducer, forQuery))
1✔
81
                .orElseGet(() -> createSubExpression(matcher, finalSubProperty, null, objectFactory, finalSubProducer, forQuery, traitsSpec));
1✔
82
    }
83

84
    private <T> Expression<T> createCollectionExpression(Matcher matcher, Property<T> property, String index,
85
                                                         ObjectFactory<T> objectFactory, Producer<?> collectionProducer, boolean forQuery) {
86
        Property<?> propertySub = property.getWriter().getType().getProperty(index);
1✔
87
        int intIndex = parseInt(index);
1✔
88
        Producer<?> subProducer;
89
        if (collectionProducer instanceof CollectionProducer) {
1✔
90
            subProducer = ((CollectionProducer<?, ?>) collectionProducer).defaultElementProducer(intIndex);
1✔
91
            if (subProducer instanceof ObjectProducer) {
1✔
92
                BeanClass type = subProducer.getType();
1✔
93
                propertySub = propertySub.decorateWriterType(type).decorateReaderType(type);
1✔
94
            }
1✔
95
        } else
96
            subProducer = collectionProducer.child(index).orElse(Producer.PLACE_HOLDER);
1✔
97
        TraitsSpec elementTraitSpec = new TraitsSpec(matcher.group(GROUP_ELEMENT_TRAIT) != null ?
1✔
98
                matcher.group(GROUP_ELEMENT_TRAIT).split(", |,| ") : new String[0], matcher.group(GROUP_ELEMENT_SPEC));
1✔
99
        return new CollectionExpression<>(property, intIndex,
1✔
100
                createSubExpression(matcher, propertySub, property, objectFactory, subProducer, forQuery, elementTraitSpec), forQuery);
1✔
101
    }
102

103
    private Optional<String> hasIndex(Matcher matcher) {
104
        return Optional.ofNullable(matcher.group(GROUP_COLLECTION_INDEX));
1✔
105
    }
106

107
    private <T> Expression<T> createSubExpression(Matcher matcher, Property<T> property, Property<?> parentProperty,
108
                                                  ObjectFactory<?> objectFactory, Producer<?> subProducer, boolean forQuery, TraitsSpec traitsSpec) {
109
        KeyValueCollection properties = new KeyValueCollection(factorySet).append(matcher.group(GROUP_CLAUSE), value);
1✔
110
        return properties.createExpression(traitsSpec.guessPropertyType(objectFactory)
1✔
111
                        .map(type -> property.decorateWriterType(type).decorateReaderType(type)).orElse(property),
1✔
112
                traitsSpec, parentProperty, objectFactory, subProducer, forQuery).setIntently(matcher.group(GROUP_INTENTLY) != null);
1✔
113
    }
114

115
    private <T> Matcher parse(BeanClass<T> beanClass) {
116
        Matcher matcher = Pattern.compile(PATTERN_PROPERTY + PATTERN_TRAIT_SPEC + PATTERN_COLLECTION_INDEX +
1✔
117
                PATTERN_TRAIT_SPEC + PATTERN_INTENTLY + PATTERN_CLAUSE).matcher(key);
1✔
118
        if (!matcher.matches())
1✔
UNCOV
119
            throw new IllegalArgumentException(String.format("Invalid property `%s` for %s creation.",
×
UNCOV
120
                    key, beanClass.getName()));
×
121
        return matcher;
1✔
122
    }
123

124
    public <T> Builder<T> apply(Builder<T> builder) {
125
        return builder.property(key, value);
1✔
126
    }
127

128
    public boolean nullKey() {
129
        return key == null;
1✔
130
    }
131

132
    @Override
133
    public int hashCode() {
134
        return Objects.hash(KeyValue.class, key, value);
1✔
135
    }
136

137
    @Override
138
    public boolean equals(Object another) {
139
        return BeanClass.cast(another, KeyValue.class)
1✔
140
                .map(keyValue -> Objects.equals(key, keyValue.key) && Objects.equals(value, keyValue.value))
1✔
141
                .orElseGet(() -> super.equals(another));
1✔
142
    }
143

144
    public Object getValue() {
145
        return value;
1✔
146
    }
147
}
148

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