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

leeonky / test-charm-java / 156

20 Mar 2025 01:53PM UTC coverage: 74.243% (-0.2%) from 74.475%
156

push

circleci

leeonky
Refactor

14 of 15 new or added lines in 12 files covered. (93.33%)

126 existing lines in 29 files now uncovered.

7947 of 10704 relevant lines covered (74.24%)

0.74 hits per line

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

91.04
/DAL-java/src/main/java/com/github/leeonky/dal/runtime/Data.java
1
package com.github.leeonky.dal.runtime;
2

3
import com.github.leeonky.dal.runtime.RuntimeContextBuilder.DALRuntimeContext;
4
import com.github.leeonky.dal.runtime.inspector.DumpingBuffer;
5
import com.github.leeonky.interpreter.InterpreterException;
6
import com.github.leeonky.util.BeanClass;
7
import com.github.leeonky.util.ConvertException;
8
import com.github.leeonky.util.ThrowingSupplier;
9

10
import java.util.*;
11
import java.util.function.Consumer;
12
import java.util.function.Function;
13
import java.util.function.Predicate;
14
import java.util.function.Supplier;
15

16
import static com.github.leeonky.dal.ast.node.SortGroupNode.NOP_COMPARATOR;
17
import static com.github.leeonky.dal.runtime.DalException.throwUserRuntimeException;
18
import static com.github.leeonky.dal.runtime.ExpressionException.illegalOperation;
19
import static com.github.leeonky.util.Sneaky.sneakyThrow;
20
import static java.lang.String.format;
21
import static java.util.Optional.empty;
22
import static java.util.Optional.ofNullable;
23
import static java.util.stream.Collectors.toList;
24

25
public class Data {
26
    private final SchemaType schemaType;
27
    private final DALRuntimeContext context;
28
    private final ThrowingSupplier<?> supplier;
29
    private Function<Throwable, Throwable> errorMapper = e -> e;
1✔
30
    private final boolean isListMapping;
31
    private Resolved resolved;
32
    private Throwable error;
33

34
    public Data(ThrowingSupplier<?> supplier, DALRuntimeContext context, SchemaType schemaType) {
1✔
35
        this.supplier = Objects.requireNonNull(supplier);
1✔
36
        this.context = context;
1✔
37
        this.schemaType = schemaType;
1✔
38
        isListMapping = false;
1✔
39
    }
1✔
40

41
    public Data(ThrowingSupplier<?> supplier, DALRuntimeContext context, SchemaType schemaType, boolean isListMapping) {
1✔
42
        this.supplier = Objects.requireNonNull(supplier);
1✔
43
        this.context = context;
1✔
44
        this.schemaType = schemaType;
1✔
45
        this.isListMapping = isListMapping;
1✔
46
    }
1✔
47

48
    public Data onError(Function<Throwable, Throwable> mapper) {
49
        errorMapper = errorMapper.andThen(mapper);
1✔
50
        return this;
1✔
51
    }
52

53
    public Object instance() {
54
        return resolved().value();
1✔
55
    }
56

57
    public Resolved resolved() {
58
        if (error != null)
1✔
UNCOV
59
            return sneakyThrow(error);
×
60
        if (resolved == null) {
1✔
61
            try {
62
                resolved = new Resolved(supplier.get());
1✔
63
            } catch (Throwable e) {
1✔
UNCOV
64
                sneakyThrow(error = errorMapper.apply(e));
×
65
            }
1✔
66
            handlers.accept(resolved);
1✔
67
        }
68
        return resolved;
1✔
69
    }
70

71
    public Data getValue(List<Object> propertyChain) {
72
        return propertyChain.isEmpty() ? this :
1✔
73
                getValue(propertyChain.get(0)).getValue(propertyChain.subList(1, propertyChain.size()));
1✔
74
    }
75

76
    public Data getValue(Object propertyChain) {
77
        List<Object> chain = schemaType.access(propertyChain).getPropertyChainBefore(schemaType);
1✔
78
        if (chain.size() == 1 && chain.get(0).equals(propertyChain)) {
1✔
79
            boolean isSubListMapping = isListMapping && propertyChain instanceof String;
1✔
80
            return new Data(() -> resolved().getValue(propertyChain), context,
1✔
81
                    propertySchema(propertyChain, isSubListMapping), isSubListMapping);
1✔
82
        }
83
        return getValue(chain);
1✔
84
    }
85

86
    public SchemaType propertySchema(Object property, boolean isListMapping) {
87
        return isListMapping ? schemaType.mappingAccess(property) : schemaType.access(property);
1✔
88
    }
89

90
    public Object firstFieldFromAlias(Object alias) {
91
        return schemaType.firstFieldFromAlias(alias);
1✔
92
    }
93

94
    public Data convert(Class<?>... targets) {
95
        return map(object -> {
1✔
96
            ConvertException e = null;
1✔
97
            for (Class<?> target : targets) {
1✔
98
                try {
99
                    return context.getConverter().convert(target, object.value());
1✔
100
                } catch (ConvertException convertException) {
1✔
101
                    e = convertException;
1✔
102
                }
103
            }
104
            throw e;
1✔
105
        });
106
    }
107

108
    public Data map(Function<Resolved, Object> mapper) {
109
        return new Data(() -> mapper.apply(resolved()), context, schemaType);
1✔
110
    }
111

112
    public <T, R> Data map(Function<Resolved, T> getter, Function<T, R> mapper) {
UNCOV
113
        return new Data(() -> mapper.apply(getter.apply(resolved())), context, schemaType);
×
114
    }
115

116
    public <T> Supplier<T> get(Function<Resolved, T> mapper) {
117
        return () -> mapper.apply(resolved());
1✔
118
    }
119

120
    public Data filter(String prefix) {
121
        return new Data(() -> {
1✔
122
            FilteredObject filteredObject = new FilteredObject();
1✔
123
            resolved().fieldNames().stream().filter(String.class::isInstance).map(String.class::cast)
1✔
124
                    .filter(field -> field.startsWith(prefix)).forEach(fieldName ->
1✔
125
                            filteredObject.put(fieldName.substring(prefix.length()), getValue(fieldName).instance()));
1✔
126
            return filteredObject;
1✔
127
        }, context, schemaType);
128
    }
129

130
    public String dump() {
131
        return DumpingBuffer.rootContext(context).dump(this).content();
1✔
132
    }
133

134
    public String dumpValue() {
135
        return DumpingBuffer.rootContext(context).dumpValue(this).content();
1✔
136
    }
137

138
    public <T> T execute(Supplier<T> supplier) {
139
        return context.pushAndExecute(this, supplier);
1✔
140
    }
141

142
    public <T> T probe(Function<Resolved, T> mapper, T defaultValue) {
143
        try {
144
            return mapper.apply(resolved());
1✔
145
        } catch (Throwable e) {
1✔
146
            return defaultValue;
1✔
147
        }
148
    }
149

150
    public <T> Optional<T> probe(Function<Resolved, Optional<T>> mapper) {
151
        try {
152
            return mapper.apply(resolved());
1✔
UNCOV
153
        } catch (Throwable e) {
×
UNCOV
154
            return empty();
×
155
        }
156
    }
157

158
    public boolean probeIf(Predicate<Resolved> mapper) {
159
        return probe(mapper::test, false);
1✔
160
    }
161

162
    public Data resolve() {
163
        instance();
1✔
164
        return this;
1✔
165
    }
166

167
    private Consumer<Resolved> handlers = r -> {
1✔
168
    };
1✔
169

170
    public Data peek(Consumer<Resolved> peek) {
171
        if (resolved != null)
1✔
172
            peek.accept(resolved);
1✔
173
        else
174
            handlers = handlers.andThen(peek);
1✔
175
        return this;
1✔
176
    }
177

178
    public Data trigger(Data another) {
179
        return peek(r -> another.resolve());
1✔
180
    }
181

182
    public ConditionalAction when(Predicate<Resolved> condition) {
183
        return new ConditionalAction(condition);
1✔
184
    }
185

186
    public class ConditionalAction {
187
        private final Predicate<Resolved> condition;
188

189
        public ConditionalAction(Predicate<Resolved> condition) {
1✔
190
            this.condition = condition;
1✔
191
        }
1✔
192

193
        public Data then(Consumer<Resolved> then) {
194
            peek(r -> {
1✔
195
                if (condition.test(r))
1✔
196
                    then.accept(r);
1✔
197
            });
1✔
198
            return Data.this;
1✔
199
        }
200

201
        public Data thenThrow(Supplier<Throwable> supplier) {
202
            peek(r -> {
1✔
203
                if (condition.test(r))
1✔
UNCOV
204
                    sneakyThrow(supplier.get());
×
205
            });
1✔
206
            return Data.this;
1✔
207
        }
208
    }
209

210
    static class FilteredObject extends LinkedHashMap<String, Object> implements PartialObject {
1✔
211
    }
212

213
    public class DataList extends DALCollection.Decorated<Object> {
214
        public DataList(DALCollection<Object> origin) {
1✔
215
            super(origin);
1✔
216
        }
1✔
217

218
        public DALCollection<Data> wraps() {
219
            return map((index, e) -> new Data(() -> e, context, schemaType.access(index)));
1✔
220
        }
221

222
        public AutoMappingList autoMapping(Function<Data, Data> mapper) {
223
            return new AutoMappingList(mapper, wraps());
1✔
224
        }
225

226
        public DataList sort(Comparator<Data> comparator) {
227
            if (comparator != NOP_COMPARATOR)
1✔
228
                try {
229
                    return new DataList(new CollectionDALCollection<Object>(wraps().collect().stream()
1✔
230
                            .sorted(comparator).map(Data::instance).collect(toList())) {
1✔
231
                        @Override
232
                        public int firstIndex() {
233
                            return DataList.this.firstIndex();
1✔
234
                        }
235

236
                        @Override
237
                        public boolean infinite() {
238
                            return DataList.this.infinite();
1✔
239
                        }
240
                    });
241
                } catch (InfiniteCollectionException e) {
1✔
242
                    throw illegalOperation("Can not sort infinite collection");
1✔
243
                }
244
            return this;
1✔
245
        }
246
    }
247

248
    public class Resolved {
249
        private final Object instance;
250
        private DataList list;
251

252
        public Resolved(Object instance) {
1✔
253
            this.instance = instance;
1✔
254
        }
1✔
255

256
        @SuppressWarnings("unchecked")
257
        public <T> T value() {
258
            return (T) instance;
1✔
259
        }
260

261
        public boolean isNull() {
262
            return context.isNull(instance);
1✔
263
        }
264

265
        public boolean isList() {
266
            return context.isRegisteredList(instance) || (instance != null && instance.getClass().isArray());
1✔
267
        }
268

269
        public DataList list() {
270
            return castList().orElseThrow(() -> new DalRuntimeException(format("Invalid input value, expect a List but: %s", dump().trim())));
1✔
271
        }
272

273
        public Optional<DataList> castList() {
274
            if (list == null && isList())
1✔
275
                list = new DataList(context.createCollection(instance));
1✔
276
            return ofNullable(list);
1✔
277
        }
278

279
        public void eachSubData(Consumer<Data> consumer) {
UNCOV
280
            list().wraps().forEach(e -> consumer.accept(e.value()));
×
UNCOV
281
        }
×
282

283
        public boolean instanceOf(Class<?> type) {
284
            return type.isInstance(instance);
1✔
285
        }
286

287
        public Data getValueData(Object field) {
288
            return Data.this.getValue(field);
1✔
289
        }
290

291
        public Set<?> fieldNames() {
292
            return context.findPropertyReaderNames(instance);
1✔
293
        }
294

295
        public Data repack() {
UNCOV
296
            return Data.this;
×
297
        }
298

299
        boolean isEnum() {
300
            return value() != null && value().getClass().isEnum();
1✔
301
        }
302

303
        public <T> Optional<T> cast(Class<T> type) {
304
            return BeanClass.cast(instance, type);
1✔
305
        }
306

307
        public Object getValue(Object propertyChain) {
308
            try {
309
                if (isList() && !(propertyChain instanceof String))
1✔
310
                    return list().getByIndex((int) propertyChain);
1✔
311
                try {
312
                    return context.getObjectPropertyAccessor(value()).getValueByData(this, propertyChain);
1✔
313
                } catch (InvalidPropertyException e) {
1✔
314
                    try {
315
                        return context.currying(value(), propertyChain).orElseThrow(() -> e).resolve();
1✔
316
                    } catch (Throwable e1) {
1✔
UNCOV
317
                        return throwUserRuntimeException(e1);
×
318
                    }
319
                } catch (Throwable e) {
1✔
UNCOV
320
                    return throwUserRuntimeException(e);
×
321
                }
322
            } catch (IndexOutOfBoundsException ex) {
1✔
323
                throw new DalRuntimeException(ex.getMessage());
1✔
324
            } catch (ListMappingElementAccessException | ExpressionException | InterpreterException ex) {
1✔
325
                throw ex;
1✔
326
            } catch (Throwable e) {
1✔
327
                throw new DalRuntimeException(format("Get property `%s` failed, property can be:\n" +
1✔
328
                        "  1. public field\n" +
329
                        "  2. public getter\n" +
330
                        "  3. public method\n" +
331
                        "  4. Map key value\n" +
332
                        "  5. customized type getter\n" +
333
                        "  6. static method extension", propertyChain), e);
334
            }
335
        }
336
    }
337

UNCOV
338
    public static class ResolvedMethods {
×
339

340
        public static Predicate<Resolved> instanceOf(Class<?> type) {
341
            return r -> type.isInstance(r.value());
1✔
342
        }
343

344
        public static <T> Function<Resolved, Optional<T>> cast(Class<T> type) {
345
            return r -> BeanClass.cast(r.value(), type);
1✔
346
        }
347
    }
348
}
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