Skip to content

Commit 23631c0

Browse files
Merge branch 'fix-generic-type-usage' into 'dev'
Resolve generic type issues See merge request objectbox/objectbox-java!60
2 parents f1adf61 + b779e32 commit 23631c0

24 files changed

+207
-200
lines changed

objectbox-java/src/main/java/io/objectbox/Box.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class Box<T> {
5656

5757
private final IdGetter<T> idGetter;
5858

59-
private EntityInfo entityInfo;
59+
private EntityInfo<T> entityInfo;
6060
private volatile Field boxStoreField;
6161

6262
Box(BoxStore store, Class<T> entityClass) {
@@ -339,7 +339,8 @@ public long put(T entity) {
339339
/**
340340
* Puts the given entities in a box using a single transaction.
341341
*/
342-
public void put(@Nullable T... entities) {
342+
@SafeVarargs // Not using T... as Object[], no ClassCastException expected.
343+
public final void put(@Nullable T... entities) {
343344
if (entities == null || entities.length == 0) {
344345
return;
345346
}
@@ -488,8 +489,9 @@ public boolean remove(T object) {
488489
/**
489490
* Removes (deletes) the given Objects in a single transaction.
490491
*/
492+
@SafeVarargs // Not using T... as Object[], no ClassCastException expected.
491493
@SuppressWarnings("Duplicates") // Detected duplicate has different type
492-
public void remove(@Nullable T... objects) {
494+
public final void remove(@Nullable T... objects) {
493495
if (objects == null || objects.length == 0) {
494496
return;
495497
}
@@ -560,7 +562,7 @@ public BoxStore getStore() {
560562
return store;
561563
}
562564

563-
public synchronized EntityInfo getEntityInfo() {
565+
public synchronized EntityInfo<T> getEntityInfo() {
564566
if (entityInfo == null) {
565567
Cursor<T> reader = getReader();
566568
try {
@@ -604,7 +606,7 @@ public Class<T> getEntityClass() {
604606
}
605607

606608
@Internal
607-
public List<T> internalGetBacklinkEntities(int entityId, Property relationIdProperty, long key) {
609+
public List<T> internalGetBacklinkEntities(int entityId, Property<?> relationIdProperty, long key) {
608610
Cursor<T> reader = getReader();
609611
try {
610612
return reader.getBacklinkEntities(entityId, relationIdProperty, key);

objectbox-java/src/main/java/io/objectbox/BoxStore.java

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ public static String getVersionNative() {
136136

137137
/** @return entity ID */
138138
// TODO only use ids once we have them in Java
139-
static native int nativeRegisterEntityClass(long store, String entityName, Class entityClass);
139+
static native int nativeRegisterEntityClass(long store, String entityName, Class<?> entityClass);
140140

141141
// TODO only use ids once we have them in Java
142142
static native void nativeRegisterCustomType(long store, int entityId, int propertyId, String propertyName,
143-
Class<? extends PropertyConverter> converterClass, Class customType);
143+
Class<? extends PropertyConverter> converterClass, Class<?> customType);
144144

145145
static native String nativeDiagnose(long store);
146146

@@ -164,12 +164,12 @@ public static boolean isObjectBrowserAvailable() {
164164
private final File directory;
165165
private final String canonicalPath;
166166
private final long handle;
167-
private final Map<Class, String> dbNameByClass = new HashMap<>();
168-
private final Map<Class, Integer> entityTypeIdByClass = new HashMap<>();
169-
private final Map<Class, EntityInfo> propertiesByClass = new HashMap<>();
170-
private final LongHashMap<Class> classByEntityTypeId = new LongHashMap<>();
167+
private final Map<Class<?>, String> dbNameByClass = new HashMap<>();
168+
private final Map<Class<?>, Integer> entityTypeIdByClass = new HashMap<>();
169+
private final Map<Class<?>, EntityInfo<?>> propertiesByClass = new HashMap<>();
170+
private final LongHashMap<Class<?>> classByEntityTypeId = new LongHashMap<>();
171171
private final int[] allEntityTypeIds;
172-
private final Map<Class, Box> boxes = new ConcurrentHashMap<>();
172+
private final Map<Class<?>, Box<?>> boxes = new ConcurrentHashMap<>();
173173
private final Set<Transaction> transactions = Collections.newSetFromMap(new WeakHashMap<>());
174174
private final ExecutorService threadPool = new ObjectBoxThreadPool(this);
175175
private final ObjectClassPublisher objectClassPublisher;
@@ -191,7 +191,7 @@ public static boolean isObjectBrowserAvailable() {
191191

192192
private final int queryAttempts;
193193

194-
private final TxCallback failedReadTxAttemptCallback;
194+
private final TxCallback<?> failedReadTxAttemptCallback;
195195

196196
BoxStore(BoxStoreBuilder builder) {
197197
context = builder.context;
@@ -213,14 +213,14 @@ public static boolean isObjectBrowserAvailable() {
213213
}
214214
debugRelations = builder.debugRelations;
215215

216-
for (EntityInfo entityInfo : builder.entityInfoList) {
216+
for (EntityInfo<?> entityInfo : builder.entityInfoList) {
217217
try {
218218
dbNameByClass.put(entityInfo.getEntityClass(), entityInfo.getDbName());
219219
int entityId = nativeRegisterEntityClass(handle, entityInfo.getDbName(), entityInfo.getEntityClass());
220220
entityTypeIdByClass.put(entityInfo.getEntityClass(), entityId);
221221
classByEntityTypeId.put(entityId, entityInfo.getEntityClass());
222222
propertiesByClass.put(entityInfo.getEntityClass(), entityInfo);
223-
for (Property property : entityInfo.getAllProperties()) {
223+
for (Property<?> property : entityInfo.getAllProperties()) {
224224
if (property.customType != null) {
225225
if (property.converterClass == null) {
226226
throw new RuntimeException("No converter class for custom type of " + property);
@@ -333,24 +333,24 @@ private void checkOpen() {
333333
}
334334
}
335335

336-
String getDbName(Class entityClass) {
336+
String getDbName(Class<?> entityClass) {
337337
return dbNameByClass.get(entityClass);
338338
}
339339

340-
Integer getEntityTypeId(Class entityClass) {
340+
Integer getEntityTypeId(Class<?> entityClass) {
341341
return entityTypeIdByClass.get(entityClass);
342342
}
343343

344344
@Internal
345-
public int getEntityTypeIdOrThrow(Class entityClass) {
345+
public int getEntityTypeIdOrThrow(Class<?> entityClass) {
346346
Integer id = entityTypeIdByClass.get(entityClass);
347347
if (id == null) {
348348
throw new DbSchemaException("No entity registered for " + entityClass);
349349
}
350350
return id;
351351
}
352352

353-
public Collection<Class> getAllEntityClasses() {
353+
public Collection<Class<?>> getAllEntityClasses() {
354354
return dbNameByClass.keySet();
355355
}
356356

@@ -360,17 +360,18 @@ int[] getAllEntityTypeIds() {
360360
}
361361

362362
@Internal
363-
Class getEntityClassOrThrow(int entityTypeId) {
364-
Class clazz = classByEntityTypeId.get(entityTypeId);
363+
Class<?> getEntityClassOrThrow(int entityTypeId) {
364+
Class<?> clazz = classByEntityTypeId.get(entityTypeId);
365365
if (clazz == null) {
366366
throw new DbSchemaException("No entity registered for type ID " + entityTypeId);
367367
}
368368
return clazz;
369369
}
370370

371+
@SuppressWarnings("unchecked") // Casting is easier than writing a custom Map.
371372
@Internal
372-
EntityInfo getEntityInfo(Class entityClass) {
373-
return propertiesByClass.get(entityClass);
373+
<T> EntityInfo<T> getEntityInfo(Class<T> entityClass) {
374+
return (EntityInfo<T>) propertiesByClass.get(entityClass);
374375
}
375376

376377
/**
@@ -608,7 +609,7 @@ void txCommitted(Transaction tx, @Nullable int[] entityTypeIdsAffected) {
608609
}
609610
}
610611

611-
for (Box box : boxes.values()) {
612+
for (Box<?> box : boxes.values()) {
612613
box.txCommitted(tx);
613614
}
614615

@@ -622,17 +623,17 @@ void txCommitted(Transaction tx, @Nullable int[] entityTypeIdsAffected) {
622623
* <p>
623624
* Creates a Box only once and then always returns the cached instance.
624625
*/
625-
@SuppressWarnings("unchecked")
626+
@SuppressWarnings("unchecked") // Casting is easier than writing a custom Map.
626627
public <T> Box<T> boxFor(Class<T> entityClass) {
627-
Box box = boxes.get(entityClass);
628+
Box<T> box = (Box<T>) boxes.get(entityClass);
628629
if (box == null) {
629630
if (!dbNameByClass.containsKey(entityClass)) {
630631
throw new IllegalArgumentException(entityClass +
631632
" is not a known entity. Please add it and trigger generation again.");
632633
}
633634
// Ensure a box is created just once
634635
synchronized (boxes) {
635-
box = boxes.get(entityClass);
636+
box = (Box<T>) boxes.get(entityClass);
636637
if (box == null) {
637638
box = new Box<>(this, entityClass);
638639
boxes.put(entityClass, box);
@@ -688,7 +689,7 @@ public void runInReadTx(Runnable runnable) {
688689

689690
// TODO That's rather a quick fix, replace with a more general solution
690691
// (that could maybe be a TX listener with abort callback?)
691-
for (Box box : boxes.values()) {
692+
for (Box<?> box : boxes.values()) {
692693
box.readTxFinished(tx);
693694
}
694695

@@ -732,7 +733,6 @@ public <T> T callInReadTxWithRetry(Callable<T> callable, int attempts, int initi
732733
cleanStaleReadTransactions();
733734
}
734735
if (failedReadTxAttemptCallback != null) {
735-
//noinspection unchecked
736736
failedReadTxAttemptCallback.txFinished(null, new DbException(message + " \n" + diagnose, e));
737737
}
738738
try {
@@ -772,7 +772,7 @@ public <T> T callInReadTx(Callable<T> callable) {
772772

773773
// TODO That's rather a quick fix, replace with a more general solution
774774
// (that could maybe be a TX listener with abort callback?)
775-
for (Box box : boxes.values()) {
775+
for (Box<?> box : boxes.values()) {
776776
box.readTxFinished(tx);
777777
}
778778

@@ -885,7 +885,7 @@ public int cleanStaleReadTransactions() {
885885
* {@link Box#closeThreadResources()} for all initiated boxes ({@link #boxFor(Class)}).
886886
*/
887887
public void closeThreadResources() {
888-
for (Box box : boxes.values()) {
888+
for (Box<?> box : boxes.values()) {
889889
box.closeThreadResources();
890890
}
891891
// activeTx is cleaned up in finally blocks, so do not free them here
@@ -972,7 +972,7 @@ public <T> SubscriptionBuilder<Class<T>> subscribe(Class<T> forClass) {
972972
}
973973

974974
@Internal
975-
public Future internalScheduleThread(Runnable runnable) {
975+
public Future<?> internalScheduleThread(Runnable runnable) {
976976
return threadPool.submit(runnable);
977977
}
978978

@@ -992,7 +992,7 @@ public int internalQueryAttempts() {
992992
}
993993

994994
@Internal
995-
public TxCallback internalFailedReadTxAttemptCallback() {
995+
public TxCallback<?> internalFailedReadTxAttemptCallback() {
996996
return failedReadTxAttemptCallback;
997997
}
998998

objectbox-java/src/main/java/io/objectbox/BoxStoreBuilder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ public class BoxStoreBuilder {
9090

9191
int queryAttempts;
9292

93-
TxCallback failedReadTxAttemptCallback;
93+
TxCallback<?> failedReadTxAttemptCallback;
9494

95-
final List<EntityInfo> entityInfoList = new ArrayList<>();
95+
final List<EntityInfo<?>> entityInfoList = new ArrayList<>();
9696
private Factory<InputStream> initialDbFileFactory;
9797

9898
/** Not for application use. */
@@ -274,7 +274,7 @@ public BoxStoreBuilder maxReaders(int maxReaders) {
274274
}
275275

276276
@Internal
277-
public void entity(EntityInfo entityInfo) {
277+
public void entity(EntityInfo<?> entityInfo) {
278278
entityInfoList.add(entityInfo);
279279
}
280280

@@ -345,7 +345,7 @@ public BoxStoreBuilder queryAttempts(int queryAttempts) {
345345
* Useful for e.g. logging.
346346
*/
347347
@Experimental
348-
public BoxStoreBuilder failedReadTxAttemptCallback(TxCallback failedReadTxAttemptCallback) {
348+
public BoxStoreBuilder failedReadTxAttemptCallback(TxCallback<?> failedReadTxAttemptCallback) {
349349
this.failedReadTxAttemptCallback = failedReadTxAttemptCallback;
350350
return this;
351351
}

objectbox-java/src/main/java/io/objectbox/Cursor.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public abstract class Cursor<T> implements Closeable {
5050

5151
static native boolean nativeSeek(long cursor, long key);
5252

53-
native Object nativeGetAllEntities(long cursor);
53+
native List<T> nativeGetAllEntities(long cursor);
5454

5555
static native Object nativeGetEntity(long cursor, long key);
5656

@@ -108,11 +108,11 @@ protected static native long collect004000(long cursor, long keyIfComplete, int
108108

109109
native int nativePropertyId(long cursor, String propertyValue);
110110

111-
native List nativeGetBacklinkEntities(long cursor, int entityId, int propertyId, long key);
111+
native List<T> nativeGetBacklinkEntities(long cursor, int entityId, int propertyId, long key);
112112

113113
native long[] nativeGetBacklinkIds(long cursor, int entityId, int propertyId, long key);
114114

115-
native List nativeGetRelationEntities(long cursor, int sourceEntityId, int relationId, long key, boolean backlink);
115+
native List<T> nativeGetRelationEntities(long cursor, int sourceEntityId, int relationId, long key, boolean backlink);
116116

117117
native long[] nativeGetRelationIds(long cursor, int sourceEntityId, int relationId, long key, boolean backlink);
118118

@@ -126,15 +126,15 @@ protected static native long collect004000(long cursor, long keyIfComplete, int
126126

127127
protected final Transaction tx;
128128
protected final long cursor;
129-
protected final EntityInfo entityInfo;
129+
protected final EntityInfo<T> entityInfo;
130130
protected final BoxStore boxStoreForEntities;
131131

132132
protected final boolean readOnly;
133133
protected boolean closed;
134134

135135
private final Throwable creationThrowable;
136136

137-
protected Cursor(Transaction tx, long cursor, EntityInfo entityInfo, BoxStore boxStore) {
137+
protected Cursor(Transaction tx, long cursor, EntityInfo<T> entityInfo, BoxStore boxStore) {
138138
if (tx == null) {
139139
throw new IllegalArgumentException("Transaction is null");
140140
}
@@ -144,8 +144,8 @@ protected Cursor(Transaction tx, long cursor, EntityInfo entityInfo, BoxStore bo
144144
this.entityInfo = entityInfo;
145145
this.boxStoreForEntities = boxStore;
146146

147-
Property[] allProperties = entityInfo.getAllProperties();
148-
for (Property property : allProperties) {
147+
Property<T>[] allProperties = entityInfo.getAllProperties();
148+
for (Property<T> property : allProperties) {
149149
if (!property.isIdVerified()) {
150150
int id = getPropertyId(property.dbName);
151151
property.verifyId(id);
@@ -181,7 +181,7 @@ protected void finalize() throws Throwable {
181181

182182
public abstract long put(T entity);
183183

184-
public EntityInfo getEntityInfo() {
184+
public EntityInfo<T> getEntityInfo() {
185185
return entityInfo;
186186
}
187187

@@ -199,7 +199,7 @@ public T first() {
199199

200200
/** ~10% slower than iterating with {@link #first()} and {@link #next()} as done by {@link Box#getAll()}. */
201201
public List<T> getAll() {
202-
return (List) nativeGetAllEntities(cursor);
202+
return nativeGetAllEntities(cursor);
203203
}
204204

205205
public boolean deleteEntity(long key) {
@@ -262,7 +262,7 @@ public boolean isClosed() {
262262
* Thus, use it only locally and don't store it long term.
263263
*/
264264
protected <TARGET> Cursor<TARGET> getRelationTargetCursor(Class<TARGET> targetClass) {
265-
EntityInfo entityInfo = boxStoreForEntities.getEntityInfo(targetClass);
265+
EntityInfo<TARGET> entityInfo = boxStoreForEntities.getEntityInfo(targetClass);
266266
long cursorHandle = nativeGetCursorFor(cursor, entityInfo.getEntityId());
267267
CursorFactory<TARGET> factory = entityInfo.getCursorFactory();
268268
return factory.createCursor(tx, cursorHandle, boxStoreForEntities);
@@ -281,7 +281,7 @@ long internalHandle() {
281281
}
282282

283283
@Internal
284-
List<T> getBacklinkEntities(int entityId, Property relationIdProperty, long key) {
284+
List<T> getBacklinkEntities(int entityId, Property<?> relationIdProperty, long key) {
285285
try {
286286
return nativeGetBacklinkEntities(cursor, entityId, relationIdProperty.getId(), key);
287287
} catch (IllegalArgumentException e) {
@@ -291,7 +291,7 @@ List<T> getBacklinkEntities(int entityId, Property relationIdProperty, long key)
291291
}
292292

293293
@Internal
294-
long[] getBacklinkIds(int entityId, Property relationIdProperty, long key) {
294+
long[] getBacklinkIds(int entityId, Property<?> relationIdProperty, long key) {
295295
try {
296296
return nativeGetBacklinkIds(cursor, entityId, relationIdProperty.getId(), key);
297297
} catch (IllegalArgumentException e) {

0 commit comments

Comments
 (0)