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

leeonky / test-charm-java / 320

28 Sep 2025 03:56PM UTC coverage: 74.512% (+0.07%) from 74.442%
320

push

circleci

leeonky
one list one property

21 of 21 new or added lines in 2 files covered. (100.0%)

13 existing lines in 7 files now uncovered.

8466 of 11362 relevant lines covered (74.51%)

0.75 hits per line

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

99.03
/jfactory/src/main/java/com/github/leeonky/jfactory/ObjectProducer.java
1
package com.github.leeonky.jfactory;
2

3
import com.github.leeonky.util.PropertyWriter;
4

5
import java.util.*;
6
import java.util.function.Function;
7
import java.util.stream.Collectors;
8

9
import static com.github.leeonky.jfactory.PropertyChain.propertyChain;
10
import static com.github.leeonky.util.Sneaky.cast;
11
import static java.util.stream.IntStream.range;
12

13
class ObjectProducer<T> extends Producer<T> {
14
    private final ObjectFactory<T> factory;
15
    private final JFactory jFactory;
16
    private final DefaultBuilder<T> builder;
17
    private final RootInstance<T> instance;
18
    private final Map<String, Producer<?>> children = new HashMap<>();
1✔
19
    private final Map<PropertyChain, String> reverseAssociations = new LinkedHashMap<>();
1✔
20
    private final ListPersistable cachedChildren = new ListPersistable();
1✔
21
    private final Set<String> ignorePropertiesInSpec = new HashSet<>();
1✔
22
    private Persistable persistable;
23
    private Function<PropertyWriter<?>, Producer<?>> defaultListElementValueProducerFactory;
24
    private final ConsistencySet consistencySet = new ConsistencySet();
1✔
25

26
    public JFactory jFactory() {
27
        return jFactory;
1✔
28
    }
29

30
    public ObjectProducer(JFactory jFactory, ObjectFactory<T> factory, DefaultBuilder<T> builder) {
31
        this(jFactory, factory, builder, false);
1✔
32
    }
1✔
33

34
    public ObjectProducer(JFactory jFactory, ObjectFactory<T> factory, DefaultBuilder<T> builder, boolean forQuery) {
35
        super(factory.getType());
1✔
36
        this.factory = factory;
1✔
37
        this.jFactory = jFactory;
1✔
38
        this.builder = builder;
1✔
39
        instance = factory.createInstance(builder.getArguments());
1✔
40
        persistable = jFactory.getDataRepository();
1✔
41
        defaultListElementValueProducerFactory = propertyWriter -> new DefaultValueFactoryProducer<>(factory.getType(),
1✔
42
                factory.getFactorySet().getDefaultValueFactory(propertyWriter.getType()),
1✔
43
                instance.sub(propertyWriter));
1✔
44
        createDefaultValueProducers();
1✔
45
        builder.collectSpec(this, instance);
1✔
46
        builder.processInputProperty(this, forQuery);
1✔
47
        setupReverseAssociations();
1✔
48
        resolveBuilderProducers();
1✔
49
    }
1✔
50

51
    protected void resolveBuilderProducers() {
52
        List<Map.Entry<String, Producer<?>>> buildValueProducers = children.entrySet().stream()
1✔
53
                .filter(entry -> entry.getValue() instanceof BuilderValueProducer).collect(Collectors.toList());
1✔
54
        buildValueProducers.forEach(e -> setChild(e.getKey(), ((BuilderValueProducer) e.getValue()).getProducer()));
1✔
55
    }
1✔
56

57
    private void createElementDefaultValueProducersWhenBuildListAsRoot() {
58
        try {
59
            children.keySet().stream().map(Integer::valueOf).max(Integer::compareTo).ifPresent(size -> {
1✔
60
                size++;
1✔
61
                instance.setCollectionSize(size);
1✔
62
                range(0, size).mapToObj(String::valueOf)
1✔
63
                        .filter(index -> children.get(index) == null)
1✔
64
                        .map(index -> getType().getPropertyWriter(index))
1✔
65
                        .forEach((PropertyWriter<T> propertyWriter) ->
1✔
66
                                setChild(propertyWriter.getName(), defaultListElementValueProducerFactory.apply(propertyWriter)));
1✔
67
            });
1✔
68
        } catch (Exception ignore) {
1✔
69
        }
1✔
70
    }
1✔
71

72
    private void setupReverseAssociations() {
73
        reverseAssociations.forEach((child, association) ->
1✔
74
                descendant(child).setupAssociation(association, instance, cachedChildren));
1✔
75
    }
1✔
76

77
    @Override
78
    public void setChild(String property, Producer<?> producer) {
79
        children.put(property, producer);
1✔
80
    }
1✔
81

82
    @Override
83
    public Producer<?> childOrDefault(String property) {
84
        return childOrDefaultCollection(getType().getPropertyWriter(property), false);
1✔
85
    }
86

87
    public Producer<?> childOrDefaultCollection(PropertyWriter<T> propertyWriter, boolean force) {
88
        Producer<?> producer = children.get(propertyWriter.getName());
1✔
89
        if (producer == null && !ignorePropertiesInSpec.contains(propertyWriter.getName())) {
1✔
90
            if (force || propertyWriter.getType().isCollection())
1✔
91
                setChild(propertyWriter.getName(), producer = new CollectionProducer<>(getType(), propertyWriter.getType(),
1✔
92
                        instance.sub(propertyWriter), factory.getFactorySet()));
1✔
93
            else if (!propertyWriter.getType().isCollection())
1✔
94
                producer = createPropertyDefaultValueProducer(propertyWriter)
1✔
95
                        .orElse(new DefaultValueProducer<>(propertyWriter.getType(), () -> cast(propertyWriter.getType().createDefault())));
1✔
96
        }
97
        return producer;
1✔
98
    }
99

100
    @Override
101
    protected T produce() {
102
        return instance.cache(() -> {
1✔
103
            createElementDefaultValueProducersWhenBuildListAsRoot();
1✔
104
            return factory.create(instance);
1✔
105
        }, obj -> {
106
            produceSubs(obj);
1✔
107
            persistable.save(obj);
1✔
108
            cachedChildren.getAll().forEach(persistable::save);
1✔
109
        });
1✔
110
    }
111

112
    private void produceSubs(T obj) {
113
        children.entrySet().stream().filter(this::isDefaultValueProducer).forEach(e -> produceSub(obj, e));
1✔
114
        children.entrySet().stream().filter(e -> !(isDefaultValueProducer(e))).forEach(e -> produceSub(obj, e));
1✔
115
    }
1✔
116

117
    private void produceSub(T obj, Map.Entry<String, Producer<?>> e) {
118
        getType().setPropertyValue(obj, e.getKey(), e.getValue().getValue());
1✔
119
    }
1✔
120

121
    private boolean isDefaultValueProducer(Map.Entry<String, Producer<?>> e) {
122
        return e.getValue() instanceof DefaultValueFactoryProducer;
1✔
123
    }
124

125
    @Override
126
    public Optional<Producer<?>> child(String property) {
127
        return Optional.ofNullable(children.get(property));
1✔
128
    }
129

130
    public ObjectProducer<T> processConsistent() {
131
        collectConsistent(this, propertyChain(""));
1✔
132
        consistencySet.resolve(this);
1✔
133
        return this;
1✔
134
    }
135

136
    @Override
137
    protected void collectConsistent(ObjectProducer<?> root, PropertyChain base) {
138
        if (root != this)
1✔
139
            root.consistencySet.addAll(consistencySet.absoluteProperty(base));
1✔
140
        children.forEach((property, producer) -> producer.collectConsistent(root, base.concat(property)));
1✔
141
    }
1✔
142

143
    private void createDefaultValueProducers() {
144
        getType().getPropertyWriters().values().stream().filter(jFactory::shouldCreateDefaultValue)
1✔
145
                .forEach(propertyWriter -> createPropertyDefaultValueProducer(propertyWriter)
1✔
146
                        .ifPresent(producer -> setChild(propertyWriter.getName(), producer)));
1✔
147
    }
1✔
148

149
    @Override
150
    public Optional<Producer<?>> createPropertyDefaultValueProducer(PropertyWriter<?> property) {
151
        return factory.getFactorySet().queryDefaultValueFactory(property.getType())
1✔
152
                .map(builder -> new DefaultValueFactoryProducer<>(getType(), builder, instance.sub(property)));
1✔
153
    }
154

155
    @Override
156
    public Producer<T> changeTo(Producer<T> newProducer) {
157
        return newProducer.changeFrom(this);
1✔
158
    }
159

160
    @Override
161
    protected Producer<T> changeFrom(ObjectProducer<T> origin) {
162
        return origin.builder.marge(builder).createProducer();
1✔
163
    }
164

165
    @Override
166
    @SuppressWarnings("unchecked")
167
    protected Producer<T> changeFrom(OptionalSpecDefaultValueProducer<T> producer) {
168
        if (producer.getTraitsAndSpec() != null)
1✔
169
            return ((DefaultBuilder<T>) jFactory.spec(producer.getTraitsAndSpec())).marge(builder).createProducer();
1✔
UNCOV
170
        return this;
×
171
    }
172

173
    public void appendReverseAssociation(PropertyChain property, String association) {
174
        reverseAssociations.put(property, association);
1✔
175
    }
1✔
176

177
    @Override
178
    protected <T> void setupAssociation(String association, RootInstance<T> instance, ListPersistable cachedChildren) {
179
        setChild(association, new UnFixedValueProducer<>(instance.reference(), instance.spec().getType()));
1✔
180
        persistable = cachedChildren;
1✔
181
    }
1✔
182

183
    public boolean isReverseAssociation(String property) {
184
        return reverseAssociations.containsKey(PropertyChain.propertyChain(property));
1✔
185
    }
186

187
    public void ignoreProperty(String property) {
188
        ignorePropertiesInSpec.add(property);
1✔
189
    }
1✔
190

191
    public void processSpecIgnoreProperties() {
192
        children.entrySet().stream().filter(e -> e.getValue() instanceof DefaultValueProducer
1✔
193
                        && ignorePropertiesInSpec.contains(e.getKey())).map(Map.Entry::getKey).collect(Collectors.toList())
1✔
194
                .forEach(children::remove);
1✔
195
    }
1✔
196

197
    @Override
198
    protected boolean isFixed() {
199
        return children.values().stream().anyMatch(Producer::isFixed);
1✔
200
    }
201

202
    public void changeElementDefaultValueProducerFactory(Function<PropertyWriter<?>, Producer<?>> factory) {
203
        defaultListElementValueProducerFactory = factory;
1✔
204
    }
1✔
205

206
    public void appendLink(DefaultConsistency<?> consistency) {
207
        consistencySet.add(consistency);
1✔
208
    }
1✔
209
}
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