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

leeonky / test-charm-java / 329

01 Oct 2025 04:21PM UTC coverage: 74.68% (+0.03%) from 74.648%
329

push

circleci

leeonky
depends on primitive default value sub property

6 of 9 new or added lines in 3 files covered. (66.67%)

13 existing lines in 4 files now uncovered.

8565 of 11469 relevant lines covered (74.68%)

0.75 hits per line

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

94.52
/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 com.github.leeonky.util.Sneaky.cast;
14
import static java.lang.Integer.parseInt;
15

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

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

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

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

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

90
    private <T> Expression<T> createCollectionExpression(Matcher matcher, Property<T> property, String index,
91
                                                         ObjectFactory<T> objectFactory, Producer<?> collectionProducer, boolean forQuery) {
92
        Property<?> propertySub = property.getWriter().getType().getProperty(index);
1✔
93
        int intIndex = parseInt(index);
1✔
94
        Producer<?> subProducer;
95
        if (collectionProducer instanceof CollectionProducer) {
1✔
96
            subProducer = ((CollectionProducer<?, ?>) collectionProducer).newElementPopulationProducer(cast(collectionProducer.getType().getPropertyWriter(String.valueOf(intIndex))));
1✔
97
            if (subProducer instanceof ObjectProducer) {
1✔
98
                BeanClass type = subProducer.getType();
1✔
99
                propertySub = propertySub.decorateWriterType(type).decorateReaderType(type);
1✔
100
            }
1✔
101
        } else
102
            subProducer = collectionProducer.getChild(index).orElse(PlaceHolderProducer.PLACE_HOLDER);
1✔
103
        TraitsSpec elementTraitSpec = new TraitsSpec(matcher.group(GROUP_ELEMENT_TRAIT) != null ?
1✔
104
                matcher.group(GROUP_ELEMENT_TRAIT).split(", |,| ") : new String[0], matcher.group(GROUP_ELEMENT_SPEC));
1✔
105
        return new CollectionExpression<>(property, intIndex,
1✔
106
                createSubExpression(matcher, propertySub, property, objectFactory, subProducer, forQuery, elementTraitSpec), forQuery);
1✔
107
    }
108

109
    private Optional<String> hasIndex(Matcher matcher) {
110
        return Optional.ofNullable(matcher.group(GROUP_COLLECTION_INDEX));
1✔
111
    }
112

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

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

130
    public <T> Builder<T> apply(Builder<T> builder) {
131
        return builder.property(key, value);
1✔
132
    }
133

134
    public boolean nullKey() {
135
        return key == null;
1✔
136
    }
137

138
    @Override
139
    public int hashCode() {
140
        return Objects.hash(KeyValue.class, key, value);
1✔
141
    }
142

143
    @Override
144
    public boolean equals(Object another) {
145
        return BeanClass.cast(another, KeyValue.class)
1✔
146
                .map(keyValue -> Objects.equals(key, keyValue.key) && Objects.equals(value, keyValue.value))
1✔
147
                .orElseGet(() -> super.equals(another));
1✔
148
    }
149

150
    public Object getValue() {
151
        return value;
1✔
152
    }
153
}
154

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