com.algolia.search.util.AlgoliaUtils Maven / Gradle / Ivy
The newest version!
package com.algolia.search.util;
import com.algolia.search.exceptions.AlgoliaRuntimeException;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.lang.reflect.Field;
import java.time.Clock;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.zone.ZoneRules;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nonnull;
public class AlgoliaUtils {
/** Checks if the given string is empty or white spaces */
public static Boolean isEmptyWhiteSpace(final String stringToCheck) {
return stringToCheck.trim().length() == 0;
}
/** Checks if the given string is null, empty or white spaces */
public static Boolean isNullOrEmptyWhiteSpace(final String stringToCheck) {
return stringToCheck == null || stringToCheck.trim().length() == 0;
}
private static final ZoneRules ZONE_RULES_UTC = ZoneOffset.UTC.getRules();
/**
* Memory optimization for getZoneRules with the same ZoneOffset (UTC). ZoneRules is immutable and
* threadsafe, but getRules method consumes a lot of memory during load testing.
*/
public static OffsetDateTime nowUTC() {
final Instant now = Clock.system(ZoneOffset.UTC).instant();
return OffsetDateTime.ofInstant(now, ZONE_RULES_UTC.getOffset(now));
}
/**
* Ensure that the objectID field or the @JsonProperty(\"objectID\")" is present in the given
* class
*
* @param clazz The class to scan
* @throws AlgoliaRuntimeException When the class doesn't have an objectID field or a Jackson
* annotation @JsonProperty(\"objectID\"")
*/
public static void ensureObjectID(@Nonnull Class clazz) {
// Try to find the objectID field
Field objectIDField = getField(clazz, "objectID");
// If objectID field doesn't exist, let's check for Jackson annotations in all the fields
Optional optObjectIDField = findObjectIDInAnnotation(clazz);
if (objectIDField == null && !optObjectIDField.isPresent()) {
throw new AlgoliaRuntimeException(
"The "
+ clazz
+ " must have an objectID property or a Jackson annotation @JsonProperty(\"objectID\")");
}
}
/**
* Get the objectID of the given class at runtime
*
* @param clazz The class to scan
* @throws AlgoliaRuntimeException When the class doesn't have an objectID field or a Jackson
* annotation @JsonProperty(\"objectID\"")
*/
public static String getObjectID(@Nonnull T data, @Nonnull Class clazz) {
String objectID = null;
// Try to find the objectID field
try {
Field objectIDField = getField(clazz, "objectID");
if (objectIDField != null) {
objectID = (String) objectIDField.get(data);
}
} catch (
IllegalAccessException
ignored) { // Ignored because if it fails we want to move forward on annotations
}
if (objectID != null) {
return objectID;
}
// If objectID field doesn't exist, let's check for Jackson annotations in all the fields
Optional optObjectIDField = findObjectIDInAnnotation(clazz);
if (optObjectIDField.isPresent()) {
Field objectIDField = optObjectIDField.get();
try {
objectIDField.setAccessible(true);
objectID = (String) objectIDField.get(data);
if (objectID != null) {
return objectID;
}
} catch (IllegalAccessException ignored) {
throw new AlgoliaRuntimeException("Can't access the ObjectID field.");
}
}
// If non of the both above the method fails
throw new AlgoliaRuntimeException(
"The "
+ clazz
+ " must have an objectID property or a Jackson annotation @JsonProperty(\"objectID\")");
}
private static Optional findObjectIDInAnnotation(@Nonnull Class> clazz) {
List fields = getFields(clazz);
return fields.stream()
.filter(
f ->
f.getAnnotation(JsonProperty.class) != null
&& f.getAnnotation(JsonProperty.class).value().equals("objectID"))
.findFirst();
}
/**
* Recursively search for the given field in the given class
*
* @param clazz The class to reflect on
* @param fieldName The field to reach
*/
private static Field getField(@Nonnull Class> clazz, @Nonnull String fieldName) {
Class> tmpClass = clazz;
do {
try {
Field f = tmpClass.getDeclaredField(fieldName);
f.setAccessible(true);
return f;
} catch (NoSuchFieldException e) {
tmpClass = tmpClass.getSuperclass();
}
} while (tmpClass != null);
return null;
}
/**
* Recursively search for all fields in the given class
*
* @param clazz The class to reflect on
*/
private static List getFields(@Nonnull Class> clazz) {
List result = new ArrayList<>();
Class> i = clazz;
while (i != null && i != Object.class) {
Collections.addAll(result, i.getDeclaredFields());
i = i.getSuperclass();
}
return result;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy