Added abstraction layer to DataSources

This commit is contained in:
Marvin Scham
2023-05-31 13:47:08 +02:00
parent 59109220e6
commit 2f1bd4407c
4 changed files with 125 additions and 60 deletions

View File

@@ -0,0 +1,99 @@
package de.rwu.easydrop.api.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import de.rwu.easydrop.api.dto.ProductDTO;
import de.rwu.easydrop.util.FormattingUtil;
/**
* Helper class for shared data and functions between data sources.
*
* @since 0.2.0
*/
public abstract class AbstractDataSource implements DataSource {
/**
* Returns the data origin for the current source.
*
* @return Data source name
*/
protected abstract String getDataOrigin();
/**
* Returns the data source's API key.
*
* @return Data source API key
*/
protected abstract String getApiKey();
/**
* Enriches a ProductDTO with API-gathered data.
*
* @param product Unfinished ProductDTO
* @param json Product data
* @return Finished ProductDTO
*/
public abstract ProductDTO buildProductDTO(ProductDTO product, String json);
/**
* Overridable standard implementation.
*/
@Override
public ProductDTO getProductDTOById(final String productIdentifier)
throws IllegalArgumentException {
StringBuilder response = new StringBuilder();
String dataOrigin = getDataOrigin();
String apiKey = getApiKey();
ProductDTO product = new ProductDTO(productIdentifier, dataOrigin);
try {
String urlReadyIdentifier = FormattingUtil.urlEncode(productIdentifier);
URL apiUrl = createApiUrl(urlReadyIdentifier);
HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Credential", apiKey);
int responseCode = connection.getResponseCode();
BufferedReader reader;
if (responseCode == HttpURLConnection.HTTP_OK) {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
throw new IllegalArgumentException(
"Nothing found: "
+ dataOrigin
+ " API responded with error code "
+ responseCode);
}
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
buildProductDTO(product, response.toString());
} catch (IOException e) {
throw new IllegalArgumentException(
"Couldn't fulfill "
+ dataOrigin
+ " API request");
}
return product;
}
/**
* Creates an URL object to connect to the API with.
*
* @param productIdentifier Product identifier
* @return URL object
* @throws MalformedURLException
*/
protected abstract URL createApiUrl(String productIdentifier) throws MalformedURLException;
}

View File

@@ -1,9 +1,5 @@
package de.rwu.easydrop.api.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
@@ -18,7 +14,7 @@ import de.rwu.easydrop.api.dto.ProductDTO;
*
* @since 0.1.0
*/
public final class AmazonProductDataSource implements DataSource {
public final class AmazonProductDataSource extends AbstractDataSource {
/**
* Name of this data source.
*/
@@ -52,47 +48,6 @@ public final class AmazonProductDataSource implements DataSource {
}
@Override
public ProductDTO getProductDTOById(final String productId) throws IllegalArgumentException {
StringBuilder response = new StringBuilder();
ProductDTO product = new ProductDTO(productId, DATA_ORIGIN);
try {
URL apiUrl = createApiUrl(productId);
HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Credential", apiKey);
int responseCode = connection.getResponseCode();
BufferedReader reader;
if (responseCode == HttpURLConnection.HTTP_OK) {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
throw new IllegalArgumentException(
"Nothing found: Amazon API responded with error code " + responseCode);
}
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
buildProductDTO(product, response.toString());
} catch (IOException e) {
throw new IllegalArgumentException("Couldn't fulfill Amazon API request");
}
return product;
}
/**
* Enriches a ProductDTO with API-gathered data.
*
* @param product Unfinished ProductDTO
* @param json Product data
* @return Finished ProductDTO
*/
public ProductDTO buildProductDTO(final ProductDTO product, final String json) {
String root = "$.featuredOffer.";
ReadContext ctx = JsonPath.parse(json);
@@ -112,6 +67,9 @@ public final class AmazonProductDataSource implements DataSource {
return product;
}
/**
* @param productId ASIN
*/
@Override
public URL createApiUrl(final String productId) throws MalformedURLException {
return new URL(baseUrl
@@ -122,4 +80,14 @@ public final class AmazonProductDataSource implements DataSource {
+ "&locale="
+ LOCALE);
}
@Override
protected String getDataOrigin() {
return DATA_ORIGIN;
}
@Override
protected String getApiKey() {
return this.apiKey;
}
}

View File

@@ -1,8 +1,5 @@
package de.rwu.easydrop.api.client;
import java.net.MalformedURLException;
import java.net.URL;
import de.rwu.easydrop.api.dto.ProductDTO;
/**
@@ -12,17 +9,8 @@ public interface DataSource {
/**
* Retrieves product info from the data source.
*
* @param productId ASIN
* @param productIdentifier Product identifier
* @return ProductDTO
*/
ProductDTO getProductDTOById(String productId);
/**
* Creates an URL object to connect to the API with.
*
* @param productId ASIN
* @return URL object
* @throws MalformedURLException
*/
URL createApiUrl(String productId) throws MalformedURLException;
ProductDTO getProductDTOById(String productIdentifier);
}

View File

@@ -27,4 +27,14 @@ public final class FormattingUtil {
public static String formatEuro(final double amount) {
return String.format(Locale.GERMAN, "%,.2f", amount) + "";
}
/**
* Makes a string URL ready. For now, only spaces are replaced.
*
* @param str
* @return URL-ready string
*/
public static String urlEncode(final String str) {
return str.replace(" ", "+");
}
}