or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-size.mdduration.mdenum-generics.mdindex.mdjar-executor.mdresource-exception.md

enum-generics.mddocs/

0

# Enum and Generic Utilities

1

2

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

3

4

## Enums Class

5

6

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

7

8

### Fuzzy String Conversion

9

10

```java { .api }

11

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

12

```

13

14

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

15

16

**Parameters:**

17

- `value` - The string to convert to an enum constant

18

- `constants` - Array of enum constants (typically obtained via `EnumClass.values()`)

19

20

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

21

22

**Permissive Matching Rules:**

23

1. **Whitespace removal**: Strips all whitespace (spaces, tabs, newlines, carriage returns)

24

2. **Character normalization**: Converts dashes (`-`) and periods (`.`) to underscores (`_`)

25

3. **Case insensitive**: Matching is case-insensitive

26

4. **toString() fallback**: If name-based matching fails, tries matching against `toString()` output

27

28

### Usage Examples

29

30

#### Basic Enum Conversion

31

32

```java

33

// Define an enum

34

public enum Color {

35

RED, GREEN, BLUE, DARK_BLUE

36

}

37

38

// Standard conversion (would throw exception for many inputs)

39

Color standard = Color.valueOf("RED"); // Works

40

// Color.valueOf("red"); // Would throw IllegalArgumentException

41

42

// Fuzzy conversion (more flexible)

43

Color fuzzy1 = (Color) Enums.fromStringFuzzy("red", Color.values()); // RED

44

Color fuzzy2 = (Color) Enums.fromStringFuzzy("RED", Color.values()); // RED

45

Color fuzzy3 = (Color) Enums.fromStringFuzzy("dark-blue", Color.values()); // DARK_BLUE

46

Color fuzzy4 = (Color) Enums.fromStringFuzzy("dark.blue", Color.values()); // DARK_BLUE

47

Color fuzzy5 = (Color) Enums.fromStringFuzzy("DARK_BLUE", Color.values()); // DARK_BLUE

48

```

49

50

#### Whitespace Handling

51

52

```java

53

public enum Status {

54

ACTIVE, INACTIVE, PENDING_APPROVAL

55

}

56

57

// Handles various whitespace scenarios

58

Status status1 = (Status) Enums.fromStringFuzzy("active", Status.values());

59

Status status2 = (Status) Enums.fromStringFuzzy(" ACTIVE ", Status.values());

60

Status status3 = (Status) Enums.fromStringFuzzy("pending\napproval", Status.values());

61

Status status4 = (Status) Enums.fromStringFuzzy("pending\t approval", Status.values());

62

// All return Status.ACTIVE or Status.PENDING_APPROVAL respectively

63

```

64

65

#### toString() Fallback Support

66

67

```java

68

public enum HttpMethod {

69

GET("get"),

70

POST("post"),

71

PUT("put"),

72

DELETE("delete");

73

74

private final String value;

75

76

HttpMethod(String value) {

77

this.value = value;

78

}

79

80

@Override

81

public String toString() {

82

return value;

83

}

84

}

85

86

// First tries name matching, then toString() matching

87

HttpMethod method1 = (HttpMethod) Enums.fromStringFuzzy("GET", HttpMethod.values()); // Matches name

88

HttpMethod method2 = (HttpMethod) Enums.fromStringFuzzy("get", HttpMethod.values()); // Matches toString()

89

HttpMethod method3 = (HttpMethod) Enums.fromStringFuzzy("post", HttpMethod.values()); // Matches toString()

90

```

91

92

#### Configuration Parsing

93

94

```java

95

public enum LogLevel {

96

TRACE, DEBUG, INFO, WARN, ERROR

97

}

98

99

public class Configuration {

100

public LogLevel parseLogLevel(String configValue) {

101

LogLevel level = (LogLevel) Enums.fromStringFuzzy(configValue, LogLevel.values());

102

if (level == null) {

103

throw new IllegalArgumentException("Invalid log level: " + configValue);

104

}

105

return level;

106

}

107

}

108

109

// Usage

110

Configuration config = new Configuration();

111

LogLevel level1 = config.parseLogLevel("info"); // INFO

112

LogLevel level2 = config.parseLogLevel("DEBUG"); // DEBUG

113

LogLevel level3 = config.parseLogLevel("warn"); // WARN

114

```

115

116

## Generics Class

117

118

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

119

120

### Type Parameter Extraction

121

122

```java { .api }

123

public static Class<?> getTypeParameter(Class<?> klass);

124

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

125

```

126

127

Find the type parameter for a given parameterized class.

128

129

**Parameters:**

130

- `klass` - A parameterized class

131

- `bound` - The type bound for the second overload

132

133

**Returns:** The class's type parameter

134

135

**Throws:**

136

- `IllegalStateException` - If type parameterization cannot be determined

137

138

### Usage Examples

139

140

#### Basic Type Parameter Extraction

141

142

```java

143

// Define a generic base class

144

public abstract class BaseRepository<T> {

145

private final Class<T> entityClass;

146

147

public BaseRepository() {

148

this.entityClass = Generics.getTypeParameter(getClass());

149

}

150

151

public Class<T> getEntityClass() {

152

return entityClass;

153

}

154

}

155

156

// Concrete implementation

157

public class UserRepository extends BaseRepository<User> {

158

// Constructor automatically determines T = User

159

}

160

161

// Usage

162

UserRepository userRepo = new UserRepository();

163

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

164

```

165

166

#### Bounded Type Parameter Extraction

167

168

```java

169

// Define classes with inheritance hierarchy

170

public abstract class Entity {

171

// Base entity class

172

}

173

174

public class User extends Entity {

175

// User entity

176

}

177

178

public class Product extends Entity {

179

// Product entity

180

}

181

182

// Generic service with bounded type parameter

183

public abstract class EntityService<T extends Entity> {

184

private final Class<T> entityClass;

185

186

public EntityService() {

187

this.entityClass = Generics.getTypeParameter(getClass(), Entity.class);

188

}

189

190

public Class<T> getEntityClass() {

191

return entityClass;

192

}

193

}

194

195

// Concrete implementations

196

public class UserService extends EntityService<User> {

197

// Constructor automatically determines T = User (bounded by Entity)

198

}

199

200

public class ProductService extends EntityService<Product> {

201

// Constructor automatically determines T = Product (bounded by Entity)

202

}

203

204

// Usage

205

UserService userService = new UserService();

206

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

207

208

ProductService productService = new ProductService();

209

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

210

```

211

212

#### Repository Pattern with Type Safety

213

214

```java

215

public abstract class GenericDao<T> {

216

private final Class<T> entityClass;

217

218

public GenericDao() {

219

this.entityClass = Generics.getTypeParameter(getClass());

220

}

221

222

public T findById(Long id) {

223

// Use entityClass for database operations

224

return entityManager.find(entityClass, id);

225

}

226

227

public List<T> findAll() {

228

CriteriaBuilder cb = entityManager.getCriteriaBuilder();

229

CriteriaQuery<T> query = cb.createQuery(entityClass);

230

query.select(query.from(entityClass));

231

return entityManager.createQuery(query).getResultList();

232

}

233

234

public void save(T entity) {

235

entityManager.persist(entity);

236

}

237

}

238

239

// Concrete DAOs

240

public class UserDao extends GenericDao<User> {

241

// Inherits all generic operations typed for User

242

}

243

244

public class OrderDao extends GenericDao<Order> {

245

// Inherits all generic operations typed for Order

246

}

247

```

248

249

#### Jackson/JSON Serialization Support

250

251

```java

252

public abstract class JsonHandler<T> {

253

private final Class<T> typeClass;

254

private final ObjectMapper objectMapper;

255

256

public JsonHandler(ObjectMapper objectMapper) {

257

this.typeClass = Generics.getTypeParameter(getClass());

258

this.objectMapper = objectMapper;

259

}

260

261

public T deserialize(String json) throws IOException {

262

return objectMapper.readValue(json, typeClass);

263

}

264

265

public String serialize(T object) throws IOException {

266

return objectMapper.writeValueAsString(object);

267

}

268

269

public Class<T> getTypeClass() {

270

return typeClass;

271

}

272

}

273

274

// Concrete handlers

275

public class UserJsonHandler extends JsonHandler<User> {

276

public UserJsonHandler(ObjectMapper objectMapper) {

277

super(objectMapper);

278

}

279

}

280

281

// Usage

282

ObjectMapper mapper = new ObjectMapper();

283

UserJsonHandler userHandler = new UserJsonHandler(mapper);

284

285

String userJson = "{\"name\":\"John\",\"email\":\"john@example.com\"}";

286

User user = userHandler.deserialize(userJson);

287

String serialized = userHandler.serialize(user);

288

```

289

290

## Error Handling

291

292

### Enums Error Handling

293

294

```java

295

public enum Color {

296

RED, GREEN, BLUE

297

}

298

299

// fromStringFuzzy returns null for no match (doesn't throw exception)

300

Enum<?> result = Enums.fromStringFuzzy("yellow", Color.values());

301

if (result == null) {

302

// Handle unknown enum value

303

throw new IllegalArgumentException("Unknown color: yellow");

304

}

305

```

306

307

### Generics Error Handling

308

309

```java

310

// Generics throws IllegalStateException for complex type scenarios

311

try {

312

Class<?> typeParam = Generics.getTypeParameter(SomeComplexClass.class);

313

} catch (IllegalStateException e) {

314

// Handle cases where type parameterization cannot be determined

315

// This typically happens with complex type hierarchies or runtime type erasure issues

316

}

317

```

318

319

## Advanced Patterns

320

321

### Configuration with Enum Defaults

322

323

```java

324

public class ServiceConfiguration {

325

public enum Environment {

326

DEVELOPMENT, STAGING, PRODUCTION

327

}

328

329

public Environment parseEnvironment(String envString, Environment defaultEnv) {

330

if (envString == null || envString.trim().isEmpty()) {

331

return defaultEnv;

332

}

333

334

Environment env = (Environment) Enums.fromStringFuzzy(envString, Environment.values());

335

return env != null ? env : defaultEnv;

336

}

337

}

338

```

339

340

### Generic Factory Pattern

341

342

```java

343

public abstract class EntityFactory<T> {

344

private final Class<T> entityClass;

345

346

public EntityFactory() {

347

this.entityClass = Generics.getTypeParameter(getClass());

348

}

349

350

public T createEntity() {

351

try {

352

return entityClass.getDeclaredConstructor().newInstance();

353

} catch (Exception e) {

354

throw new RuntimeException("Cannot create entity of type: " + entityClass, e);

355

}

356

}

357

358

public Class<T> getEntityType() {

359

return entityClass;

360

}

361

}

362

```