Skip to content

Commit

Permalink
DateUtilities - improved TimeZone handling, consolidated and strength…
Browse files Browse the repository at this point in the history
…ened regex's
  • Loading branch information
jdereg committed Jan 7, 2024
1 parent 871e411 commit d7a0a45
Show file tree
Hide file tree
Showing 6 changed files with 546 additions and 271 deletions.
4 changes: 2 additions & 2 deletions src/main/java/com/cedarsoftware/util/CompactMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* Many developers do not realize than they may have thousands or hundreds of thousands of Maps in memory, often
* representing small JSON objects. These maps (often HashMaps) usually have a table of 16/32/64... elements in them,
* with many empty elements. HashMap doubles it's internal storage each time it expands, so often these Maps have
* fewer than 50% of these arrays filled.<p></p>
* barely 50% of these arrays filled.<p></p>
*
* CompactMap is a Map that strives to reduce memory at all costs while retaining speed that is close to HashMap's speed.
* It does this by using only one (1) member variable (of type Object) and changing it as the Map grows. It goes from
Expand All @@ -35,7 +35,7 @@
* // Map you would like it to use when size() {@literal >} compactSize(). HashMap is default
* protected abstract Map{@literal <}K, V{@literal >} getNewMap();
*
* // If you want case insensitivity, return true and return new CaseInsensitiveMap or TreeMap(String.CASE_INSENSITIVE_PRDER) from getNewMap()
* // If you want case insensitivity, return true and return new CaseInsensitiveMap or TreeMap(String.CASE_INSENSITIVE_ORDER) from getNewMap()
* protected boolean isCaseInsensitive() { return false; }
*
* // When size() {@literal >} than this amount, the Map returned from getNewMap() is used to store elements.
Expand Down
64 changes: 62 additions & 2 deletions src/main/java/com/cedarsoftware/util/Converter.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
Expand Down Expand Up @@ -101,6 +102,8 @@ protected interface Work<T>
conversion.put(AtomicInteger.class, Converter::convertToAtomicInteger);
conversion.put(AtomicLong.class, Converter::convertToAtomicLong);
conversion.put(AtomicBoolean.class, Converter::convertToAtomicBoolean);
conversion.put(Class.class, Converter::convertToClass);
conversion.put(UUID.class, Converter::convertToUUID);

conversionToString.put(String.class, fromInstance -> fromInstance);
conversionToString.put(BigDecimal.class, fromInstance -> {
Expand All @@ -125,7 +128,11 @@ protected interface Work<T>
Work<?> toNoExpString = Object::toString;
conversionToString.put(Double.class, toNoExpString);
conversionToString.put(Float.class, toNoExpString);

conversionToString.put(Class.class, fromInstance -> {
Class<?> clazz = (Class<?>) fromInstance;
return clazz.getName();
});
conversionToString.put(UUID.class, Object::toString);
conversionToString.put(Date.class, fromInstance -> SafeSimpleDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(fromInstance));
conversionToString.put(Character.class, fromInstance -> "" + fromInstance);
conversionToString.put(LocalDate.class, fromInstance -> {
Expand Down Expand Up @@ -232,6 +239,50 @@ else if (fromInstance instanceof Enum)
return nope(fromInstance, "String");
}

public static Class<?> convertToClass(Object fromInstance) {
if (fromInstance instanceof Class) {
return (Class<?>)fromInstance;
} else if (fromInstance instanceof String) {
try {
Class<?> clazz = Class.forName((String)fromInstance);
return clazz;
}
catch (ClassNotFoundException ignore) {
}
}
throw new IllegalArgumentException("value [" + name(fromInstance) + "] could not be converted to a 'Class'");
}

public static UUID convertToUUID(Object fromInstance) {
try {
if (fromInstance instanceof UUID) {
return (UUID)fromInstance;
} else if (fromInstance instanceof String) {
return UUID.fromString((String)fromInstance);
} else if (fromInstance instanceof BigInteger) {
BigInteger bigInteger = (BigInteger) fromInstance;
BigInteger mask = BigInteger.valueOf(Long.MAX_VALUE);
long mostSignificantBits = bigInteger.shiftRight(64).and(mask).longValue();
long leastSignificantBits = bigInteger.and(mask).longValue();
return new UUID(mostSignificantBits, leastSignificantBits);
}
else if (fromInstance instanceof Map) {
Map<?, ?> map = (Map<?, ?>) fromInstance;
if (map.containsKey("mostSigBits") && map.containsKey("leastSigBits")) {
long mostSigBits = convert2long(map.get("mostSigBits"));
long leastSigBits = convert2long(map.get("leastSigBits"));
return new UUID(mostSigBits, leastSigBits);
} else {
throw new IllegalArgumentException("To convert Map to UUID, the Map must contain both a 'mostSigBits' and 'leastSigBits' key.");
}
}
} catch (Exception e) {
throw new IllegalArgumentException("value [" + name(fromInstance) + "] could not be converted to a 'UUID'", e);
}
nope(fromInstance, "UUID");
return null;
}

/**
* Convert from the passed in instance to a BigDecimal. If null or "" is passed in, this method will return a
* BigDecimal with the value of 0. Possible inputs are String (base10 numeric values in string), BigInteger,
Expand Down Expand Up @@ -374,6 +425,12 @@ else if (fromInstance instanceof BigDecimal)
else if (fromInstance instanceof Number)
{
return new BigInteger(Long.toString(((Number) fromInstance).longValue()));
} else if (fromInstance instanceof UUID) {
UUID uuid = (UUID) fromInstance;
BigInteger mostSignificant = BigInteger.valueOf(uuid.getMostSignificantBits());
BigInteger leastSignificant = BigInteger.valueOf(uuid.getLeastSignificantBits());
// Shift the most significant bits to the left and add the least significant bits
return mostSignificant.shiftLeft(64).add(leastSignificant);
}
else if (fromInstance instanceof Boolean)
{
Expand Down Expand Up @@ -823,7 +880,7 @@ else if (fromInstance instanceof AtomicLong)
}
catch (Exception e)
{
throw new IllegalArgumentException("value [" + name(fromInstance) + "] could not be converted to a 'LocalDateTime'", e);
throw new IllegalArgumentException("value [" + name(fromInstance) + "] could not be converted to a 'ZonedDateTime'", e);
}
nope(fromInstance, "LocalDateTime");
return null;
Expand Down Expand Up @@ -1541,6 +1598,9 @@ private static String nope(Object fromInstance, String targetType)

private static String name(Object fromInstance)
{
if (fromInstance == null) {
return "null";
}
return fromInstance.getClass().getName() + " (" + fromInstance.toString() + ")";
}

Expand Down
Loading

0 comments on commit d7a0a45

Please sign in to comment.