CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-dropwizard--dropwizard-util

Dropwizard utility classes for data sizes, durations, enums, generics, resources, exceptions, JAR locations, and direct execution services.

Pending
Overview
Eval results
Files

enum-generics.mddocs/

Enum and Generic Utilities

Utilities for flexible enum conversion with fuzzy matching and generic type parameter reflection capabilities.

Enums Class

The Enums utility class provides helper methods for enum types with more permissive conversion rules than the standard Enum.valueOf() method.

Fuzzy String Conversion

public static Enum<?> fromStringFuzzy(String value, Enum<?>[] constants);

Convert a string to an enum with more permissive rules than standard Enum.valueOf().

Parameters:

  • value - The string to convert to an enum constant
  • constants - Array of enum constants (typically obtained via EnumClass.values())

Returns: The matching enum constant, or null if no match found

Permissive Matching Rules:

  1. Whitespace removal: Strips all whitespace (spaces, tabs, newlines, carriage returns)
  2. Character normalization: Converts dashes (-) and periods (.) to underscores (_)
  3. Case insensitive: Matching is case-insensitive
  4. toString() fallback: If name-based matching fails, tries matching against toString() output

Usage Examples

Basic Enum Conversion

// Define an enum
public enum Color {
    RED, GREEN, BLUE, DARK_BLUE
}

// Standard conversion (would throw exception for many inputs)
Color standard = Color.valueOf("RED"); // Works
// Color.valueOf("red"); // Would throw IllegalArgumentException

// Fuzzy conversion (more flexible)
Color fuzzy1 = (Color) Enums.fromStringFuzzy("red", Color.values());     // RED
Color fuzzy2 = (Color) Enums.fromStringFuzzy("RED", Color.values());     // RED  
Color fuzzy3 = (Color) Enums.fromStringFuzzy("dark-blue", Color.values()); // DARK_BLUE
Color fuzzy4 = (Color) Enums.fromStringFuzzy("dark.blue", Color.values()); // DARK_BLUE
Color fuzzy5 = (Color) Enums.fromStringFuzzy("DARK_BLUE", Color.values()); // DARK_BLUE

Whitespace Handling

public enum Status {
    ACTIVE, INACTIVE, PENDING_APPROVAL
}

// Handles various whitespace scenarios
Status status1 = (Status) Enums.fromStringFuzzy("active", Status.values());
Status status2 = (Status) Enums.fromStringFuzzy(" ACTIVE ", Status.values());
Status status3 = (Status) Enums.fromStringFuzzy("pending\napproval", Status.values());
Status status4 = (Status) Enums.fromStringFuzzy("pending\t approval", Status.values());
// All return Status.ACTIVE or Status.PENDING_APPROVAL respectively

toString() Fallback Support

public enum HttpMethod {
    GET("get"),
    POST("post"),
    PUT("put"),
    DELETE("delete");
    
    private final String value;
    
    HttpMethod(String value) {
        this.value = value;
    }
    
    @Override
    public String toString() {
        return value;
    }
}

// First tries name matching, then toString() matching
HttpMethod method1 = (HttpMethod) Enums.fromStringFuzzy("GET", HttpMethod.values());    // Matches name
HttpMethod method2 = (HttpMethod) Enums.fromStringFuzzy("get", HttpMethod.values());    // Matches toString()
HttpMethod method3 = (HttpMethod) Enums.fromStringFuzzy("post", HttpMethod.values());   // Matches toString()

Configuration Parsing

public enum LogLevel {
    TRACE, DEBUG, INFO, WARN, ERROR
}

public class Configuration {
    public LogLevel parseLogLevel(String configValue) {
        LogLevel level = (LogLevel) Enums.fromStringFuzzy(configValue, LogLevel.values());
        if (level == null) {
            throw new IllegalArgumentException("Invalid log level: " + configValue);
        }
        return level;
    }
}

// Usage
Configuration config = new Configuration();
LogLevel level1 = config.parseLogLevel("info");      // INFO
LogLevel level2 = config.parseLogLevel("DEBUG");     // DEBUG  
LogLevel level3 = config.parseLogLevel("warn");      // WARN

Generics Class

The Generics utility class provides helper methods for class type parameters and reflection operations, particularly useful for retrieving generic type information at runtime.

Type Parameter Extraction

public static Class<?> getTypeParameter(Class<?> klass);
public static <T> Class<T> getTypeParameter(Class<?> klass, Class<? super T> bound);

Find the type parameter for a given parameterized class.

Parameters:

  • klass - A parameterized class
  • bound - The type bound for the second overload

Returns: The class's type parameter

Throws:

  • IllegalStateException - If type parameterization cannot be determined

Usage Examples

Basic Type Parameter Extraction

// Define a generic base class
public abstract class BaseRepository<T> {
    private final Class<T> entityClass;
    
    public BaseRepository() {
        this.entityClass = Generics.getTypeParameter(getClass());
    }
    
    public Class<T> getEntityClass() {
        return entityClass;
    }
}

// Concrete implementation
public class UserRepository extends BaseRepository<User> {
    // Constructor automatically determines T = User
}

// Usage
UserRepository userRepo = new UserRepository();
Class<?> entityClass = userRepo.getEntityClass(); // Returns User.class

Bounded Type Parameter Extraction

// Define classes with inheritance hierarchy
public abstract class Entity {
    // Base entity class
}

public class User extends Entity {
    // User entity
}

public class Product extends Entity {
    // Product entity  
}

// Generic service with bounded type parameter
public abstract class EntityService<T extends Entity> {
    private final Class<T> entityClass;
    
    public EntityService() {
        this.entityClass = Generics.getTypeParameter(getClass(), Entity.class);
    }
    
    public Class<T> getEntityClass() {
        return entityClass;
    }
}

// Concrete implementations
public class UserService extends EntityService<User> {
    // Constructor automatically determines T = User (bounded by Entity)
}

public class ProductService extends EntityService<Product> {
    // Constructor automatically determines T = Product (bounded by Entity)
}

// Usage
UserService userService = new UserService();
Class<User> userClass = userService.getEntityClass(); // Returns User.class

ProductService productService = new ProductService();
Class<Product> productClass = productService.getEntityClass(); // Returns Product.class

Repository Pattern with Type Safety

public abstract class GenericDao<T> {
    private final Class<T> entityClass;
    
    public GenericDao() {
        this.entityClass = Generics.getTypeParameter(getClass());
    }
    
    public T findById(Long id) {
        // Use entityClass for database operations
        return entityManager.find(entityClass, id);
    }
    
    public List<T> findAll() {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<T> query = cb.createQuery(entityClass);
        query.select(query.from(entityClass));
        return entityManager.createQuery(query).getResultList();
    }
    
    public void save(T entity) {
        entityManager.persist(entity);
    }
}

// Concrete DAOs
public class UserDao extends GenericDao<User> {
    // Inherits all generic operations typed for User
}

public class OrderDao extends GenericDao<Order> {
    // Inherits all generic operations typed for Order
}

Jackson/JSON Serialization Support

public abstract class JsonHandler<T> {
    private final Class<T> typeClass;
    private final ObjectMapper objectMapper;
    
    public JsonHandler(ObjectMapper objectMapper) {
        this.typeClass = Generics.getTypeParameter(getClass());
        this.objectMapper = objectMapper;
    }
    
    public T deserialize(String json) throws IOException {
        return objectMapper.readValue(json, typeClass);
    }
    
    public String serialize(T object) throws IOException {
        return objectMapper.writeValueAsString(object);
    }
    
    public Class<T> getTypeClass() {
        return typeClass;
    }
}

// Concrete handlers
public class UserJsonHandler extends JsonHandler<User> {
    public UserJsonHandler(ObjectMapper objectMapper) {
        super(objectMapper);
    }
}

// Usage
ObjectMapper mapper = new ObjectMapper();
UserJsonHandler userHandler = new UserJsonHandler(mapper);

String userJson = "{\"name\":\"John\",\"email\":\"john@example.com\"}";
User user = userHandler.deserialize(userJson);
String serialized = userHandler.serialize(user);

Error Handling

Enums Error Handling

public enum Color {
    RED, GREEN, BLUE
}

// fromStringFuzzy returns null for no match (doesn't throw exception)
Enum<?> result = Enums.fromStringFuzzy("yellow", Color.values());
if (result == null) {
    // Handle unknown enum value
    throw new IllegalArgumentException("Unknown color: yellow");
}

Generics Error Handling

// Generics throws IllegalStateException for complex type scenarios
try {
    Class<?> typeParam = Generics.getTypeParameter(SomeComplexClass.class);
} catch (IllegalStateException e) {
    // Handle cases where type parameterization cannot be determined
    // This typically happens with complex type hierarchies or runtime type erasure issues
}

Advanced Patterns

Configuration with Enum Defaults

public class ServiceConfiguration {
    public enum Environment {
        DEVELOPMENT, STAGING, PRODUCTION
    }
    
    public Environment parseEnvironment(String envString, Environment defaultEnv) {
        if (envString == null || envString.trim().isEmpty()) {
            return defaultEnv;
        }
        
        Environment env = (Environment) Enums.fromStringFuzzy(envString, Environment.values());
        return env != null ? env : defaultEnv;
    }
}

Generic Factory Pattern

public abstract class EntityFactory<T> {
    private final Class<T> entityClass;
    
    public EntityFactory() {
        this.entityClass = Generics.getTypeParameter(getClass());
    }
    
    public T createEntity() {
        try {
            return entityClass.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Cannot create entity of type: " + entityClass, e);
        }
    }
    
    public Class<T> getEntityType() {
        return entityClass;
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-io-dropwizard--dropwizard-util

docs

data-size.md

duration.md

enum-generics.md

index.md

jar-executor.md

resource-exception.md

tile.json