Connected application components
This commit is contained in:
@@ -1,23 +1,8 @@
|
|||||||
package de.rwu.easydrop;
|
package de.rwu.easydrop;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.sqlite.SQLiteDataSource;
|
|
||||||
|
|
||||||
import de.rwu.easydrop.api.client.DataSourceFactory;
|
|
||||||
import de.rwu.easydrop.core.Core;
|
import de.rwu.easydrop.core.Core;
|
||||||
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
|
||||||
import de.rwu.easydrop.data.connector.SQLiteConnector;
|
|
||||||
import de.rwu.easydrop.model.ProductCatalogue;
|
|
||||||
import de.rwu.easydrop.service.retriever.CatalogueRetriever;
|
|
||||||
import de.rwu.easydrop.service.retriever.ProductRetriever;
|
|
||||||
import de.rwu.easydrop.service.writer.CatalogueWriter;
|
|
||||||
import de.rwu.easydrop.util.Config;
|
|
||||||
import de.rwu.easydrop.util.ProductsConfig;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kickoff point for the service.
|
* Kickoff point for the service.
|
||||||
@@ -25,11 +10,6 @@ import de.rwu.easydrop.util.ProductsConfig;
|
|||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
public final class Main {
|
public final class Main {
|
||||||
/**
|
|
||||||
* Logger for main process.
|
|
||||||
*/
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents unwanted instantiation.
|
* Prevents unwanted instantiation.
|
||||||
*/
|
*/
|
||||||
@@ -43,19 +23,6 @@ public final class Main {
|
|||||||
* @param args
|
* @param args
|
||||||
*/
|
*/
|
||||||
public static void main(final String[] args) throws ConfigurationException {
|
public static void main(final String[] args) throws ConfigurationException {
|
||||||
Config config = Config.getInstance();
|
Core.run();
|
||||||
ProductsConfig pConfig = ProductsConfig.getInstance();
|
|
||||||
DataSourceFactory dataSourceFactory = new DataSourceFactory(config);
|
|
||||||
ProductRetriever retriever = new ProductRetriever(dataSourceFactory);
|
|
||||||
CatalogueRetriever catRetriever = new CatalogueRetriever(pConfig, retriever);
|
|
||||||
AbstractProductPersistence db = new SQLiteConnector(new SQLiteDataSource());
|
|
||||||
CatalogueWriter catWriter = new CatalogueWriter(db);
|
|
||||||
|
|
||||||
catRetriever.loadCatalogues();
|
|
||||||
List<ProductCatalogue> pCats = catRetriever.getProductCatalogues();
|
|
||||||
catWriter.writeCatalogues(pCats);
|
|
||||||
|
|
||||||
Core core = new Core();
|
|
||||||
core.runCore(pCats);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.jayway.jsonpath.ReadContext;
|
|||||||
|
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
import de.rwu.easydrop.model.Webshop;
|
import de.rwu.easydrop.model.Webshop;
|
||||||
|
import de.rwu.easydrop.util.Timestamp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to an Amazon data source.
|
* Interface to an Amazon data source.
|
||||||
@@ -61,6 +62,7 @@ public final class AmazonProductDataSource extends AbstractDataSource {
|
|||||||
product.setDeliveryPrice(
|
product.setDeliveryPrice(
|
||||||
ctx.read(root + "shippingOptions[0].shippingCost.value.amount", double.class));
|
ctx.read(root + "shippingOptions[0].shippingCost.value.amount", double.class));
|
||||||
product.setMerchant(ctx.read(root + "merchant.name", String.class));
|
product.setMerchant(ctx.read(root + "merchant.name", String.class));
|
||||||
|
product.setLastUpdate(Timestamp.now());
|
||||||
} catch (PathNotFoundException e) {
|
} catch (PathNotFoundException e) {
|
||||||
// Pass, allow incomplete ProductDTO to pass for later validation
|
// Pass, allow incomplete ProductDTO to pass for later validation
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package de.rwu.easydrop.api.client;
|
|||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
|
||||||
import de.rwu.easydrop.exception.PersistenceException;
|
|
||||||
import de.rwu.easydrop.util.Config;
|
import de.rwu.easydrop.util.Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,17 +15,6 @@ public class DataSourceFactory {
|
|||||||
* The data source config.
|
* The data source config.
|
||||||
*/
|
*/
|
||||||
private Config config;
|
private Config config;
|
||||||
/**
|
|
||||||
* Persistence interface.
|
|
||||||
*/
|
|
||||||
private AbstractProductPersistence persistence = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param newPersistence the persistence to set
|
|
||||||
*/
|
|
||||||
public void setPersistence(final AbstractProductPersistence newPersistence) {
|
|
||||||
this.persistence = newPersistence;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param newConfig the config to set
|
* @param newConfig the config to set
|
||||||
@@ -65,17 +52,4 @@ public class DataSourceFactory {
|
|||||||
String apiKey = config.getProperty("EBAY_API_KEY");
|
String apiKey = config.getProperty("EBAY_API_KEY");
|
||||||
return new EbayItemDataSource(apiUrl, apiKey);
|
return new EbayItemDataSource(apiUrl, apiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a persistence data source.
|
|
||||||
*
|
|
||||||
* @return ProductPersistenceInterface
|
|
||||||
*/
|
|
||||||
public AbstractProductPersistence createProductPersistenceDataSource() {
|
|
||||||
if (persistence == null) {
|
|
||||||
throw new PersistenceException("Persistence is not set");
|
|
||||||
}
|
|
||||||
|
|
||||||
return persistence;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.jayway.jsonpath.ReadContext;
|
|||||||
|
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
import de.rwu.easydrop.model.Webshop;
|
import de.rwu.easydrop.model.Webshop;
|
||||||
|
import de.rwu.easydrop.util.Timestamp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to an eBay data source.
|
* Interface to an eBay data source.
|
||||||
@@ -70,6 +71,7 @@ public final class EbayItemDataSource extends AbstractDataSource {
|
|||||||
product.setDeliveryPrice(
|
product.setDeliveryPrice(
|
||||||
ctx.read(root + "shippingOptions[0].shippingCost.value", double.class));
|
ctx.read(root + "shippingOptions[0].shippingCost.value", double.class));
|
||||||
product.setMerchant(ctx.read(root + "seller.username", String.class));
|
product.setMerchant(ctx.read(root + "seller.username", String.class));
|
||||||
|
product.setLastUpdate(Timestamp.now());
|
||||||
} catch (PathNotFoundException e) {
|
} catch (PathNotFoundException e) {
|
||||||
// Pass, allow incomplete ProductDTO to pass for later validation
|
// Pass, allow incomplete ProductDTO to pass for later validation
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,31 @@
|
|||||||
package de.rwu.easydrop.api.dto;
|
package de.rwu.easydrop.api.dto;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import de.rwu.easydrop.model.Product;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Offer data transfer object
|
* Offer data transfer object.
|
||||||
|
*
|
||||||
|
* @since 0.3.0
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class OfferDTO {
|
public class OfferDTO {
|
||||||
/**
|
/**
|
||||||
* Platform internal offer identifier.
|
* ID of the offer, built from identifiers of the source platforms.
|
||||||
*/
|
*/
|
||||||
private String offerId;
|
private String offerId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The product that our software buys.
|
* The product that our software buys.
|
||||||
*/
|
*/
|
||||||
private Product sourceProduct;
|
private ProductDTO sourceProduct;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The product that our software sells.
|
* The product that our software sells.
|
||||||
*/
|
*/
|
||||||
private Product saleProduct;
|
private ProductDTO targetProduct;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date of the creation of the offer
|
* Date of last update of the offer.
|
||||||
* NOTE: Use Timestamp?
|
|
||||||
* https://docs.oracle.com/javase/8/docs/api/java/sql/Timestamp.html
|
|
||||||
*/
|
*/
|
||||||
private Date creationDate;
|
private String lastUpdate;
|
||||||
|
|
||||||
/**
|
|
||||||
* Date of last update of the offer on the destination website (API).
|
|
||||||
*/
|
|
||||||
private Date upDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Date of last check if offer is still valid.
|
|
||||||
*/
|
|
||||||
private Date checkDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates OfferDTO instance.
|
|
||||||
*
|
|
||||||
* @param newOfferId Internal Offer identifier
|
|
||||||
*/
|
|
||||||
public OfferDTO(final String newOfferId) {
|
|
||||||
this.offerId = newOfferId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ public class ProductDTO {
|
|||||||
*/
|
*/
|
||||||
private boolean available;
|
private boolean available;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Last update from API.
|
||||||
|
*/
|
||||||
|
private String lastUpdate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates ProductDTO instance.
|
* Creates ProductDTO instance.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -4,42 +4,74 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.sqlite.SQLiteDataSource;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.client.DataSourceFactory;
|
||||||
|
import de.rwu.easydrop.data.connector.OfferPersistenceInterface;
|
||||||
|
import de.rwu.easydrop.data.connector.ProductPersistenceInterface;
|
||||||
|
import de.rwu.easydrop.data.connector.SQLiteConnector;
|
||||||
import de.rwu.easydrop.model.Offer;
|
import de.rwu.easydrop.model.Offer;
|
||||||
import de.rwu.easydrop.model.ProductCatalogue;
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
|
import de.rwu.easydrop.service.processing.OfferIdentifier;
|
||||||
|
import de.rwu.easydrop.service.processing.OfferProvisioner;
|
||||||
|
import de.rwu.easydrop.service.retriever.CatalogueRetriever;
|
||||||
|
import de.rwu.easydrop.service.retriever.ProductRetriever;
|
||||||
|
import de.rwu.easydrop.service.writer.CatalogueWriter;
|
||||||
|
import de.rwu.easydrop.util.Config;
|
||||||
|
import de.rwu.easydrop.util.ProductsConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The application core.
|
* The application core.
|
||||||
*
|
*
|
||||||
* @since 0.3.0
|
* @since 0.3.0
|
||||||
*/
|
*/
|
||||||
public class Core {
|
public final class Core {
|
||||||
/**
|
/**
|
||||||
* Offer identifier.
|
* Logging instance.
|
||||||
*/
|
*/
|
||||||
private OfferIdentifier ident;
|
private static final Logger LOGGER = LoggerFactory.getLogger(Core.class);
|
||||||
/**
|
|
||||||
* Offer provisioner.
|
|
||||||
*/
|
|
||||||
private OfferProvisioner provis;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Hidden Constructor.
|
||||||
*
|
|
||||||
* @throws ConfigurationException
|
|
||||||
*/
|
*/
|
||||||
public Core() throws ConfigurationException {
|
private Core() {
|
||||||
this.ident = new OfferIdentifier();
|
// Hidden constructor
|
||||||
this.provis = new OfferProvisioner();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the core.
|
* Runs the core.
|
||||||
*
|
*
|
||||||
* @param pCats
|
* @throws ConfigurationException
|
||||||
*/
|
*/
|
||||||
public void runCore(final List<ProductCatalogue> pCats) {
|
public static void run() throws ConfigurationException {
|
||||||
|
LOGGER.info("Loading config...");
|
||||||
|
Config config = Config.getInstance();
|
||||||
|
ProductsConfig pConfig = ProductsConfig.getInstance();
|
||||||
|
|
||||||
|
LOGGER.info("Preparing...");
|
||||||
|
DataSourceFactory dataSourceFactory = new DataSourceFactory(config);
|
||||||
|
ProductPersistenceInterface pdb = new SQLiteConnector(new SQLiteDataSource());
|
||||||
|
OfferPersistenceInterface odb = new SQLiteConnector(new SQLiteDataSource());
|
||||||
|
ProductRetriever retriever = new ProductRetriever(dataSourceFactory, pdb);
|
||||||
|
CatalogueRetriever catRetriever = new CatalogueRetriever(pConfig, retriever);
|
||||||
|
CatalogueWriter catWriter = new CatalogueWriter(pdb);
|
||||||
|
|
||||||
|
LOGGER.info("Loading catalogues");
|
||||||
|
catRetriever.loadCatalogues();
|
||||||
|
List<ProductCatalogue> pCats = catRetriever.getProductCatalogues();
|
||||||
|
catWriter.writeCatalogues(pCats);
|
||||||
|
|
||||||
|
LOGGER.info("Creating offers");
|
||||||
|
OfferIdentifier ident = new OfferIdentifier();
|
||||||
List<Offer> identifiedOffers = ident.runIdentifier(pCats);
|
List<Offer> identifiedOffers = ident.runIdentifier(pCats);
|
||||||
|
OfferProvisioner provis = new OfferProvisioner(odb);
|
||||||
provis.runProvisioner(identifiedOffers);
|
provis.runProvisioner(identifiedOffers);
|
||||||
|
|
||||||
|
// LOGGER.info("Creating transactions");
|
||||||
|
// TODO: Transactions
|
||||||
|
|
||||||
|
LOGGER.info("Done!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
package de.rwu.easydrop.core;
|
|
||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import de.rwu.easydrop.model.Offer;
|
|
||||||
import de.rwu.easydrop.model.ProductCatalogue;
|
|
||||||
import de.rwu.easydrop.model.ProductPair;
|
|
||||||
import de.rwu.easydrop.service.retriever.OfferRetriever;
|
|
||||||
import de.rwu.easydrop.service.processing.OrderManager;
|
|
||||||
import de.rwu.easydrop.exception.InvalidCatalogueException;
|
|
||||||
|
|
||||||
public class OfferIdentifier {
|
|
||||||
/**
|
|
||||||
* Logger for main process.
|
|
||||||
*/
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(OfferIdentifier.class);
|
|
||||||
/**
|
|
||||||
* OfferRetriever gets the offer from persistence.
|
|
||||||
*/
|
|
||||||
private OfferRetriever offerRetriever;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OfferIdentifier identifies offers that are
|
|
||||||
* feasible to place on a target platform based on
|
|
||||||
* their margin.
|
|
||||||
*
|
|
||||||
* @throws ConfigurationException
|
|
||||||
*/
|
|
||||||
public OfferIdentifier() throws ConfigurationException {
|
|
||||||
this.offerRetriever = new OfferRetriever();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* runIdentifier calls the price function that decides
|
|
||||||
* if it is feasible to dropship products and if so,
|
|
||||||
* at which margin.
|
|
||||||
*
|
|
||||||
* @param pCats
|
|
||||||
* @return newOffers
|
|
||||||
*/
|
|
||||||
public List<Offer> runIdentifier(final List<ProductCatalogue> pCats) {
|
|
||||||
List<Offer> identifiedOffers = new ArrayList<>();
|
|
||||||
for (ProductCatalogue pCat : pCats) {
|
|
||||||
try {
|
|
||||||
// Call price finder for all catalogue
|
|
||||||
ProductPair pair = OrderManager.getHighestMarginProducts(pCat);
|
|
||||||
Offer possibleOffer = new Offer();
|
|
||||||
possibleOffer.setCheckDate(new Date());
|
|
||||||
possibleOffer.setSourceProduct(pair.getProduct1());
|
|
||||||
possibleOffer.setSaleProduct(pair.getProduct2());
|
|
||||||
identifiedOffers.add(possibleOffer);
|
|
||||||
LOGGER.info(
|
|
||||||
"Identified offer "
|
|
||||||
+
|
|
||||||
pair.getProduct1().getProductId()
|
|
||||||
+
|
|
||||||
" -> "
|
|
||||||
+
|
|
||||||
pair.getProduct2().getProductId());
|
|
||||||
// Following fields will be set if offer confirmed
|
|
||||||
// creationDate, offerId
|
|
||||||
// Following fields will be set if offer needs update
|
|
||||||
// upDate
|
|
||||||
} catch (InvalidCatalogueException e) {
|
|
||||||
// if no margin, getHighestMarginProducts will throw
|
|
||||||
System.out.print("product has no margin");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<Offer> newOffers = new ArrayList<>();
|
|
||||||
for (Offer identifiedOffer : identifiedOffers) {
|
|
||||||
boolean isNew = true;
|
|
||||||
if (isNew) {
|
|
||||||
newOffers.add(identifiedOffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newOffers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package de.rwu.easydrop.core;
|
|
||||||
|
|
||||||
import de.rwu.easydrop.model.Offer;
|
|
||||||
import de.rwu.easydrop.model.Product;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
public class OfferReviewer {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check all Offers and compare them with the API.
|
|
||||||
* @return list of all items that need to be changed
|
|
||||||
*/
|
|
||||||
public List<Offer> checkOffer(/*OfferReader/retriever for database? */) {
|
|
||||||
|
|
||||||
Connection connection = null;
|
|
||||||
Statement statement = null;
|
|
||||||
ResultSet resultSet = null;
|
|
||||||
List<Offer> changedOffers = new ArrayList<>();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Establish the database connection
|
|
||||||
connection = DriverManager.getConnection("jdbc:sqlite:persistence.db");
|
|
||||||
|
|
||||||
// Create a SQL statement
|
|
||||||
statement = connection.createStatement();
|
|
||||||
|
|
||||||
// Execute the query to retrieve the entries
|
|
||||||
String query = "SELECT sourceProduct, saleProduct, creationDate, upDate, "
|
|
||||||
+ "checkDate, offerId FROM table";
|
|
||||||
resultSet = statement.executeQuery(query);
|
|
||||||
|
|
||||||
// Process the retrieved entries
|
|
||||||
while (resultSet.next()) {
|
|
||||||
Product sourceProduct = (Product) resultSet.getObject("sourceProduct");
|
|
||||||
Product saleProduct = (Product) resultSet.getObject("saleProduct");
|
|
||||||
java.sql.Date creationDate = resultSet.getDate("creationDate");
|
|
||||||
Date updateDate = resultSet.getDate("upDate");
|
|
||||||
Date checkDate = resultSet.getDate("checkDate");
|
|
||||||
String offerId = resultSet.getString("offerId");
|
|
||||||
|
|
||||||
// Call the API to get the current price
|
|
||||||
double apiPrice = getPriceFromAPI(sourceProduct);
|
|
||||||
|
|
||||||
// Compare the prices
|
|
||||||
if (saleProduct.getCurrentPrice() != apiPrice) {
|
|
||||||
// Price has changed, create a Product object and add it to the changedProducts list
|
|
||||||
Offer offer = new Offer();
|
|
||||||
changedOffers.add(offer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (resultSet != null) {
|
|
||||||
resultSet.close();
|
|
||||||
}
|
|
||||||
if (statement != null) {
|
|
||||||
statement.close();
|
|
||||||
}
|
|
||||||
if (connection != null) {
|
|
||||||
connection.close();
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ArrayList<Offer>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
package de.rwu.easydrop.core;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.List;
|
|
||||||
import de.rwu.easydrop.model.Offer;
|
|
||||||
import de.rwu.easydrop.model.Product;
|
|
||||||
|
|
||||||
|
|
||||||
public class OfferUpdater {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* a.
|
|
||||||
*/
|
|
||||||
public OfferUpdater() {
|
|
||||||
|
|
||||||
OfferReviewer offerReviewer = new OfferReviewer();
|
|
||||||
List<Offer> changedOffers = offerReviewer.checkOffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A.
|
|
||||||
* @param offersToUpdate
|
|
||||||
*/
|
|
||||||
public void runUpdater(final List<Offer> offersToUpdate) {
|
|
||||||
Connection connection = null;
|
|
||||||
PreparedStatement deleteStatement = null;
|
|
||||||
PreparedStatement insertStatement = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Establish the database connection
|
|
||||||
connection = DriverManager.getConnection("jdbc:sqlite:persistence.db");
|
|
||||||
|
|
||||||
// Disable auto-commit to perform a transaction
|
|
||||||
connection.setAutoCommit(false);
|
|
||||||
|
|
||||||
// Prepare the DELETE statement to remove the existing entries
|
|
||||||
String deleteQuery = "DELETE FROM your_table WHERE product_id = ?";
|
|
||||||
deleteStatement = connection.prepareStatement(deleteQuery);
|
|
||||||
|
|
||||||
// Prepare the INSERT statement to add the new entries
|
|
||||||
String insertQuery = "INSERT INTO your_table (product_id, product_name, price)"
|
|
||||||
+ "VALUES (?, ?, ?)";
|
|
||||||
insertStatement = connection.prepareStatement(insertQuery);
|
|
||||||
|
|
||||||
// Retrieve the existing entries from the database
|
|
||||||
List<Product> existingProducts = retrieveExistingProducts(connection);
|
|
||||||
|
|
||||||
// Delete the existing entries that are not present in the changedProducts list
|
|
||||||
for (Product existingProduct : existingProducts) {
|
|
||||||
if (!changedOffers.(existingProduct)) {
|
|
||||||
deleteStatement.setString(1, existingProduct.getProductId());
|
|
||||||
deleteStatement.executeUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert the new entries or update the existing entries
|
|
||||||
for (Product changedOffers : offersToUpdate) {
|
|
||||||
if (existingProducts.contains(changedOffers)) {
|
|
||||||
// Update the existing entry with the new data
|
|
||||||
// You need to modify the update query and statement based on your requirements
|
|
||||||
// Here's an example of updating the price of an existing entry
|
|
||||||
String updateQuery = "UPDATE table SET currentPrice = ? WHERE offerId = ?";
|
|
||||||
PreparedStatement updateStatement = connection.prepareStatement(updateQuery);
|
|
||||||
updateStatement.setDouble(1, changedOffers.getCurrentPrice());
|
|
||||||
updateStatement.setString(2, changedOffers.getProductId());
|
|
||||||
updateStatement.executeUpdate();
|
|
||||||
updateStatement.close();
|
|
||||||
} else {
|
|
||||||
// Insert the new entry
|
|
||||||
insertStatement.setString(1, changedOffers.getProductId());
|
|
||||||
insertStatement.setString(2, changedOffers.getMerchant());
|
|
||||||
insertStatement.setDouble(3, changedOffers.getCurrentPrice());
|
|
||||||
insertStatement.executeUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit the transaction
|
|
||||||
connection.commit();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
// Rollback the transaction in case of an exception
|
|
||||||
if (connection != null) {
|
|
||||||
try {
|
|
||||||
connection.rollback();
|
|
||||||
} catch (SQLException rollbackException) {
|
|
||||||
rollbackException.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
// Close the resources (deleteStatement, insertStatement, connection) in a finally block
|
|
||||||
try {
|
|
||||||
if (deleteStatement != null) {
|
|
||||||
deleteStatement.close();
|
|
||||||
}
|
|
||||||
if (insertStatement != null) {
|
|
||||||
insertStatement.close();
|
|
||||||
}
|
|
||||||
if (connection != null) {
|
|
||||||
connection.close();
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package de.rwu.easydrop.data.connector;
|
|
||||||
|
|
||||||
import de.rwu.easydrop.api.client.AbstractDataSource;
|
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows connecting to a persistent product data store.
|
|
||||||
*
|
|
||||||
* @since 0.2.0
|
|
||||||
*/
|
|
||||||
public abstract class AbstractProductPersistence extends AbstractDataSource {
|
|
||||||
/**
|
|
||||||
* Data origin.
|
|
||||||
*/
|
|
||||||
public static final String DATA_ORIGIN = "Persistence";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a ProductDTO to persistence.
|
|
||||||
*
|
|
||||||
* @param dto
|
|
||||||
*/
|
|
||||||
public abstract void saveProduct(ProductDTO dto);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a ProductDTO from persistence.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public abstract ProductDTO getProductDTOById(String productId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes all data from persistence.
|
|
||||||
*/
|
|
||||||
public abstract void clearData();
|
|
||||||
}
|
|
||||||
@@ -2,13 +2,13 @@ package de.rwu.easydrop.data.connector;
|
|||||||
|
|
||||||
import de.rwu.easydrop.api.dto.OfferDTO;
|
import de.rwu.easydrop.api.dto.OfferDTO;
|
||||||
|
|
||||||
public abstract class AbstractOfferPersistence {
|
public interface OfferPersistenceInterface {
|
||||||
/**
|
/**
|
||||||
* Writes a ProductDTO to persistence.
|
* Writes a ProductDTO to persistence.
|
||||||
*
|
*
|
||||||
* @param dto
|
* @param dto
|
||||||
*/
|
*/
|
||||||
public abstract void saveOffer(OfferDTO dto);
|
void writeOffer(OfferDTO dto);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a OfferDTO from persistence.
|
* Gets a OfferDTO from persistence.
|
||||||
@@ -16,10 +16,10 @@ public abstract class AbstractOfferPersistence {
|
|||||||
* @param offerId
|
* @param offerId
|
||||||
* @return Offer data transfer object
|
* @return Offer data transfer object
|
||||||
*/
|
*/
|
||||||
public abstract OfferDTO getOfferDTOById(String offerId);
|
OfferDTO getOfferDTOById(String offerId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all data from persistence.
|
* Deletes all data from persistence.
|
||||||
*/
|
*/
|
||||||
public abstract void clearData();
|
void clearData();
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package de.rwu.easydrop.data.connector;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows connecting to a persistent product data store.
|
||||||
|
*
|
||||||
|
* @since 0.2.0
|
||||||
|
*/
|
||||||
|
public interface ProductPersistenceInterface {
|
||||||
|
/**
|
||||||
|
* Writes a ProductDTO to persistence.
|
||||||
|
*
|
||||||
|
* @param dto
|
||||||
|
*/
|
||||||
|
void writeProduct(ProductDTO dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a ProductDTO from persistence.
|
||||||
|
*
|
||||||
|
* @param productId Product identifier
|
||||||
|
* @return Product data transfer object
|
||||||
|
*/
|
||||||
|
ProductDTO getProductDTOById(String productId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all data from persistence.
|
||||||
|
*/
|
||||||
|
void clearData();
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package de.rwu.easydrop.data.connector;
|
package de.rwu.easydrop.data.connector;
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@@ -9,6 +8,7 @@ import java.sql.Statement;
|
|||||||
|
|
||||||
import org.sqlite.SQLiteDataSource;
|
import org.sqlite.SQLiteDataSource;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.OfferDTO;
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
import de.rwu.easydrop.exception.PersistenceException;
|
import de.rwu.easydrop.exception.PersistenceException;
|
||||||
import de.rwu.easydrop.model.Webshop;
|
import de.rwu.easydrop.model.Webshop;
|
||||||
@@ -18,7 +18,8 @@ import de.rwu.easydrop.model.Webshop;
|
|||||||
*
|
*
|
||||||
* @since 0.2.0
|
* @since 0.2.0
|
||||||
*/
|
*/
|
||||||
public final class SQLiteConnector extends AbstractProductPersistence {
|
public final class SQLiteConnector implements
|
||||||
|
ProductPersistenceInterface, OfferPersistenceInterface {
|
||||||
/**
|
/**
|
||||||
* SQLite Database.
|
* SQLite Database.
|
||||||
*/
|
*/
|
||||||
@@ -53,8 +54,8 @@ public final class SQLiteConnector extends AbstractProductPersistence {
|
|||||||
Connection connection = db.getConnection();
|
Connection connection = db.getConnection();
|
||||||
|
|
||||||
// Execute SQL statements to create tables
|
// Execute SQL statements to create tables
|
||||||
Statement statement = connection.createStatement();
|
Statement createProducts = connection.createStatement();
|
||||||
statement.execute(
|
createProducts.execute(
|
||||||
"CREATE TABLE IF NOT EXISTS products ("
|
"CREATE TABLE IF NOT EXISTS products ("
|
||||||
+ "dataOrigin TEXT, "
|
+ "dataOrigin TEXT, "
|
||||||
+ "productId TEXT, "
|
+ "productId TEXT, "
|
||||||
@@ -62,12 +63,29 @@ public final class SQLiteConnector extends AbstractProductPersistence {
|
|||||||
+ "merchant TEXT, "
|
+ "merchant TEXT, "
|
||||||
+ "deliveryPrice REAL, "
|
+ "deliveryPrice REAL, "
|
||||||
+ "available INT, "
|
+ "available INT, "
|
||||||
+ "lastupdate TEXT, "
|
+ "lastUpdate TEXT, "
|
||||||
+ "UNIQUE(productId, dataOrigin) ON CONFLICT REPLACE"
|
+ "UNIQUE(productId, dataOrigin) ON CONFLICT REPLACE"
|
||||||
+ ")");
|
+ ")");
|
||||||
|
|
||||||
// Close the statement and connection
|
// Close the statement
|
||||||
statement.close();
|
createProducts.close();
|
||||||
|
|
||||||
|
Statement createOffers = connection.createStatement();
|
||||||
|
createOffers.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS offers ("
|
||||||
|
+ "offerId TEXT, "
|
||||||
|
+ "sourceWebshop TEXT, "
|
||||||
|
+ "sourceId TEXT,"
|
||||||
|
+ "sourcePrice REAL, "
|
||||||
|
+ "targetWebshop TEXT, "
|
||||||
|
+ "targetId TEXT, "
|
||||||
|
+ "targetPrice REAL, "
|
||||||
|
+ "lastUpdate TEXT, "
|
||||||
|
+ "UNIQUE(offerId) ON CONFLICT REPLACE"
|
||||||
|
+ ")");
|
||||||
|
createOffers.close();
|
||||||
|
|
||||||
|
// Close the connection
|
||||||
connection.close();
|
connection.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PersistenceException("Something went wrong while initializing SQLite DB", e);
|
throw new PersistenceException("Something went wrong while initializing SQLite DB", e);
|
||||||
@@ -79,12 +97,12 @@ public final class SQLiteConnector extends AbstractProductPersistence {
|
|||||||
*
|
*
|
||||||
* @param dto
|
* @param dto
|
||||||
*/
|
*/
|
||||||
public void saveProduct(final ProductDTO dto) {
|
public void writeProduct(final ProductDTO dto) {
|
||||||
String query = "INSERT INTO products ("
|
String query = "INSERT INTO products ("
|
||||||
+ "dataOrigin, productId, currentPrice, merchant, "
|
+ "dataOrigin, productId, currentPrice, merchant, "
|
||||||
+ "deliveryPrice, available, lastupdate"
|
+ "deliveryPrice, available, lastUpdate"
|
||||||
+ ") VALUES ("
|
+ ") VALUES ("
|
||||||
+ "?, ?, ?, ?, ?, ?, datetime('now', 'localtime')"
|
+ "?, ?, ?, ?, ?, ?, ?"
|
||||||
+ ")";
|
+ ")";
|
||||||
|
|
||||||
try (Connection connection = db.getConnection();
|
try (Connection connection = db.getConnection();
|
||||||
@@ -97,6 +115,7 @@ public final class SQLiteConnector extends AbstractProductPersistence {
|
|||||||
statement.setString(++index, dto.getMerchant());
|
statement.setString(++index, dto.getMerchant());
|
||||||
statement.setDouble(++index, dto.getDeliveryPrice());
|
statement.setDouble(++index, dto.getDeliveryPrice());
|
||||||
statement.setBoolean(++index, dto.isAvailable());
|
statement.setBoolean(++index, dto.isAvailable());
|
||||||
|
statement.setString(++index, dto.getLastUpdate());
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -138,7 +157,7 @@ public final class SQLiteConnector extends AbstractProductPersistence {
|
|||||||
public void clearData() {
|
public void clearData() {
|
||||||
try (Connection connection = db.getConnection();
|
try (Connection connection = db.getConnection();
|
||||||
Statement statement = connection.createStatement()) {
|
Statement statement = connection.createStatement()) {
|
||||||
String query = "DELETE FROM products";
|
String query = "DELETE FROM products; DELETE FROM offers;";
|
||||||
statement.executeUpdate(query);
|
statement.executeUpdate(query);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PersistenceException("Something went wrong while clearing the database", e);
|
throw new PersistenceException("Something went wrong while clearing the database", e);
|
||||||
@@ -146,26 +165,68 @@ public final class SQLiteConnector extends AbstractProductPersistence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Webshop getDataOrigin() {
|
public void writeOffer(final OfferDTO dto) {
|
||||||
throw new UnsupportedOperationException(
|
String query = "INSERT INTO offers ("
|
||||||
this.getClass().getName() + " doesn't support getDataOrigin");
|
+ "offerId, "
|
||||||
|
+ "sourceWebshop, sourceId, sourcePrice, "
|
||||||
|
+ "targetWebshop, targetId, targetPrice, "
|
||||||
|
+ "lastUpdate"
|
||||||
|
+ ") VALUES ("
|
||||||
|
+ "?, ?, ?, ?, ?, ?, ?, ?"
|
||||||
|
+ ")";
|
||||||
|
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
|
int index = 0;
|
||||||
|
ProductDTO sourceProduct = dto.getSourceProduct();
|
||||||
|
ProductDTO targetProduct = dto.getTargetProduct();
|
||||||
|
|
||||||
|
statement.setString(++index, dto.getOfferId());
|
||||||
|
statement.setString(++index, sourceProduct.getProductId());
|
||||||
|
statement.setString(++index, sourceProduct.getDataOrigin().toString());
|
||||||
|
statement.setDouble(++index, sourceProduct.getCurrentPrice());
|
||||||
|
statement.setString(++index, targetProduct.getProductId());
|
||||||
|
statement.setString(++index, targetProduct.getDataOrigin().toString());
|
||||||
|
statement.setDouble(++index, targetProduct.getCurrentPrice());
|
||||||
|
statement.setString(++index, dto.getLastUpdate());
|
||||||
|
|
||||||
|
statement.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException("Something went wrong while saving to SQLite", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getApiKey() {
|
public OfferDTO getOfferDTOById(final String offerId) {
|
||||||
throw new UnsupportedOperationException(
|
String query = "SELECT * FROM offers WHERE offerId = ?";
|
||||||
this.getClass().getName() + " doesn't support getApiKey");
|
OfferDTO dto = null;
|
||||||
|
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
|
|
||||||
|
statement.setString(1, offerId);
|
||||||
|
|
||||||
|
try (ResultSet resultSet = statement.executeQuery()) {
|
||||||
|
if (resultSet.next()) {
|
||||||
|
dto = new OfferDTO();
|
||||||
|
ProductDTO srcProduct = new ProductDTO(
|
||||||
|
resultSet.getString("sourceId"),
|
||||||
|
Webshop.fromString(resultSet.getString("sourceWebshop")));
|
||||||
|
srcProduct.setCurrentPrice(resultSet.getDouble("sourcePrice"));
|
||||||
|
ProductDTO targetProduct = new ProductDTO(
|
||||||
|
resultSet.getString("targetId"),
|
||||||
|
Webshop.fromString(resultSet.getString("targetWebshop")));
|
||||||
|
srcProduct.setCurrentPrice(resultSet.getDouble("targetPrice"));
|
||||||
|
dto.setOfferId(resultSet.getString("offerId"));
|
||||||
|
dto.setSourceProduct(srcProduct);
|
||||||
|
dto.setTargetProduct(targetProduct);
|
||||||
|
dto.setLastUpdate(resultSet.getString("lastUpdate"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException("Something went wrong while reading from SQLite", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
return dto;
|
||||||
protected ProductDTO buildProductDTO(final ProductDTO product, final String json) {
|
|
||||||
throw new UnsupportedOperationException(
|
|
||||||
this.getClass().getName() + " doesn't support buildProductDTO");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected URL createApiUrl(final String productIdentifier) {
|
|
||||||
throw new UnsupportedOperationException(
|
|
||||||
this.getClass().getName() + " doesn't support createApiUrl");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package de.rwu.easydrop.exception;
|
||||||
|
|
||||||
|
public class InvalidOfferException extends RuntimeException {
|
||||||
|
/**
|
||||||
|
* Throws an exception that signifies the data of an Offer are invalid.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public InvalidOfferException(final String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception that signifies the data of an Offer are invalid.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* @param cause
|
||||||
|
*/
|
||||||
|
public InvalidOfferException(final String message, final Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
package de.rwu.easydrop.model;
|
package de.rwu.easydrop.model;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -10,9 +7,13 @@ import lombok.Data;
|
|||||||
*
|
*
|
||||||
* @since 0.3.0
|
* @since 0.3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class Offer {
|
public class Offer {
|
||||||
|
/**
|
||||||
|
* ID of the offer, built from identifiers of the source platforms.
|
||||||
|
*/
|
||||||
|
private String offerId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The product that our software buys.
|
* The product that our software buys.
|
||||||
*/
|
*/
|
||||||
@@ -21,27 +22,10 @@ public class Offer {
|
|||||||
/**
|
/**
|
||||||
* The product that our software sells.
|
* The product that our software sells.
|
||||||
*/
|
*/
|
||||||
private Product saleProduct;
|
private Product targetProduct;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date of the creation of the offer.
|
* Date of last update of the offer.
|
||||||
* NOTE: Use Timestamp? https://docs.oracle.com/javase/8/docs/api/java/sql/Timestamp.html
|
|
||||||
*/
|
*/
|
||||||
private Date creationDate;
|
private String lastUpdate;
|
||||||
|
|
||||||
/**
|
|
||||||
* Date of last update of the offer on the destination website (API).
|
|
||||||
*/
|
|
||||||
private Date upDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Date of last check if offer is still valid.
|
|
||||||
*/
|
|
||||||
private Date checkDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ID of the offer.
|
|
||||||
*/
|
|
||||||
private String offerId;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ public class Product {
|
|||||||
*/
|
*/
|
||||||
private boolean available;
|
private boolean available;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Last update from API.
|
||||||
|
*/
|
||||||
|
private String lastUpdate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final String toString() {
|
public final String toString() {
|
||||||
return "Product: ["
|
return "Product: ["
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class ProductCatalogue {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("Product Catalogue: ").append(productName).append("\n");
|
sb.append("Catalogue Name: ").append(productName).append("\n");
|
||||||
sb.append("Description: ").append(description).append("\n");
|
sb.append("Description: ").append(description).append("\n");
|
||||||
sb.append("Products:\n");
|
sb.append("Products:\n");
|
||||||
for (Product product : products) {
|
for (Product product : products) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package de.rwu.easydrop.service.mapping;
|
package de.rwu.easydrop.service.mapping;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.dto.OfferDTO;
|
import de.rwu.easydrop.api.dto.OfferDTO;
|
||||||
|
|
||||||
import de.rwu.easydrop.model.Offer;
|
import de.rwu.easydrop.model.Offer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,6 +30,10 @@ public final class OfferMapper {
|
|||||||
*/
|
*/
|
||||||
public static Offer mapOfferFromDTO(final OfferDTO dto) {
|
public static Offer mapOfferFromDTO(final OfferDTO dto) {
|
||||||
Offer offer = new Offer();
|
Offer offer = new Offer();
|
||||||
|
offer.setOfferId(dto.getOfferId());
|
||||||
|
offer.setSourceProduct(ProductMapper.mapProductFromDTO(dto.getSourceProduct()));
|
||||||
|
offer.setTargetProduct(ProductMapper.mapProductFromDTO(dto.getTargetProduct()));
|
||||||
|
offer.setLastUpdate(dto.getLastUpdate());
|
||||||
|
|
||||||
return offer;
|
return offer;
|
||||||
}
|
}
|
||||||
@@ -42,7 +45,11 @@ public final class OfferMapper {
|
|||||||
* @return OfferDTO
|
* @return OfferDTO
|
||||||
*/
|
*/
|
||||||
public static OfferDTO mapOfferToDTO(final Offer offer) {
|
public static OfferDTO mapOfferToDTO(final Offer offer) {
|
||||||
OfferDTO dto = new OfferDTO(offer.getOfferId());
|
OfferDTO dto = new OfferDTO();
|
||||||
|
dto.setOfferId(offer.getOfferId());
|
||||||
|
dto.setSourceProduct(ProductMapper.mapProductToDTO(offer.getSourceProduct()));
|
||||||
|
dto.setTargetProduct(ProductMapper.mapProductToDTO(offer.getTargetProduct()));
|
||||||
|
dto.setLastUpdate(offer.getLastUpdate());
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public final class ProductMapper {
|
|||||||
product.setDeliveryPrice(dto.getDeliveryPrice());
|
product.setDeliveryPrice(dto.getDeliveryPrice());
|
||||||
product.setMerchant(dto.getMerchant());
|
product.setMerchant(dto.getMerchant());
|
||||||
product.setProductId(dto.getProductId());
|
product.setProductId(dto.getProductId());
|
||||||
|
product.setLastUpdate(dto.getLastUpdate());
|
||||||
|
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
@@ -56,6 +57,7 @@ public final class ProductMapper {
|
|||||||
dto.setCurrentPrice(product.getCurrentPrice());
|
dto.setCurrentPrice(product.getCurrentPrice());
|
||||||
dto.setDeliveryPrice(product.getDeliveryPrice());
|
dto.setDeliveryPrice(product.getDeliveryPrice());
|
||||||
dto.setMerchant(product.getMerchant());
|
dto.setMerchant(product.getMerchant());
|
||||||
|
dto.setLastUpdate(product.getLastUpdate());
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
package de.rwu.easydrop.service.processing;
|
package de.rwu.easydrop.service.processing;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import de.rwu.easydrop.exception.InvalidCatalogueException;
|
import de.rwu.easydrop.exception.InvalidCatalogueException;
|
||||||
|
import de.rwu.easydrop.exception.InvalidOfferException;
|
||||||
|
import de.rwu.easydrop.model.Offer;
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
import de.rwu.easydrop.model.ProductCatalogue;
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
import de.rwu.easydrop.model.ProductPair;
|
import de.rwu.easydrop.model.ProductPair;
|
||||||
import de.rwu.easydrop.util.FormattingUtil;
|
import de.rwu.easydrop.util.FormattingUtil;
|
||||||
|
import de.rwu.easydrop.util.Timestamp;
|
||||||
|
|
||||||
/**
|
public class OfferIdentifier {
|
||||||
* Creates dropshipping orders based on price margin.
|
/**
|
||||||
*
|
* Logging instance.
|
||||||
* @since 0.3.0
|
|
||||||
*/
|
*/
|
||||||
public final class OrderManager {
|
private static final Logger LOGGER = LoggerFactory.getLogger(OfferIdentifier.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary logging instance.
|
* runIdentifier calls the price function that decides
|
||||||
*/
|
* if it is feasible to dropship products.
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(OrderManager.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor to prevent unwanted instantiation.
|
|
||||||
*
|
*
|
||||||
* @throws UnsupportedOperationException always
|
* @param pCats Product catalogues
|
||||||
|
* @return Identified offers
|
||||||
*/
|
*/
|
||||||
private OrderManager() throws UnsupportedOperationException {
|
public List<Offer> runIdentifier(final List<ProductCatalogue> pCats) {
|
||||||
throw new UnsupportedOperationException("This is a stateless class, don't instantiate it.");
|
List<Offer> identifiedOffers = new ArrayList<>();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates orders for products with sufficient margin.
|
|
||||||
*
|
|
||||||
* @param pCats Product Catalogues
|
|
||||||
*/
|
|
||||||
public static void createOrders(final List<ProductCatalogue> pCats) {
|
|
||||||
for (ProductCatalogue pCat : pCats) {
|
for (ProductCatalogue pCat : pCats) {
|
||||||
ProductPair pair = getHighestMarginProducts(pCat);
|
|
||||||
|
|
||||||
// #12: Create actual orders/transactions, remove logger
|
// Call price finder for all catalogue
|
||||||
|
ProductPair pair = getHighestMarginProducts(pCat);
|
||||||
|
Offer possibleOffer = new Offer();
|
||||||
|
possibleOffer.setLastUpdate(Timestamp.now());
|
||||||
|
possibleOffer.setSourceProduct(pair.getProduct1());
|
||||||
|
possibleOffer.setTargetProduct(pair.getProduct2());
|
||||||
|
identifiedOffers.add(possibleOffer);
|
||||||
|
|
||||||
double margin = pair.getProduct2().getCurrentPrice()
|
double margin = pair.getProduct2().getCurrentPrice()
|
||||||
- pair.getProduct1().getCurrentPrice();
|
- pair.getProduct1().getCurrentPrice();
|
||||||
String marginFormatted = FormattingUtil.formatEuro(margin);
|
String marginFormatted = FormattingUtil.formatEuro(margin);
|
||||||
LOGGER.info("{}: Margin {} ({} to {})",
|
LOGGER.info("\n Identified Offer: {} ({} to {}) with margin {} ",
|
||||||
pCat.getProductName(),
|
pCat.getProductName(),
|
||||||
marginFormatted,
|
|
||||||
pair.getProduct1().getDataOrigin(),
|
pair.getProduct1().getDataOrigin(),
|
||||||
pair.getProduct2().getDataOrigin());
|
pair.getProduct2().getDataOrigin(),
|
||||||
|
marginFormatted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return identifiedOffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,7 +79,7 @@ public final class OrderManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cheapestProduct.getCurrentPrice() == mostExpensiveProduct.getCurrentPrice()) {
|
if (cheapestProduct.getCurrentPrice() == mostExpensiveProduct.getCurrentPrice()) {
|
||||||
throw new InvalidCatalogueException("Price margin is zero!");
|
throw new InvalidOfferException("Price margin is zero!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ProductPair(cheapestProduct, mostExpensiveProduct);
|
return new ProductPair(cheapestProduct, mostExpensiveProduct);
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
package de.rwu.easydrop.core;
|
package de.rwu.easydrop.service.processing;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.client.AmazonSeller;
|
import de.rwu.easydrop.api.client.AmazonSeller;
|
||||||
import de.rwu.easydrop.api.client.EbaySeller;
|
import de.rwu.easydrop.api.client.EbaySeller;
|
||||||
import de.rwu.easydrop.exception.DataWriterException;
|
import de.rwu.easydrop.data.connector.OfferPersistenceInterface;
|
||||||
import de.rwu.easydrop.model.Offer;
|
import de.rwu.easydrop.model.Offer;
|
||||||
import de.rwu.easydrop.model.Webshop;
|
import de.rwu.easydrop.model.Webshop;
|
||||||
import de.rwu.easydrop.service.mapping.ProductMapper;
|
import de.rwu.easydrop.service.mapping.ProductMapper;
|
||||||
import de.rwu.easydrop.service.writer.OfferWriter;
|
import de.rwu.easydrop.service.writer.OfferWriter;
|
||||||
import de.rwu.easydrop.util.Config;
|
import de.rwu.easydrop.util.Config;
|
||||||
|
import de.rwu.easydrop.util.FormattingUtil;
|
||||||
|
|
||||||
public class OfferProvisioner {
|
public class OfferProvisioner {
|
||||||
/**
|
/**
|
||||||
@@ -31,11 +32,11 @@ public class OfferProvisioner {
|
|||||||
private EbaySeller ebaySeller;
|
private EbaySeller ebaySeller;
|
||||||
|
|
||||||
private void toSeller(final Offer offer) throws IllegalArgumentException {
|
private void toSeller(final Offer offer) throws IllegalArgumentException {
|
||||||
if (offer.getSaleProduct().getDataOrigin() == Webshop.eBay) {
|
if (offer.getTargetProduct().getDataOrigin() == Webshop.eBay) {
|
||||||
this.ebaySeller.sellProduct(ProductMapper.mapProductToDTO(offer.getSaleProduct()));
|
this.ebaySeller.sellProduct(ProductMapper.mapProductToDTO(offer.getTargetProduct()));
|
||||||
|
|
||||||
} else if (offer.getSaleProduct().getDataOrigin().equals(Webshop.Amazon)) {
|
} else if (offer.getTargetProduct().getDataOrigin().equals(Webshop.Amazon)) {
|
||||||
this.amazonSeller.sellProduct(ProductMapper.mapProductToDTO(offer.getSaleProduct()));
|
this.amazonSeller.sellProduct(ProductMapper.mapProductToDTO(offer.getTargetProduct()));
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported target plattform");
|
throw new IllegalArgumentException("Unsupported target plattform");
|
||||||
}
|
}
|
||||||
@@ -44,10 +45,11 @@ public class OfferProvisioner {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the class for placing orders on a target platform.
|
* Is the class for placing orders on a target platform.
|
||||||
|
*
|
||||||
|
* @param db Persistence Interface
|
||||||
*/
|
*/
|
||||||
public OfferProvisioner(/* OfferWriter for database? */) {
|
public OfferProvisioner(final OfferPersistenceInterface db) {
|
||||||
|
this.offerWriter = new OfferWriter(db);
|
||||||
this.offerWriter = new OfferWriter();
|
|
||||||
this.config = Config.getInstance();
|
this.config = Config.getInstance();
|
||||||
this.amazonSeller = new AmazonSeller(
|
this.amazonSeller = new AmazonSeller(
|
||||||
config.getProperty("AMAZON_API_URL"),
|
config.getProperty("AMAZON_API_URL"),
|
||||||
@@ -63,27 +65,17 @@ public class OfferProvisioner {
|
|||||||
* @param offersToProvision
|
* @param offersToProvision
|
||||||
*/
|
*/
|
||||||
public final void runProvisioner(final List<Offer> offersToProvision) {
|
public final void runProvisioner(final List<Offer> offersToProvision) {
|
||||||
|
|
||||||
for (Offer newOffer : offersToProvision) {
|
for (Offer newOffer : offersToProvision) {
|
||||||
|
String newOfferId = FormattingUtil.removeSpaces(
|
||||||
|
newOffer.getSourceProduct().getDataOrigin().toString()
|
||||||
|
+ newOffer.getTargetProduct().getDataOrigin().toString()
|
||||||
|
+ "_"
|
||||||
|
+ newOffer.getSourceProduct().getProductId()
|
||||||
|
+ newOffer.getTargetProduct().getProductId());
|
||||||
|
|
||||||
try {
|
|
||||||
this.toSeller(newOffer);
|
this.toSeller(newOffer);
|
||||||
// if successfully transmitted
|
newOffer.setOfferId(newOfferId);
|
||||||
// add to persistence
|
|
||||||
// "duplicate" the product with dataOrigin new platform and merchant = "me"
|
|
||||||
try {
|
|
||||||
offerWriter.writeOfferToPersistence(newOffer);
|
offerWriter.writeOfferToPersistence(newOffer);
|
||||||
} catch (Exception e) {
|
|
||||||
System.out.println("Could not write to persistence");
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
System.out.println(
|
|
||||||
"Offer could not be placed, "
|
|
||||||
+ newOffer.getSaleProduct().getDataOrigin()
|
|
||||||
+ " is not supported");
|
|
||||||
} catch (DataWriterException e) {
|
|
||||||
System.out.println("could not transmit offer");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,9 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
import de.rwu.easydrop.model.ProductCatalogue;
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
import de.rwu.easydrop.util.ProductsConfig;
|
import de.rwu.easydrop.util.ProductsConfig;
|
||||||
@@ -17,6 +20,11 @@ import lombok.Data;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class CatalogueRetriever {
|
public class CatalogueRetriever {
|
||||||
|
/**
|
||||||
|
* Logging instance.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(CatalogueRetriever.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User-configured products.
|
* User-configured products.
|
||||||
*/
|
*/
|
||||||
@@ -56,15 +64,14 @@ public class CatalogueRetriever {
|
|||||||
pCat.getProductName(), pCat.getDescription());
|
pCat.getProductName(), pCat.getDescription());
|
||||||
|
|
||||||
for (Product product : pCat.getProducts()) {
|
for (Product product : pCat.getProducts()) {
|
||||||
Product newProduct = new Product();
|
Product newProduct = productRetriever.getProductFromWebshop(product.getDataOrigin(),
|
||||||
|
|
||||||
newProduct = productRetriever.getProductFromWebshop(product.getDataOrigin(),
|
|
||||||
product.getProductId());
|
product.getProductId());
|
||||||
|
|
||||||
newProductCatalogue.addProduct(newProduct);
|
newProductCatalogue.addProduct(newProduct);
|
||||||
}
|
}
|
||||||
|
|
||||||
productCatalogues.add(newProductCatalogue);
|
productCatalogues.add(newProductCatalogue);
|
||||||
|
LOGGER.info("\nLoaded Catalogue: \n" + newProductCatalogue.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,40 @@
|
|||||||
package de.rwu.easydrop.service.retriever;
|
package de.rwu.easydrop.service.retriever;
|
||||||
|
|
||||||
public class OfferRetriever {
|
import de.rwu.easydrop.api.dto.OfferDTO;
|
||||||
|
import de.rwu.easydrop.data.connector.OfferPersistenceInterface;
|
||||||
|
import de.rwu.easydrop.model.Offer;
|
||||||
|
import de.rwu.easydrop.service.mapping.OfferMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves offer information from different sources.
|
||||||
|
*
|
||||||
|
* @since 0.3.0
|
||||||
|
*/
|
||||||
|
public class OfferRetriever {
|
||||||
|
/**
|
||||||
|
* Persistence interface.
|
||||||
|
*/
|
||||||
|
private OfferPersistenceInterface persistence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an Offer Retriever.
|
||||||
|
*
|
||||||
|
* @param db Persistence Interface
|
||||||
|
*/
|
||||||
|
public OfferRetriever(final OfferPersistenceInterface db) {
|
||||||
|
this.persistence = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an offer from persistence.
|
||||||
|
*
|
||||||
|
* @param offerId
|
||||||
|
* @return Offer from persistence
|
||||||
|
*/
|
||||||
|
public Offer getOfferFromPersistence(final String offerId) {
|
||||||
|
OfferPersistenceInterface src = persistence;
|
||||||
|
|
||||||
|
OfferDTO dto = src.getOfferDTOById(offerId);
|
||||||
|
return OfferMapper.mapOfferFromDTO(dto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import de.rwu.easydrop.api.client.AmazonProductDataSource;
|
|||||||
import de.rwu.easydrop.api.client.DataSourceFactory;
|
import de.rwu.easydrop.api.client.DataSourceFactory;
|
||||||
import de.rwu.easydrop.api.client.EbayItemDataSource;
|
import de.rwu.easydrop.api.client.EbayItemDataSource;
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
import de.rwu.easydrop.data.connector.ProductPersistenceInterface;
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
import de.rwu.easydrop.model.Webshop;
|
import de.rwu.easydrop.model.Webshop;
|
||||||
import de.rwu.easydrop.service.mapping.ProductMapper;
|
import de.rwu.easydrop.service.mapping.ProductMapper;
|
||||||
@@ -20,19 +20,20 @@ public class ProductRetriever {
|
|||||||
* Data source factory.
|
* Data source factory.
|
||||||
*/
|
*/
|
||||||
private DataSourceFactory dataSourceFactory;
|
private DataSourceFactory dataSourceFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param newDataSourceFactory the WebshopFactory to set
|
* Persistence interface.
|
||||||
*/
|
*/
|
||||||
public void setWebshopFactory(final DataSourceFactory newDataSourceFactory) {
|
private ProductPersistenceInterface persistence;
|
||||||
this.dataSourceFactory = newDataSourceFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param newDataSourceFactory
|
* @param newDataSourceFactory
|
||||||
|
* @param newPersistence
|
||||||
*/
|
*/
|
||||||
public ProductRetriever(final DataSourceFactory newDataSourceFactory) {
|
public ProductRetriever(
|
||||||
this.setWebshopFactory(newDataSourceFactory);
|
final DataSourceFactory newDataSourceFactory,
|
||||||
|
final ProductPersistenceInterface newPersistence) {
|
||||||
|
this.dataSourceFactory = newDataSourceFactory;
|
||||||
|
this.persistence = newPersistence;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,9 +75,7 @@ public class ProductRetriever {
|
|||||||
* @return Product from persistence
|
* @return Product from persistence
|
||||||
*/
|
*/
|
||||||
public Product getProductFromPersistence(final String productId) {
|
public Product getProductFromPersistence(final String productId) {
|
||||||
AbstractProductPersistence src = dataSourceFactory.createProductPersistenceDataSource();
|
ProductDTO dto = persistence.getProductDTOById(productId);
|
||||||
|
|
||||||
ProductDTO dto = src.getProductDTOById(productId);
|
|
||||||
Product product = ProductMapper.mapProductFromDTO(dto);
|
Product product = ProductMapper.mapProductFromDTO(dto);
|
||||||
ProductValidator.validate(product);
|
ProductValidator.validate(product);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package de.rwu.easydrop.service.validation;
|
package de.rwu.easydrop.service.validation;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.exception.InvalidOfferException;
|
||||||
import de.rwu.easydrop.model.Offer;
|
import de.rwu.easydrop.model.Offer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,13 +17,19 @@ public final class OfferValidator {
|
|||||||
private OfferValidator() throws UnsupportedOperationException {
|
private OfferValidator() throws UnsupportedOperationException {
|
||||||
throw new UnsupportedOperationException("This is a validator class, don't instantiate it.");
|
throw new UnsupportedOperationException("This is a validator class, don't instantiate it.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes sure an Offer does not contain invalid information.
|
* Makes sure an Offer does not contain invalid information.
|
||||||
*
|
*
|
||||||
* @param offer the Offer
|
* @param offer the Offer
|
||||||
*/
|
*/
|
||||||
public static void validate(final Offer offer) { }
|
public static void validate(final Offer offer) {
|
||||||
|
try {
|
||||||
|
if (offer.getOfferId().equals("")) {
|
||||||
|
throw new InvalidOfferException("Offer ID cannot be empty");
|
||||||
|
}
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
throw new InvalidOfferException("Required information is missing in the offer", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package de.rwu.easydrop.service.writer;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
import de.rwu.easydrop.data.connector.ProductPersistenceInterface;
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
import de.rwu.easydrop.model.ProductCatalogue;
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
import de.rwu.easydrop.service.mapping.ProductMapper;
|
import de.rwu.easydrop.service.mapping.ProductMapper;
|
||||||
@@ -18,14 +18,14 @@ public final class CatalogueWriter {
|
|||||||
/**
|
/**
|
||||||
* Holds a persistence reference.
|
* Holds a persistence reference.
|
||||||
*/
|
*/
|
||||||
private AbstractProductPersistence persistence;
|
private ProductPersistenceInterface persistence;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new instance.
|
* Creates new instance.
|
||||||
*
|
*
|
||||||
* @param newPersistence
|
* @param newPersistence
|
||||||
*/
|
*/
|
||||||
public CatalogueWriter(final AbstractProductPersistence newPersistence) {
|
public CatalogueWriter(final ProductPersistenceInterface newPersistence) {
|
||||||
persistence = newPersistence;
|
persistence = newPersistence;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ public final class CatalogueWriter {
|
|||||||
ProductValidator.validate(product);
|
ProductValidator.validate(product);
|
||||||
ProductDTO dto = ProductMapper.mapProductToDTO(product);
|
ProductDTO dto = ProductMapper.mapProductToDTO(product);
|
||||||
|
|
||||||
persistence.saveProduct(dto);
|
persistence.writeProduct(dto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
package de.rwu.easydrop.service.writer;
|
package de.rwu.easydrop.service.writer;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.dto.OfferDTO;
|
import de.rwu.easydrop.api.dto.OfferDTO;
|
||||||
import de.rwu.easydrop.data.connector.AbstractOfferPersistence;
|
import de.rwu.easydrop.data.connector.OfferPersistenceInterface;
|
||||||
import de.rwu.easydrop.model.Offer;
|
import de.rwu.easydrop.model.Offer;
|
||||||
import de.rwu.easydrop.service.mapping.OfferMapper;
|
import de.rwu.easydrop.service.mapping.OfferMapper;
|
||||||
import de.rwu.easydrop.service.validation.OfferValidator;
|
|
||||||
|
|
||||||
public class OfferWriter {
|
public class OfferWriter {
|
||||||
/**
|
/**
|
||||||
* Persistence.
|
* Persistence.
|
||||||
*/
|
*/
|
||||||
private AbstractOfferPersistence persistence;
|
private OfferPersistenceInterface persistence;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param newPersistence the persistence to set
|
* @param newPersistence the persistence to set
|
||||||
*/
|
*/
|
||||||
public void setPersistence(final AbstractOfferPersistence newPersistence) {
|
public OfferWriter(final OfferPersistenceInterface newPersistence) {
|
||||||
this.persistence = newPersistence;
|
this.persistence = newPersistence;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,9 +24,8 @@ public class OfferWriter {
|
|||||||
* @param offer
|
* @param offer
|
||||||
*/
|
*/
|
||||||
public void writeOfferToPersistence(final Offer offer) {
|
public void writeOfferToPersistence(final Offer offer) {
|
||||||
OfferValidator.validate(offer);
|
|
||||||
OfferDTO dto = OfferMapper.mapOfferToDTO(offer);
|
OfferDTO dto = OfferMapper.mapOfferToDTO(offer);
|
||||||
|
|
||||||
persistence.saveOffer(dto);
|
persistence.writeOffer(dto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package de.rwu.easydrop.service.writer;
|
package de.rwu.easydrop.service.writer;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
import de.rwu.easydrop.data.connector.AbstractProductPersistence;
|
import de.rwu.easydrop.data.connector.ProductPersistenceInterface;
|
||||||
import de.rwu.easydrop.model.Product;
|
import de.rwu.easydrop.model.Product;
|
||||||
import de.rwu.easydrop.service.mapping.ProductMapper;
|
import de.rwu.easydrop.service.mapping.ProductMapper;
|
||||||
import de.rwu.easydrop.service.validation.ProductValidator;
|
import de.rwu.easydrop.service.validation.ProductValidator;
|
||||||
@@ -15,12 +15,12 @@ public class ProductWriter {
|
|||||||
/**
|
/**
|
||||||
* Persistence.
|
* Persistence.
|
||||||
*/
|
*/
|
||||||
private AbstractProductPersistence persistence;
|
private ProductPersistenceInterface persistence;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param newPersistence the persistence to set
|
* @param newPersistence the persistence to set
|
||||||
*/
|
*/
|
||||||
public void setPersistence(final AbstractProductPersistence newPersistence) {
|
public ProductWriter(final ProductPersistenceInterface newPersistence) {
|
||||||
this.persistence = newPersistence;
|
this.persistence = newPersistence;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,6 +33,6 @@ public class ProductWriter {
|
|||||||
ProductValidator.validate(product);
|
ProductValidator.validate(product);
|
||||||
ProductDTO dto = ProductMapper.mapProductToDTO(product);
|
ProductDTO dto = ProductMapper.mapProductToDTO(product);
|
||||||
|
|
||||||
persistence.saveProduct(dto);
|
persistence.writeProduct(dto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,4 +37,14 @@ public final class FormattingUtil {
|
|||||||
public static String urlEncode(final String str) {
|
public static String urlEncode(final String str) {
|
||||||
return str.replace(" ", "+");
|
return str.replace(" ", "+");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes spaces from target string.
|
||||||
|
*
|
||||||
|
* @param str String
|
||||||
|
* @return Space-less string
|
||||||
|
*/
|
||||||
|
public static String removeSpaces(final String str) {
|
||||||
|
return str.replace(" ", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
src/main/java/de/rwu/easydrop/util/Timestamp.java
Normal file
29
src/main/java/de/rwu/easydrop/util/Timestamp.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package de.rwu.easydrop.util;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serves as a timestamp source.
|
||||||
|
*
|
||||||
|
* @since 0.3.0
|
||||||
|
*/
|
||||||
|
public abstract class Timestamp {
|
||||||
|
/**
|
||||||
|
* Hidden constructor.
|
||||||
|
*/
|
||||||
|
private Timestamp() {
|
||||||
|
// Don't instantiate me!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a formatted time string.
|
||||||
|
*
|
||||||
|
* @return String such as "2023-01-01 00:00:00"
|
||||||
|
*/
|
||||||
|
public static String now() {
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
return now.format(formatter);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user