Consider adding type parameters to AbstractTestElement so elements are linked with schemas
- Dominant language
- Java
- Stars
- 9.5k
- Forks
- 2.3k
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 5
Description
### Use case
https://github.com/apache/jmeter/issues/5946 adds schemes in backward-compatible way, so `TestElement` implements default methods `getSchema() = TestElementSchema` and `getProps() = ...`, however it does not enforce constraints on the schemas.
With suggestion in 596, every element has to override two methods, and the second one has to be in every subclass otherwise `getProps()` will return base `PropertiesAccessor`, so extra properties won't be visible in autocomplete.
```java
// Users need to override two methods with a concrete types
// Here's an example for AbstractThreadGroup
@Override
public AbstractThreadGroupSchema getSchema() {
return AbstractThreadGroupSchema.INSTANCE;
}
// The generics should be `? extends ..`, so subclasses can override with subtypes
@Override
public PropertiesAccessor getProps() {
return new PropertiesAccessor<>(this, getSchema());
}
```
We can't add generics to `TestElement`, see https://github.com/apache/jmeter/issues/5946#issuecomment-1565639598.
### Possible solution
If we add generics to `AbstractTestElement`, then we could link elements with their schemas:
```java
public abstract class AbstractTestElement<
Schema extends TestElementSchema,
TestElementClass extends AbstractTestElement>
implements TestElement, Serializable, Searchable {
private final PropertiesAccessor props = new PropertiesAccessor(this, getSchema());
// If we add generics, then getProps could be implemented in a single place (in AbstractTestElement),
// and the elements would inherit it, however, they would need to add type parameters
public PropertiesAccessor getProps() {
return props; // it is safe to reuse a single instance and "unsafe cast" is safe here
}
...
public abstract class AbstractThreadGroup<
Schema extends AbstractThreadGroupSchema,
TestElementClass extends AbstractThreadGroup>
extends AbstractTestElement
implements Serializable, Controller, JMeterThreadMonitor, TestCompilerHelper {
```
...
```kotlin
public class OpenModelThreadGroup :
AbstractThreadGroup(),
```
However, adding generics to `AbstractTestElement` is likely a disruptive change. For instance, Kotlin does not support raw types, and if we add generics to `AbstractTestElement`, `AbstractThreadGroup`, and so on, then Kotlin users would have to change their code in order to compile with never JMeter versions. Even though it should not be a big deal, recursive generics are not easy.
### Possible workarounds
_No response_
### JMeter Version
5.5
### Java Version
_No response_
### OS Version
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.