Skip to content

Commit 42ce0f5

Browse files
dmealingclaude
andcommitted
Implement comprehensive targeted type-safe improvements across metadata framework
PHASE 2: Add type-safe alternatives alongside existing methods to eliminate unsafe casting ## Core Improvements: ### MetaData.java (+29 lines) - Add getSuperDataSafe() with Optional return and type checking - Add addMetaAttrSafe() returning concrete MetaData type - Add addChildSafe() returning concrete MetaData type - Maintains backward compatibility while providing type-safe alternatives ### ValidationChain.java (+19 lines) - Add type-hinted builder() methods with Class<T> parameter - Enable cleaner type inference: builder(MetaData.class) - Reduces need for explicit type parameters ### IndexedMetaDataCollection.java (+14 lines) - Add findByClassSafe() with stream-based filtering and casting - Eliminates unsafe List<MetaData> to List<T> cast - Guarantees returned items match specified type ### MetaField.java (+10 lines) - Add addMetaViewSafe() returning concrete MetaField<T> type - Eliminates generic T cast in fluent interface ## Benefits Achieved: ✅ Eliminate ClassCastException risks in collection operations ✅ Improve IDE IntelliSense and compile-time type checking ✅ Provide Optional-based APIs for safer null handling ✅ Maintain 100% backward compatibility ✅ All 72 lines of improvements compile and test successfully No breaking changes - existing code continues to work unchanged while new type-safe alternatives are available for adoption. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 0278a2b commit 42ce0f5

4 files changed

Lines changed: 72 additions & 0 deletions

File tree

metadata/src/main/java/com/draagon/meta/MetaData.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,15 @@ public <T extends MetaData> T getSuperData() {
520520
return (T) superData;
521521
}
522522

523+
/**
524+
* Gets the Super Data with type safety - returns Optional to avoid ClassCastException
525+
* @param type The expected type of the super data
526+
* @return Optional containing the super data if it matches the expected type
527+
*/
528+
public <T extends MetaData> Optional<T> getSuperDataSafe(Class<T> type) {
529+
return type.isInstance(superData) ? Optional.of(type.cast(superData)) : Optional.empty();
530+
}
531+
523532
/**
524533
* Returns whether this MetaData has a Super MetaData
525534
* @return SuperData exists
@@ -540,6 +549,16 @@ public <T extends MetaData> T addMetaAttr(MetaAttribute attr) {
540549
return (T) this;
541550
}
542551

552+
/**
553+
* Sets an attribute of the MetaClass and returns this MetaData (type-safe version)
554+
* @param attr The attribute to add
555+
* @return This MetaData instance for method chaining
556+
*/
557+
public MetaData addMetaAttrSafe(MetaAttribute attr) {
558+
addChild(attr);
559+
return this;
560+
}
561+
543562
/**
544563
* Retrieves an attribute value of the MetaData
545564
*/
@@ -652,6 +671,16 @@ public <T extends MetaData> T addChild(MetaData data) throws InvalidMetaDataExce
652671
return (T) this;
653672
}
654673

674+
/**
675+
* Adds a child MetaData object and returns this MetaData (type-safe version)
676+
* @param data The child MetaData to add
677+
* @return This MetaData instance for method chaining
678+
*/
679+
public MetaData addChildSafe(MetaData data) throws InvalidMetaDataException {
680+
addChild(data, true);
681+
return this;
682+
}
683+
655684
/**
656685
* Check whether this MetaData is a valid Child to add
657686
* @param data MetaData to add as a Child

metadata/src/main/java/com/draagon/meta/collections/IndexedMetaDataCollection.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,20 @@ public <T extends MetaData> List<T> findByClass(Class<T> clazz) {
162162
List<MetaData> found = classIndex.getOrDefault(clazz, Collections.emptyList());
163163
return (List<T>) found;
164164
}
165+
166+
/**
167+
* Find children by class with type safety - filters and casts safely
168+
*
169+
* @param clazz The class to search for
170+
* @return List of children guaranteed to be of the specified class
171+
*/
172+
public <T extends MetaData> List<T> findByClassSafe(Class<T> clazz) {
173+
List<MetaData> found = classIndex.getOrDefault(clazz, Collections.emptyList());
174+
return found.stream()
175+
.filter(clazz::isInstance)
176+
.map(clazz::cast)
177+
.collect(java.util.stream.Collectors.toList());
178+
}
165179

166180
/**
167181
* Find children matching a predicate

metadata/src/main/java/com/draagon/meta/field/MetaField.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,16 @@ public <T extends MetaField> T addMetaView(MetaView view) {
434434
return (T) this;
435435
}
436436

437+
/**
438+
* Adds a MetaView to this MetaField (type-safe version)
439+
* @param view MetaView to add
440+
* @return This MetaField instance for method chaining
441+
*/
442+
public MetaField<T> addMetaViewSafe(MetaView view) {
443+
addChild(view);
444+
return this;
445+
}
446+
437447
/**
438448
* Adds a MetaView to this MetaField
439449
*

metadata/src/main/java/com/draagon/meta/validation/ValidationChain.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,25 @@ public static <T> Builder<T> builder(String chainName) {
206206
return new Builder<T>().withName(chainName);
207207
}
208208

209+
/**
210+
* Create a type-hinted builder for cleaner type inference
211+
* @param type The class of objects this chain will validate
212+
* @return A builder with proper type inference
213+
*/
214+
public static <T> Builder<T> builder(Class<T> type) {
215+
return new Builder<>();
216+
}
217+
218+
/**
219+
* Create a named, type-hinted builder for cleaner type inference
220+
* @param type The class of objects this chain will validate
221+
* @param chainName The name for this validation chain
222+
* @return A builder with proper type inference
223+
*/
224+
public static <T> Builder<T> builder(Class<T> type, String chainName) {
225+
return new Builder<T>().withName(chainName);
226+
}
227+
209228
/**
210229
* Builder class for fluent ValidationChain construction
211230
*/

0 commit comments

Comments
 (0)