If a parameter represents a generic component such as authentication or destination, multiple valid sets of configurations are allowed. Your authentication can be of different types (basic, digest, ntlm, oauth) but it is a terrible experience for the user to have all the parameters of each authentication available all at once.
For example, if we want an authentication that supports basic, digest and ntlm in a single parameter, our Authentication class would be short, but also confusing:
public class Authentication {
@Parameter
private boolean useDigest; (1)
@Parameter
private String username;
@Parameter
@Password
private String password;
@Parameter
@Optional
private String domain; (2)
@Parameter
@Optional
private String workstation;
}
| 1 |
The parameter useDigest only exists to separate basic and digest |
| 2 |
domain and workstation are only relevant for an ntlm configuration, making useDigest irrelevant. |
It’s easy to get lost in the correct configuration even when you need only four parameters.
Instead, if you use @SubTypeMapping, it’s easy to understand how to use the types from the code itself, and declaring values is more concise:
@Extension(name = "HTTP")
@SubTypeMapping(baseType = Authentication.class, (1)
subTypes = {BasicAuthentication.class, DigestAuthentication.class, NtlmAuthentication.class})
public class HttpConnector {
}
public interface Authentication { (2)
void authenticate(HttpRequestBuilder builder);
}
public class BasicAuthentication implements Authentication { (3)
@Parameter
private String username;
@Parameter
@Password
private String password;
}
public class DigestAuthentication implements Authentication { (4)
@Parameter
private String username;
@Parameter
@Password
private String password;
}
public class NtlmAuthentication implements Authentication { (5)
@Parameter
private String username;
@Parameter
@Password
private String password;
@Parameter
@Optional
private String domain;
@Parameter
@Optional
private String workstation;
}
| 1 |
Declaration of the SubTypeMapping |
| 2 |
Generic Authentication interface |
| 3 |
Implementation of Authentication as basic |
| 4 |
Implementation of Authentication as digest |
| 5 |
Implementation of Authentication as ntlm |
Next, declare a parameter of the generic type Authentication:
@Alias("request")
public class HttpRequesterProvider implements CachedConnectionProvider<HttpExtensionClient> {
@Parameter
private Authentication authentication;
}
Now the user is able to declare each of the three possible values in a more concise and coherent way:
<http:request-connection>
<http:authentication>
<http:basic-authentication username="withBasic" password="123">
</http:authentication>
</http:request-connection>
<http:request-connection>
<http:authentication>
<http:digest-authentication username="withDigest" password="456">
</http:authentication>
</http:request-connection>
<http:request-connection>
<http:authentication>
<http:ntlm-authentication username="withNtlm" password="Beeblebrox" domain="Ursa-Minor"/>>
</http:authentication>
</http:request-connection>