I have an HTTP client class that uses Generics. I would like to create a factory class that has a map with (key, value) => (String type, HttpClient<?>).
The HttpClient
class has one function that just sends data to the server depending on the generic class type. Essentially what I want to have is a generic class that sends data, that's it.
The issue is that I have multiple classes and I wanted to use a factory class in order to:
- Simplify the creation of HttpClient's objects.
- Avoid using the "new" keyword all the time because I can use the same instance of the
HttpClient<Some Object>
class throughout my application.
Please see code below:
Factory
public class SystemPreferencesFactory {
private static SystemPreferencesFactory factory = null;
private Map<String, PreferencesHTTPClient<? extends ISystemPreferences>> preferencesMap;
private SystemPreferencesFactory(){
this.preferencesMap = Map.of
(PreferencesHTTPType.DUT_PREFERENCES.getName(), new PreferencesHTTPClient<DutPreferencesDTO>(PreferencesHTTPType.DUT_PREFERENCES.getUrl()),
PreferencesHTTPType.MACHINE_PROPERTIES.getName(), new PreferencesHTTPClient<MachineProperties>(PreferencesHTTPType.MACHINE_PROPERTIES.getUrl())
);
}
public static PreferencesHTTPClient<? extends ISystemPreferences> getPreferencesHTTPClient(String type) {
if (factory == null) {
factory = new SystemPreferencesFactory();
}
return factory.preferencesMap.get(type);
}
}
HttpClient
public class PreferencesHTTPClient<T> extends HTTPClient {
private static final Logger logger = LoggerManager.getLogger();
private static String route = "";
public PreferencesHTTPClient(String route){
this.route = route;
}
public Future<HttpResponse> put(T dto) {
try {
System.err.println(dto.getClass());
HttpPut request = new HttpPut(URIAffix + route + "/" + SystemPreferences.systemPreferences().getSetupName());
request.addHeader("Authorization", authorizationPassword);
request.addHeader("Content-Type","application/json");
request.setEntity(new StringEntity(objectMapper.writeValueAsString(dto)));
return getClient().execute(request,
new FutureCallback<>() {
@Override
public void completed(final HttpResponse response) {
logger.info("update request succeeded");
}
@Override
public void failed(Exception ex) {
logger.error("update request failed: {}", ex.getMessage());
}
@Override
public void cancelled() {
logger.error("update request canceled");
}
});
} catch (JsonProcessingException | UnsupportedEncodingException e) {
logger.error("update request failed: {}", e.getMessage());
}
return CompletableFuture.completedFuture(null);
}
}
When I try to call it in main I get an compile error
SystemPreferencesFactory.getPreferencesHTTPClient(PreferencesHTTPType.DUT_PREFERENCES.getName())
.put(converterUtil.DutFromEntityToDTO(dp));
The compile error is:
Required type:
capture of ? extends ISystemPreferences
Provided:
DutPreferencesDTO
My DutPreferencesDTO class is declared as so:
public class DutPreferencesDTO implements ISystemPreferences
What is wrong with my syntax?