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

burningwave / reflection / #81

23 Oct 2023 10:22AM UTC coverage: 74.528%. Remained the same
#81

push

Roberto-Gentili
Releasing new version

790 of 1060 relevant lines covered (74.53%)

0.75 hits per line

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

69.23
/src/main/java/org/burningwave/reflection/Fields.java
1
/*
2
 * This file is part of Burningwave Reflection.
3
 *
4
 * Author: Roberto Gentili
5
 *
6
 * Hosted at: https://github.com/burningwave/reflection
7
 *
8
 * --
9
 *
10
 * The MIT License (MIT)
11
 *
12
 * Copyright (c) 2022-2023 Roberto Gentili
13
 *
14
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
15
 * documentation files (the "Software"), to deal in the Software without restriction, including without
16
 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
17
 * the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
18
 * conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all copies or substantial
21
 * portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24
 * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
25
 * EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
27
 * OR OTHER DEALINGS IN THE SOFTWARE.
28
 */
29
package org.burningwave.reflection;
30

31

32
import java.lang.reflect.Field;
33
import java.lang.reflect.Modifier;
34
import java.util.Collection;
35
import java.util.HashMap;
36
import java.util.Map;
37
import java.util.function.Supplier;
38

39
import org.burningwave.Classes;
40
import org.burningwave.Strings;
41
import org.burningwave.Throwables;
42

43

44

45

46
public class Fields extends Members.Handler<Field, FieldCriteria> {
47

48
        public static final Fields INSTANCE;
49

50
        static {
51
                INSTANCE = new Fields();
1✔
52
        }
1✔
53

54
        private Fields() {}
1✔
55

56
        public Collection<Field> findAllAndMakeThemAccessible(
57
                Class<?> targetClass
58
        ) {
59
                String cacheKey = getCacheKey(targetClass, Members.ALL_FOR_CLASS, (Class<?>[])null);
1✔
60
                return Cache.INSTANCE.uniqueKeyForAllFields.getOrUploadIfAbsent(
1✔
61
                        cacheKey,
62
                        () ->
63
                                findAllAndMakeThemAccessible(
1✔
64
                                        FieldCriteria.forEntireClassHierarchy(), targetClass
1✔
65
                                )
66
                );
67
        }
68

69
        public Collection<Field> findAllByExactNameAndMakeThemAccessible(
70
                Class<?> targetClass,
71
                String fieldName
72
        ) {
73
                return findAllByExactNameAndMakeThemAccessible(targetClass, fieldName, null);
×
74
        }
75

76
        public Collection<Field> findAllByExactNameAndMakeThemAccessible(
77
                Class<?> targetClass,
78
                String fieldName,
79
                Class<?> valueType
80
        ) {
81
                String cacheKey = getCacheKey(targetClass, "equals " + fieldName, valueType);
1✔
82
                return Cache.INSTANCE.uniqueKeyForAllFields.getOrUploadIfAbsent(
1✔
83
                        cacheKey,
84
                        () ->
85
                                findAllAndMakeThemAccessible(
1✔
86
                                        FieldCriteria.forEntireClassHierarchy().allThoseThatMatch(field -> {
1✔
87
                                                if (valueType == null) {
1✔
88
                                                        return field.getName().equals(fieldName);
1✔
89
                                                } else {
90
                                                        return field.getName().equals(fieldName) && Classes.INSTANCE.isAssignableFrom(field.getType(), valueType);
1✔
91
                                                }
92
                                        }), targetClass
93
                                )
94
                );
95
        }
96

97
        public Field findFirstAndMakeItAccessible(Class<?> targetClass, String fieldName) {
98
                return findFirstAndMakeItAccessible(targetClass, fieldName, null);
×
99
        }
100

101
        public Field findFirstAndMakeItAccessible(Class<?> targetClass, String fieldName, Class<?> fieldTypeOrSubType) {
102
                Collection<Field> members = findAllByExactNameAndMakeThemAccessible(targetClass, fieldName, fieldTypeOrSubType);
1✔
103
                if (members.size() < 1) {
1✔
104
                        Throwables.INSTANCE.throwException(
×
105
                                new NoSuchFieldException(
106
                                        Strings.INSTANCE.compile("Field {} not found in {} hierarchy", fieldName, targetClass.getName())
×
107
                                )
108
                        );
109
                }
110
                return members.stream().findFirst().get();
1✔
111
        }
112

113
        public Field findOneAndMakeItAccessible(Class<?> targetClass, String memberName) {
114
                Collection<Field> members = findAllByExactNameAndMakeThemAccessible(targetClass, memberName, null);
1✔
115
                if (members.size() != 1) {
1✔
116
                        Throwables.INSTANCE.throwException(
×
117
                                new NoSuchFieldException(
118
                                                Strings.INSTANCE.compile("Field {} not found or found more than one field in {} hierarchy", memberName, targetClass.getName())
×
119
                                )
120
                        );
121
                }
122
                return members.stream().findFirst().get();
1✔
123
        }
124

125
        public <T> T get(Object target, Field field) {
126
                return Facade.INSTANCE.getFieldValue(target, field);
1✔
127
        }
128

129
        public <T> T get(Object target, String fieldName) {
130
                return get(target, findFirstAndMakeItAccessible(Classes.INSTANCE.retrieveFrom(target), fieldName, null));
1✔
131
        }
132

133
        public Map<Field, ?> getAll(FieldCriteria criteria, Object target) {
134
                return getAll(() -> findAllAndMakeThemAccessible(criteria, Classes.INSTANCE.retrieveFrom(target)), target);
1✔
135
        }
136

137
        public Map<Field, ?> getAll(Object target) {
138
                return getAll(() -> findAllAndMakeThemAccessible(Classes.INSTANCE.retrieveFrom(target)), target);
1✔
139
        }
140

141
        public Map<Field, ?> getAllDirect(FieldCriteria criteria, Object target) {
142
                return getAllDirect(() -> findAllAndMakeThemAccessible(criteria, Classes.INSTANCE.retrieveFrom(target)), target);
×
143
        }
144

145

146
        public Map<Field, ?> getAllDirect(Object target) {
147
                return getAllDirect(() -> findAllAndMakeThemAccessible(Classes.INSTANCE.retrieveFrom(target)), target);
1✔
148
        }
149

150
        public Map<Field, ?> getAllStatic(Class<?> targetClass) {
151
                return getAll(() -> findAllAndMakeThemAccessible(targetClass), null);
×
152
        }
153

154
        public Map<Field, ?> getAllStaticDirect(Class<?> targetClass) {
155
                return getAllDirect(() -> findAllAndMakeThemAccessible(targetClass), null);
×
156
        }
157

158
        public <T> T getStatic(Class<?> targetClass, String fieldName) {
159
                return getStatic(findFirstAndMakeItAccessible(targetClass, fieldName, null));
×
160
        }
161

162
        public <T> T getStatic(Field field) {
163
                return get(null, field);
×
164
        }
165

166
        public void set(Object target, Field field, Object value) {
167
                Facade.INSTANCE.setFieldValue(target, field, value);
1✔
168
        }
1✔
169

170
        public void set(Object target, String fieldName, Object value) {
171
                set(Classes.INSTANCE.retrieveFrom(target), target, fieldName, value);
1✔
172
        }
1✔
173

174
        public void setStatic(Class<?> targetClass, String fieldName, Object value) {
175
                set(targetClass, null, fieldName, value);
×
176
        }
×
177

178
        public void setStatic(Field field, Object value) {
179
                set(null, field, value);
×
180
        }
×
181

182
        private Map<Field, Object> getAll(Supplier<Collection<Field>> fieldsSupplier, Object target) {
183
                Map<Field, Object> fieldValues = new HashMap<>();
1✔
184
                for (Field field : fieldsSupplier.get()) {
1✔
185
                        if (target != null) {
1✔
186
                                fieldValues.put(
1✔
187
                                        field,
188
                                        get(
1✔
189
                                                Modifier.isStatic(field.getModifiers()) ? null : target, field
1✔
190
                                        )
191
                                );
192
                        } else if (Modifier.isStatic(field.getModifiers())) {
×
193
                                fieldValues.put(
×
194
                                        field,
195
                                        get(null, field)
×
196
                                );
197
                        }
198
                }
1✔
199
                return fieldValues;
1✔
200
        }
201

202
        private Map<Field, ?> getAllDirect(Supplier<Collection<Field>> fieldsSupplier, Object target) {
203
                Map<Field, ?> fieldValues = new HashMap<>();
1✔
204
                for (Field field : fieldsSupplier.get()) {
1✔
205
                        fieldValues.put(
1✔
206
                                field,
207
                                Facade.INSTANCE.getFieldValue(target, field)
1✔
208
                        );
209
                }
1✔
210
                return fieldValues;
1✔
211
        }
212

213
        private void set(Class<?> targetClass, Object target, String fieldName, Object value) {
214
                set(target, findFirstAndMakeItAccessible(targetClass, fieldName, Classes.INSTANCE.retrieveFrom(value)), value);
1✔
215
        }
1✔
216

217
        public static class NoSuchFieldException extends RuntimeException {
218

219
                private static final long serialVersionUID = 3656790511956737635L;
220

221
                public NoSuchFieldException(String message) {
222
                        super(message);
×
223
                }
×
224

225
        }
226

227
}
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

© 2025 Coveralls, Inc