void assertUnfrozen() { if (frozen) { throw new DatabaseException( "Modifications to DatabaseConfig objects must occur before they are in use"); } }
code = ChatError.Code.USER_CODE_EXCEPTION; String[] stacktrace = error.toException().getMessage().split(": ");
/** * Can be used if a third party needs an Exception from Firebase Database for integration * purposes. * * @return An exception wrapping this error, with an appropriate message and no stack trace. */ public DatabaseException toException() { return new DatabaseException("Firebase Database error: " + message); } }
@SuppressWarnings("unchecked") private static Map<String, Object> expectMap(Object object) { if (object instanceof Map) { // TODO: runtime validation of keys? return (Map<String, Object>) object; } else { throw new DatabaseException( "Expected a Map while deserializing, but got a " + object.getClass()); } }
private static void validateDoubleValue(double d) { if (Double.isInfinite(d) || Double.isNaN(d)) { throw new DatabaseException("Invalid value: Value cannot be NaN, Inf or -Inf."); } }
private static Boolean convertBoolean(Object obj) { if (obj instanceof Boolean) { return (Boolean) obj; } else { throw new DatabaseException( "Failed to convert value of type " + obj.getClass().getName() + " to boolean"); } }
private static String convertString(Object obj) { if (obj instanceof String) { return (String) obj; } else { throw new DatabaseException( "Failed to convert value of type " + obj.getClass().getName() + " to String"); } }
private void addProperty(String property) { String oldValue = this.properties.put(property.toLowerCase(), property); if (oldValue != null && !property.equals(oldValue)) { throw new DatabaseException( "Found two getters or fields with conflicting case " + "sensitivity for property: " + property.toLowerCase()); } }
@SuppressWarnings("unchecked") private static <T> T deserializeToEnum(Object object, Class<T> clazz) { if (object instanceof String) { String value = (String) object; // We cast to Class without generics here since we can't prove the bound // T extends Enum<T> statically try { return (T) Enum.valueOf((Class) clazz, value); } catch (IllegalArgumentException e) { throw new DatabaseException( "Could not find enum value of " + clazz.getName() + " for value \"" + value + "\""); } } else { throw new DatabaseException( "Expected a String while deserializing to enum " + clazz + " but got a " + object.getClass()); } }
private static Integer convertInteger(Object obj) { if (obj instanceof Integer) { return (Integer) obj; } else if (obj instanceof Long || obj instanceof Double) { double value = ((Number) obj).doubleValue(); if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) { return ((Number) obj).intValue(); } else { throw new DatabaseException( "Numeric value out of 32-bit integer range: " + value + ". Did you mean to use a long or double instead of an int?"); } } else { throw new DatabaseException( "Failed to convert a value of type " + obj.getClass().getName() + " to int"); } }
private void checkValid() throws DatabaseException { if (byteLength > MAX_PATH_LENGTH_BYTES) { throw new DatabaseException( "Data has a key path longer than " + MAX_PATH_LENGTH_BYTES + " bytes (" + byteLength + ")."); } if (parts.size() > MAX_PATH_DEPTH) { throw new DatabaseException( "Path specified exceeds the maximum depth that can be written (" + MAX_PATH_DEPTH + ") or object contains a cycle " + toErrorString()); } }
private static Long convertLong(Object obj) { if (obj instanceof Integer) { return ((Integer) obj).longValue(); } else if (obj instanceof Long) { return (Long) obj; } else if (obj instanceof Double) { Double value = (Double) obj; if (value >= Long.MIN_VALUE && value <= Long.MAX_VALUE) { return value.longValue(); } else { throw new DatabaseException( "Numeric value out of 64-bit long range: " + value + ". Did you mean to use a double instead of a long?"); } } else { throw new DatabaseException( "Failed to convert a value of type " + obj.getClass().getName() + " to long"); } }
public static void validateWritableKey(String key) throws DatabaseException { if (!isWritableKey(key)) { throw new DatabaseException( "Invalid key: " + key + ". Keys must not contain '/', '.', '#', '$', '[', or ']'"); } }
private void assertUnfrozen(String methodCalled) { synchronized (lock) { checkNotDestroyed(); if (this.repo != null) { throw new DatabaseException( "Calls to " + methodCalled + "() must be made before any " + "other usage of FirebaseDatabase instance."); } } }
public static void validateNullableKey(String key) throws DatabaseException { if (!(key == null || isValidKey(key))) { throw new DatabaseException( "Invalid key: " + key + ". Keys must not contain '/', '.', '#', '$', '[', or ']'"); } }
/** * By default Firebase Database will use up to 10MB of disk space to cache data. If the cache * grows beyond this size, Firebase Database will start removing data that hasn't been recently * used. If you find that your application caches too little or too much data, call this method to * change the cache size. This method must be called before creating your first Database reference * and only needs to be called once per application. * * <p>Note that the specified cache size is only an approximation and the size on disk may * temporarily exceed it at times. * * @param cacheSizeInBytes The new size of the cache in bytes. * @since 2.3 */ public synchronized void setPersistenceCacheSizeBytes(long cacheSizeInBytes) { assertUnfrozen(); if (cacheSizeInBytes < 1024 * 1024) { throw new DatabaseException("The minimum cache size must be at least 1MB"); } if (cacheSizeInBytes > 100 * 1024 * 1024) { throw new DatabaseException( "Firebase Database currently doesn't support a cache size larger than 100MB"); } this.cacheSize = cacheSizeInBytes; }
private static Double convertDouble(Object obj) { if (obj instanceof Integer) { return ((Integer) obj).doubleValue(); } else if (obj instanceof Long) { Long value = (Long) obj; Double doubleValue = ((Long) obj).doubleValue(); if (doubleValue.longValue() == value) { return doubleValue; } else { throw new DatabaseException( "Loss of precision while converting number to " + "double: " + obj + ". Did you mean to use a 64-bit long instead?"); } } else if (obj instanceof Double) { return (Double) obj; } else { throw new DatabaseException( "Failed to convert a value of type " + obj.getClass().getName() + " to double"); } }
public static void validatePathString(String pathString) throws DatabaseException { if (!isValidPathString(pathString)) { throw new DatabaseException( "Invalid Firebase Database path: " + pathString + ". Firebase Database paths must not contain '.', '#', '$', '[', or ']'"); } }
@SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) private static <T> T deserializeToType(Object obj, Type type) { if (obj == null) { return null; } else if (type instanceof ParameterizedType) { return deserializeToParameterizedType(obj, (ParameterizedType) type); } else if (type instanceof Class) { return deserializeToClass(obj, (Class<T>) type); } else if (type instanceof WildcardType) { throw new DatabaseException("Generic wildcard types are not supported"); } else if (type instanceof GenericArrayType) { throw new DatabaseException( "Generic Arrays are not supported, please use Lists " + "instead"); } else { throw new IllegalStateException("Unknown type encountered: " + type); } }
/** * Converts a standard library Java representation of JSON data to an object of the class provided * through the GenericTypeIndicator * * @param object The representation of the JSON data * @param typeIndicator The indicator providing class of the object to convert to * @return The POJO object. */ public static <T> T convertToCustomClass(Object object, GenericTypeIndicator<T> typeIndicator) { Class<?> clazz = typeIndicator.getClass(); Type genericTypeIndicatorType = clazz.getGenericSuperclass(); if (genericTypeIndicatorType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) genericTypeIndicatorType; if (!parameterizedType.getRawType().equals(GenericTypeIndicator.class)) { throw new DatabaseException( "Not a direct subclass of GenericTypeIndicator: " + genericTypeIndicatorType); } // We are guaranteed to have exactly one type parameter Type type = parameterizedType.getActualTypeArguments()[0]; return deserializeToType(object, type); } else { throw new DatabaseException( "Not a direct subclass of GenericTypeIndicator: " + genericTypeIndicatorType); } }