|
2 | 2 |
|
3 | 3 | import com.github.collinalpert.java2db.annotations.ColumnName; |
4 | 4 | import com.github.collinalpert.java2db.annotations.ForeignKeyEntity; |
| 5 | +import com.github.collinalpert.java2db.contracts.IdentifiableEnum; |
5 | 6 | import com.github.collinalpert.java2db.entities.BaseEntity; |
6 | 7 | import com.github.collinalpert.java2db.modules.ArrayModule; |
7 | 8 | import com.github.collinalpert.java2db.utilities.IoC; |
8 | 9 | import com.github.collinalpert.java2db.utilities.UniqueIdentifier; |
9 | 10 | import com.github.collinalpert.java2db.utilities.Utilities; |
10 | 11 |
|
| 12 | +import java.lang.reflect.Field; |
11 | 13 | import java.sql.ResultSet; |
12 | 14 | import java.sql.SQLException; |
13 | 15 | import java.time.LocalDate; |
14 | 16 | import java.time.LocalDateTime; |
15 | 17 | import java.time.LocalTime; |
| 18 | +import java.util.Arrays; |
16 | 19 | import java.util.Calendar; |
17 | 20 | import java.util.LinkedList; |
18 | 21 | import java.util.List; |
|
22 | 25 | import java.util.stream.Stream; |
23 | 26 |
|
24 | 27 | import static com.github.collinalpert.java2db.utilities.Utilities.tryAction; |
| 28 | +import static com.github.collinalpert.java2db.utilities.Utilities.tryGetValue; |
25 | 29 |
|
26 | 30 | /** |
27 | 31 | * Default mapper for converting a {@link ResultSet} to the respective Java entity. |
@@ -138,32 +142,31 @@ private <E extends BaseEntity> void setFields(ResultSet set, E entity, String id |
138 | 142 | var fields = Utilities.getEntityFields(entity.getClass(), true); |
139 | 143 | for (var field : fields) { |
140 | 144 | field.setAccessible(true); |
| 145 | + |
141 | 146 | if (field.getAnnotation(ForeignKeyEntity.class) != null) { |
142 | | - var foreignKeyColumnName = field.getAnnotation(ForeignKeyEntity.class).value(); |
143 | | - if (!BaseEntity.class.isAssignableFrom(field.getType())) { |
144 | | - throw new IllegalArgumentException(String.format("Type %s, which is annotated as a foreign key, does not extend BaseEntity.", field.getType().getSimpleName())); |
145 | | - } |
146 | 147 |
|
147 | | - // This block is for checking if the foreign key is null. |
148 | | - // That means that the corresponding foreign key entity must be set to null. |
149 | | - var foreignKeyName = ""; |
150 | | - try { |
151 | | - var foreignKeyField = field.getDeclaringClass().getDeclaredField(foreignKeyColumnName); |
152 | | - foreignKeyName = foreignKeyField.getName(); |
153 | | - if (foreignKeyField.getAnnotation(ColumnName.class) != null) { |
154 | | - foreignKeyName = foreignKeyField.getAnnotation(ColumnName.class).value(); |
155 | | - } |
156 | | - } catch (NoSuchFieldException e) { |
157 | | - //Oh boi, you've done it now! |
158 | | - for (var declaredField : field.getDeclaringClass().getDeclaredFields()) { |
159 | | - if (declaredField.getAnnotation(ColumnName.class) != null && declaredField.getAnnotation(ColumnName.class).value().equals(foreignKeyColumnName)) { |
160 | | - foreignKeyName = declaredField.getAnnotation(ColumnName.class).value(); |
161 | | - break; |
162 | | - } |
| 148 | + if (field.getType().isEnum()) { |
| 149 | + if (!IdentifiableEnum.class.isAssignableFrom(field.getType())) { |
| 150 | + throw new IllegalArgumentException(String.format("The enum %s used in %s was annotated with a ForeignKeyEntity attribute but does not extend IdentifiableEnum.", field.getType().getSimpleName(), field.getDeclaringClass().getSimpleName())); |
163 | 151 | } |
| 152 | + |
| 153 | + var foreignKeyName = getForeignKeyName(field); |
| 154 | + var foundEnum = Arrays.stream(field.getType().getEnumConstants()) |
| 155 | + .map(x -> (IdentifiableEnum) x) |
| 156 | + .filter(x -> Long.valueOf(tryGetValue(() -> getAccessibleField(field.getDeclaringClass(), foreignKeyName).get(entity)).toString()) == x.getId()) |
| 157 | + .findFirst(); |
| 158 | + |
| 159 | + foundEnum.ifPresent(identifiableEnum -> tryAction(() -> field.set(entity, field.getType().cast(identifiableEnum)))); |
| 160 | + |
| 161 | + continue; |
164 | 162 | } |
165 | 163 |
|
166 | | - if (set.getObject((identifier == null ? Utilities.getTableName(entity.getClass()) : identifier) + "_" + foreignKeyName) == null) { |
| 164 | + if (!BaseEntity.class.isAssignableFrom(field.getType())) { |
| 165 | + throw new IllegalArgumentException(String.format("Type %s, which is annotated as a foreign key, does not extend BaseEntity.", field.getType().getSimpleName())); |
| 166 | + } |
| 167 | + |
| 168 | + // If foreign key is null, the corresponding entity must also be null. |
| 169 | + if (set.getObject((identifier == null ? Utilities.getTableName(entity.getClass()) : identifier) + "_" + getForeignKeyName(field)) == null) { |
167 | 170 | continue; |
168 | 171 | } |
169 | 172 |
|
@@ -196,4 +199,29 @@ private <E extends BaseEntity> void setFields(ResultSet set, E entity, String id |
196 | 199 | tryAction(() -> field.set(entity, value)); |
197 | 200 | } |
198 | 201 | } |
| 202 | + |
| 203 | + private String getForeignKeyName(Field field) { |
| 204 | + var foreignKeyColumnName = field.getAnnotation(ForeignKeyEntity.class).value(); |
| 205 | + |
| 206 | + try { |
| 207 | + var foreignKeyField = field.getDeclaringClass().getDeclaredField(foreignKeyColumnName); |
| 208 | + return Utilities.getColumnName(foreignKeyField); |
| 209 | + } catch (NoSuchFieldException e) { |
| 210 | + //Oh boi, you've done it now! This case occurs when a foreign key field gets altered by a ColumnName attribute. |
| 211 | + for (var declaredField : field.getDeclaringClass().getDeclaredFields()) { |
| 212 | + ColumnName columnName; |
| 213 | + if ((columnName = declaredField.getAnnotation(ColumnName.class)) != null && columnName.value().equals(foreignKeyColumnName)) { |
| 214 | + return columnName.value(); |
| 215 | + } |
| 216 | + } |
| 217 | + } |
| 218 | + |
| 219 | + return ""; |
| 220 | + } |
| 221 | + |
| 222 | + private Field getAccessibleField(Class<?> clazz, String name) throws NoSuchFieldException { |
| 223 | + var field = clazz.getDeclaredField(name); |
| 224 | + field.setAccessible(true); |
| 225 | + return field; |
| 226 | + } |
199 | 227 | } |
0 commit comments