| <dependency> | ||
| <groupId>org.hibernate</groupId> | ||
| - <artifactId>hibernate-entitymanager</artifactId> | ||
| + <artifactId>hibernate-c3p0</artifactId> | ||
| <version>5.1.0.Final</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.hibernate</groupId> | ||
| - <artifactId>hibernate-c3p0</artifactId> | ||
| + <artifactId>hibernate-entitymanager</artifactId> | ||
| <version>5.1.0.Final</version> | ||
| </dependency> |
| import java.io.Serializable; | ||
| +import javax.persistence.Id; | ||
| +import javax.persistence.MappedSuperclass; | ||
| +import javax.persistence.Transient; | ||
| /** | ||
| * Provides fluent interface for constructing objects. | ||
| * | ||
| * @author White Magic Software, Ltd. | ||
| */ | ||
| +@MappedSuperclass | ||
| public class BusinessEntity implements Serializable { | ||
| + | ||
| + @Id | ||
| + private int id; | ||
| /** | ||
| * Full name, first name, last name, etc. | ||
| */ | ||
| + @Transient | ||
| private EntityName entityName; | ||
| public BusinessEntity() { | ||
| } | ||
| - | ||
| - public String getName() { | ||
| + | ||
| + protected void setId( int id ) { | ||
| + this.id = id; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns a unique identifier for this subscriber. | ||
| + * | ||
| + * @return The primary key, or 0 if not initialized. | ||
| + */ | ||
| + public int getId() { | ||
| + return this.id; | ||
| + } | ||
| + | ||
| + protected String getName() { | ||
| return getEntityName().getName(); | ||
| } | ||
| - | ||
| + | ||
| + protected void setName( String name ) { | ||
| + setEntityName( name ); | ||
| + } | ||
| + | ||
| /** | ||
| * Sets the entity name. Do not pass in null. | ||
| * | ||
| * @param entityName | ||
| */ | ||
| - protected final void setEntityName(EntityName entityName) { | ||
| + protected final void setEntityName( EntityName entityName ) { | ||
| this.entityName = entityName; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Sets the entity name using a string. This is called by setName. | ||
| + * | ||
| + * @param name Entity name. | ||
| + */ | ||
| + private void setEntityName( String name ) { | ||
| + setEntityName( new EntityName( name ) ); | ||
| } | ||
| } | ||
| - protected String nullSafe(String s) { | ||
| + protected String nullSafe( String s ) { | ||
| return s == null ? "" : s; | ||
| } | ||
| protected abstract B getBuilder(); | ||
| - @SuppressWarnings("OverridableMethodCallInConstructor") | ||
| + @SuppressWarnings( "OverridableMethodCallInConstructor" ) | ||
| public Builder() { | ||
| this.object = createObject(); | ||
| this.builder = getBuilder(); | ||
| } | ||
| - public B withEntityName(EntityName entityName) { | ||
| - getObject().setEntityName(entityName); | ||
| + public B withEntityName( EntityName entityName ) { | ||
| + getObject().setEntityName( entityName ); | ||
| return getBuilder(); | ||
| } | ||
| - public B withName(String name) { | ||
| - withEntityName(new EntityName(name)); | ||
| + public B withName( String name ) { | ||
| + withEntityName( new EntityName( name ) ); | ||
| return getBuilder(); | ||
| } | ||
| } | ||
| - public final void setName( String name ) { | ||
| + protected final void setName( String name ) { | ||
| this.name = name; | ||
| } |
| import com.whitemagicsoftware.sales.service.ProductService; | ||
| import com.whitemagicsoftware.sales.service.SubscriberService; | ||
| +import com.whitemagicsoftware.sales.service.SubscriptionService; | ||
| import com.whitemagicsoftware.sales.service.VendorService; | ||
| import com.whitemagicsoftware.sales.service.impl.NotifyServiceImpl; | ||
| import com.whitemagicsoftware.sales.service.impl.ProductServiceImpl; | ||
| import com.whitemagicsoftware.sales.service.impl.SubscriberServiceImpl; | ||
| +import com.whitemagicsoftware.sales.service.impl.SubscriptionServiceImpl; | ||
| import com.whitemagicsoftware.sales.service.impl.VendorServiceImpl; | ||
| import java.io.File; | ||
| } | ||
| + /** | ||
| + * Iterates over all the vendors for each subscriber | ||
| + * | ||
| + * @param subscriber | ||
| + * | ||
| + * @return | ||
| + * | ||
| + * @throws Exception | ||
| + */ | ||
| private String process( Subscriber subscriber ) | ||
| throws Exception { | ||
| boolean includeVendorName = true; | ||
| - for( Product product : getProducts( subscriber, vendor ) ) { | ||
| + for( Subscription subscription : getSubscriptions( subscriber, vendor ) ) { | ||
| Scraper scraper = getScraper( vendor ); | ||
| + | ||
| + Product product = subscription.getProduct(); | ||
| scraper.addVariableToContext( "vendor_name_include", includeVendorName ); | ||
| private NotifyService getNotifyService() { | ||
| return new NotifyServiceImpl(); | ||
| + } | ||
| + | ||
| + private SubscriptionService getSubscriptionService() { | ||
| + return new SubscriptionServiceImpl(); | ||
| } | ||
| } | ||
| - private List<Product> getProducts( Subscriber subscriber, Vendor vendor ) { | ||
| - return getProductService().list( subscriber, vendor ); | ||
| + private List<Subscription> getSubscriptions( Subscriber subscriber, Vendor vendor ) { | ||
| + return getSubscriptionService().list( subscriber, vendor ); | ||
| } | ||
| package com.whitemagicsoftware.sales; | ||
| +import javax.persistence.Column; | ||
| +import javax.persistence.Entity; | ||
| +import javax.persistence.Table; | ||
| +import javax.persistence.Transient; | ||
| + | ||
| /** | ||
| * @author White Magic Software, Ltd. | ||
| */ | ||
| -public final class Product extends BusinessEntity { | ||
| +@Entity | ||
| +@Table( name = "product" ) | ||
| +public class Product extends BusinessEntity { | ||
| - private Price sale; | ||
| - private Price regular; | ||
| + /** | ||
| + * Setting this value will indirectly set the entity name. | ||
| + */ | ||
| + @Column( name = "product_name" ) | ||
| + private String name; | ||
| /** | ||
| * Path to the product page for products that have their own web page. | ||
| */ | ||
| + @Column( name = "product_path" ) | ||
| private String urlPath; | ||
| - private Product() { | ||
| + @Transient | ||
| + private Price sale; | ||
| + | ||
| + @Transient | ||
| + private Price regular; | ||
| + | ||
| + public Product() { | ||
| } | ||
| * @param price | ||
| */ | ||
| - public void setSalePrice(Price price) { | ||
| + public void setSalePrice( Price price ) { | ||
| this.sale = price; | ||
| } | ||
| * @param price | ||
| */ | ||
| - public void setRegularPrice(Price price) { | ||
| + public void setRegularPrice( Price price ) { | ||
| this.regular = price; | ||
| } | ||
| /** | ||
| * Sets the web page to the product for a vendor's web site. | ||
| * | ||
| * @param urlPath The unique path component to the product URL. | ||
| */ | ||
| - private void setUrlPath(String urlPath) { | ||
| + protected void setUrlPath( String urlPath ) { | ||
| this.urlPath = urlPath; | ||
| } | ||
| + /** | ||
| + * Returns the product's web page path, which is appended to the vendor's web | ||
| + * site URL. | ||
| + * | ||
| + * @return Path to the vendor's product page or empty string, never null. | ||
| + */ | ||
| protected String getUrlPath() { | ||
| - return nullSafe(this.urlPath); | ||
| + return nullSafe( this.urlPath ); | ||
| } | ||
| - public static final class Builder extends BusinessEntity.Builder<Product, Builder> { | ||
| + public static final class Builder | ||
| + extends BusinessEntity.Builder<Product, Builder> { | ||
| @Override | ||
| } | ||
| - public Builder withUrlPath(String urlPath) { | ||
| - getObject().setUrlPath(urlPath); | ||
| + public Builder withUrlPath( String urlPath ) { | ||
| + getObject().setUrlPath( urlPath ); | ||
| return getBuilder(); | ||
| } | ||
| import javax.persistence.Column; | ||
| import javax.persistence.Entity; | ||
| -import javax.persistence.GeneratedValue; | ||
| -import javax.persistence.GenerationType; | ||
| -import javax.persistence.Id; | ||
| import javax.persistence.Table; | ||
| import javax.persistence.Temporal; | ||
| +import javax.persistence.Transient; | ||
| /** | ||
| private static final long serialVersionUID = 0L; | ||
| - | ||
| - @Id | ||
| - @GeneratedValue( strategy = GenerationType.AUTO ) | ||
| - private int id; | ||
| /* Notifications are sent to this address. */ | ||
| + @Transient | ||
| private Address address; | ||
| protected Subscriber() { | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns a unique identifier for this subscriber. | ||
| - * | ||
| - * @return The primary key, or 0 if not initialized. | ||
| - */ | ||
| - private int getId() { | ||
| - return this.id; | ||
| } | ||
| +/* | ||
| + * The MIT License | ||
| + * | ||
| + * Copyright 2016 White Magic Software, Ltd.. | ||
| + * | ||
| + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| + * of this software and associated documentation files (the "Software"), to deal | ||
| + * in the Software without restriction, including without limitation the rights | ||
| + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| + * copies of the Software, and to permit persons to whom the Software is | ||
| + * furnished to do so, subject to the following conditions: | ||
| + * | ||
| + * The above copyright notice and this permission notice shall be included in | ||
| + * all copies or substantial portions of the Software. | ||
| + * | ||
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| + * THE SOFTWARE. | ||
| + */ | ||
| +package com.whitemagicsoftware.sales; | ||
| + | ||
| +import javax.persistence.Entity; | ||
| +import javax.persistence.OneToOne; | ||
| +import javax.persistence.Table; | ||
| + | ||
| +/** | ||
| + * | ||
| + * @author White Magic Software, Ltd. | ||
| + */ | ||
| +@Entity | ||
| +@Table( name = "subscription_vw" ) | ||
| +public class Subscription extends BusinessEntity { | ||
| + | ||
| + @OneToOne | ||
| + private Product product; | ||
| + | ||
| + public Subscription() { | ||
| + } | ||
| + | ||
| + protected Product getProduct() { | ||
| + return this.product; | ||
| + } | ||
| +} | ||
| package com.whitemagicsoftware.sales; | ||
| +import javax.persistence.Column; | ||
| +import javax.persistence.Entity; | ||
| +import javax.persistence.Table; | ||
| + | ||
| /** | ||
| * Represents a company that sells products. | ||
| * | ||
| * @author White Magic Software, Ltd. | ||
| */ | ||
| -public final class Vendor extends BusinessEntity { | ||
| +@Entity | ||
| +@Table( name = "vendors()" ) | ||
| +public class Vendor extends BusinessEntity { | ||
| + | ||
| + private static final long serialVersionUID = 0L; | ||
| + | ||
| /** | ||
| * The script to run for this Vendor. | ||
| */ | ||
| + @Column( name = "script" ) | ||
| private String scriptName; | ||
| public Vendor() { | ||
| } | ||
| - private void setScriptName(String scriptName) { | ||
| + /** | ||
| + * Sets the script used to scrap the product page (or flyer). | ||
| + * | ||
| + * @param scriptName Script to run to scrape a page. | ||
| + */ | ||
| + public void setScriptName( String scriptName ) { | ||
| this.scriptName = scriptName; | ||
| } | ||
| - | ||
| - public String getScriptName() { | ||
| - return nullSafe(this.scriptName); | ||
| + | ||
| + protected String getScriptName() { | ||
| + return nullSafe( this.scriptName ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns a formatted vendor ID and script name. | ||
| + * | ||
| + * @return The vendor ID and script as a string suitable for use with | ||
| + * debugging. | ||
| + */ | ||
| + @Override | ||
| + public String toString() { | ||
| + return "Vendor script #" + getId() + ": " + getScriptName(); | ||
| } | ||
| /** | ||
| * Script name must have an extension of .xml. | ||
| - * | ||
| + * | ||
| * @param scriptName The name of the script for a particular vendor. | ||
| + * | ||
| * @return this.builder | ||
| */ | ||
| - public Builder withScriptName(String scriptName) { | ||
| - getObject().setScriptName(scriptName); | ||
| + public Builder withScriptName( String scriptName ) { | ||
| + getObject().setScriptName( scriptName ); | ||
| return getBuilder(); | ||
| } | ||
| import com.whitemagicsoftware.sales.Product; | ||
| -import com.whitemagicsoftware.sales.Subscriber; | ||
| -import com.whitemagicsoftware.sales.Vendor; | ||
| import java.util.List; | ||
| /** | ||
| - * Returns a list of products for a given subscriber and vendor. | ||
| + * Returns a list of products. | ||
| * | ||
| - * @param subscriber Person who has subscribed to products from a particular | ||
| - * vendor. | ||
| - * @param vendor The vendor that has products. | ||
| - * @return | ||
| + * @return A list of products, by name, stored in the database. | ||
| */ | ||
| - public List<Product> list(Subscriber subscriber, Vendor vendor); | ||
| + public List<Product> list(); | ||
| } | ||
| +/* | ||
| + * The MIT License | ||
| + * | ||
| + * Copyright 2016 White Magic Software, Ltd.. | ||
| + * | ||
| + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| + * of this software and associated documentation files (the "Software"), to deal | ||
| + * in the Software without restriction, including without limitation the rights | ||
| + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| + * copies of the Software, and to permit persons to whom the Software is | ||
| + * furnished to do so, subject to the following conditions: | ||
| + * | ||
| + * The above copyright notice and this permission notice shall be included in | ||
| + * all copies or substantial portions of the Software. | ||
| + * | ||
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| + * THE SOFTWARE. | ||
| + */ | ||
| +package com.whitemagicsoftware.sales.service; | ||
| + | ||
| +import com.whitemagicsoftware.sales.Subscriber; | ||
| +import com.whitemagicsoftware.sales.Subscription; | ||
| +import com.whitemagicsoftware.sales.Vendor; | ||
| +import java.util.List; | ||
| + | ||
| +/** | ||
| + * Provides the ability to load subscription data. | ||
| + * | ||
| + * @author White Magic Software, Ltd. | ||
| + */ | ||
| +public interface SubscriptionService extends Service { | ||
| + | ||
| + /** | ||
| + * Returns a list of subscriptions for a given subscriber and vendor pairing. | ||
| + * | ||
| + * @param subscriber The subscriber that has subscriptions to sale notifications. | ||
| + * @param vendor The vendor that has products the subscriber is interested in. | ||
| + * | ||
| + * @return A non-null, possibly empty, list. | ||
| + */ | ||
| + public List<Subscription> list( Subscriber subscriber, Vendor vendor ); | ||
| +} | ||
| * | ||
| * @return A non-null list, possibly empty. | ||
| - * @throws java.lang.Exception Could not obtain the vendor list. | ||
| */ | ||
| - public List<Vendor> list() throws Exception; | ||
| + public List<Vendor> list(); | ||
| } | ||
| import com.whitemagicsoftware.sales.Product; | ||
| -import com.whitemagicsoftware.sales.Subscriber; | ||
| -import com.whitemagicsoftware.sales.Vendor; | ||
| import com.whitemagicsoftware.sales.service.ProductService; | ||
| import java.util.List; | ||
| @Override | ||
| - public List<Product> list(Subscriber subscriber, Vendor vendor) { | ||
| - List<Product> result = createList(); | ||
| - | ||
| - Product product = new Product.Builder() | ||
| - .withName("Sunflower Seeds") | ||
| - .withUrlPath("sunflower-seeds/00000_000000000000005091") | ||
| - .build(); | ||
| - | ||
| - result.add(product); | ||
| - | ||
| - return result; | ||
| + public List<Product> list() { | ||
| + return getResultList( Product.class ); | ||
| } | ||
| - | ||
| } | ||
| * Ensure only a single instance is created. | ||
| */ | ||
| + private static EntityManagerFactory ENTITY_MANAGER_FACTORY; | ||
| + | ||
| private EntityManager entityManager; | ||
| private final static String PERSISTENCE_PASSWORD_PROPERTY | ||
| = "javax.persistence.jdbc.password"; | ||
| /** | ||
| * Creates a new list of items. | ||
| * | ||
| - * @return | ||
| + * @return An empty, non-null ArrayList. | ||
| */ | ||
| protected List<T> createList() { | ||
| private synchronized EntityManager getEntityManager() { | ||
| if( this.entityManager == null ) { | ||
| - this.entityManager = createEntityManager(); | ||
| + this.entityManager = getEntityManagerFactory().createEntityManager(); | ||
| } | ||
| return this.entityManager; | ||
| } | ||
| - private EntityManager createEntityManager() { | ||
| - return getEntityManagerFactory().createEntityManager(); | ||
| + private synchronized EntityManagerFactory getEntityManagerFactory() { | ||
| + if( ENTITY_MANAGER_FACTORY == null ) { | ||
| + ENTITY_MANAGER_FACTORY = createEntityManagerFactory(); | ||
| + } | ||
| + | ||
| + return ENTITY_MANAGER_FACTORY; | ||
| } | ||
| - private EntityManagerFactory getEntityManagerFactory() { | ||
| + private EntityManagerFactory createEntityManagerFactory() { | ||
| return Persistence.createEntityManagerFactory( getPersistenceUnitName(), | ||
| getPersistenceProperties() ); | ||
| private String getPersistenceUnitName() { | ||
| return "SALES"; | ||
| + } | ||
| + | ||
| + protected CriteriaQuery<T> createQuery( Class<T> clazz ) { | ||
| + return getCriteriaBuilder().createQuery( clazz ); | ||
| + } | ||
| + | ||
| + protected TypedQuery<T> createQuery( String sql, Class<T> clazz ) { | ||
| + return getEntityManager().createQuery( sql, clazz ); | ||
| + } | ||
| + | ||
| + protected TypedQuery<T> createQuery( CriteriaQuery<T> cq ) { | ||
| + return getEntityManager().createQuery( cq ); | ||
| } | ||
| */ | ||
| protected List<T> getResultList( Class<T> clazz ) { | ||
| - CriteriaBuilder cb = getCriteriaBuilder(); | ||
| - CriteriaQuery<T> cq = cb.createQuery( clazz ); | ||
| + CriteriaQuery<T> cq = createQuery( clazz ); | ||
| Root<T> root = cq.from( clazz ); | ||
| - | ||
| CriteriaQuery<T> all = cq.select( root ); | ||
| - TypedQuery<T> query = getEntityManager().createQuery( all ); | ||
| - return query.getResultList(); | ||
| + | ||
| + return createQuery( all ).getResultList(); | ||
| } | ||
| } | ||
| @Override | ||
| public List<Subscriber> list() throws AddressException { | ||
| - return getResultList(Subscriber.class); | ||
| + return getResultList( Subscriber.class ); | ||
| } | ||
| } |
| +/* | ||
| + * The MIT License | ||
| + * | ||
| + * Copyright 2016 White Magic Software, Ltd.. | ||
| + * | ||
| + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| + * of this software and associated documentation files (the "Software"), to deal | ||
| + * in the Software without restriction, including without limitation the rights | ||
| + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| + * copies of the Software, and to permit persons to whom the Software is | ||
| + * furnished to do so, subject to the following conditions: | ||
| + * | ||
| + * The above copyright notice and this permission notice shall be included in | ||
| + * all copies or substantial portions of the Software. | ||
| + * | ||
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| + * THE SOFTWARE. | ||
| + */ | ||
| +package com.whitemagicsoftware.sales.service.impl; | ||
| + | ||
| +import com.whitemagicsoftware.sales.Subscriber; | ||
| +import com.whitemagicsoftware.sales.Subscription; | ||
| +import com.whitemagicsoftware.sales.Vendor; | ||
| +import com.whitemagicsoftware.sales.service.SubscriptionService; | ||
| +import java.util.List; | ||
| +import javax.persistence.TypedQuery; | ||
| + | ||
| +/** | ||
| + * @author White Magic Software, Ltd. | ||
| + */ | ||
| +public class SubscriptionServiceImpl extends ServiceImpl<Subscription> implements SubscriptionService { | ||
| + @Override | ||
| + public List<Subscription> list( Subscriber subscriber, Vendor vendor ) { | ||
| + TypedQuery<Subscription> products = createQuery( "SELECT " | ||
| + + "id, name, urlPath FROM Product " | ||
| + + "WHERE subscriber_id = :subscriber_id AND vendor_id = :vendor_id", | ||
| + Subscription.class ); | ||
| + | ||
| + products.setParameter( "subscriber_id", subscriber.getId() ); | ||
| + products.setParameter( "vendor_id", vendor.getId() ); | ||
| + | ||
| + return null; | ||
| + } | ||
| +} | ||
| package com.whitemagicsoftware.sales.service.impl; | ||
| -import com.whitemagicsoftware.sales.Subscriber; | ||
| import com.whitemagicsoftware.sales.Vendor; | ||
| import com.whitemagicsoftware.sales.service.VendorService; | ||
| -import java.io.BufferedReader; | ||
| -import java.io.IOException; | ||
| -import java.io.InputStream; | ||
| -import java.io.InputStreamReader; | ||
| -import java.util.ArrayList; | ||
| import java.util.List; | ||
| /** | ||
| * @author White Magic Software, Ltd. | ||
| */ | ||
| public class VendorServiceImpl extends ServiceImpl<Vendor> | ||
| implements VendorService { | ||
| @Override | ||
| - public List<Vendor> list() throws Exception { | ||
| - List<Vendor> result = createList(); | ||
| - | ||
| - for( final String filename : getScriptFilenames() ) { | ||
| - Vendor vendor = new Vendor.Builder() | ||
| - .withScriptName( filename ) | ||
| - .build(); | ||
| - | ||
| - result.add( vendor ); | ||
| - | ||
| - } | ||
| - | ||
| - return result; | ||
| - } | ||
| - | ||
| - private List<String> getScriptFilenames() throws IOException { | ||
| - List<String> filenames = new ArrayList<>(); | ||
| - | ||
| - try( | ||
| - InputStream in = getResourceAsStream( "scripts" ); | ||
| - BufferedReader br = new BufferedReader( new InputStreamReader( in ) ) ) { | ||
| - String resource; | ||
| - | ||
| - while( (resource = br.readLine()) != null ) { | ||
| - filenames.add( resource ); | ||
| - } | ||
| - } | ||
| - | ||
| - return filenames; | ||
| - } | ||
| - | ||
| - private InputStream getResourceAsStream( String resource ) { | ||
| - final InputStream in | ||
| - = getContextClassLoader().getResourceAsStream( resource ); | ||
| - | ||
| - return in == null ? getClass().getResourceAsStream( resource ) : in; | ||
| - } | ||
| - | ||
| - private ClassLoader getContextClassLoader() { | ||
| - return Thread.currentThread().getContextClassLoader(); | ||
| + public List<Vendor> list() { | ||
| + return getResultList( Vendor.class ); | ||
| } | ||
| } |
| <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> | ||
| <persistence-unit name="SALES" transaction-type="RESOURCE_LOCAL"> | ||
| - <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> | ||
| + <provider>org.hibernate.ejb.HibernatePersistence</provider> | ||
| <properties> | ||
| + <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/> | ||
| <property name="javax.persistence.jdbc.url" value="jdbc:postgresql:sales"/> | ||
| <property name="javax.persistence.jdbc.user" value="sales"/> | ||
| <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/> | ||
| - <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/> | ||
| - <property name="hibernate.hbm2ddl.auto" value="validate"/> | ||
| - | ||
| + | ||
| <!-- Password is set using a command line property of the same name. --> | ||
| <!--property name="javax.persistence.jdbc.password" value=""/--> | ||
| - | ||
| + | ||
| <!-- http://www.hibernate.org/214.html --> | ||
| <!-- https://developer.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool --> | ||
| <property name="hibernate.c3p0.acquireRetryAttempts" value="1"/> | ||
| <property name="hibernate.c3p0.acquireRetryDelay" value="250"/> | ||
| - | ||
| <!-- Show SQL statements for debugging purposes. --> | ||
| - <property name="hibernate.show_sql" value="false"/> | ||
| + <property name="hibernate.show_sql" value="true"/> | ||
| + <!-- Disabled because "vendor" isn't a table, it's a function. --> | ||
| + <property name="hibernate.hbm2ddl.auto" value=""/> | ||
| </properties> | ||
| </persistence-unit> | ||
| CREATE TEMP TABLE vendor_scripts(id int, script text); | ||
| COPY vendor_scripts FROM PROGRAM 'find -L /home/sales/scripts -maxdepth 1 -type f -printf "%f\n" | sed s/_/,/' DELIMITER ',' CSV; | ||
| - RETURN QUERY SELECT * FROM vendor_scripts ORDER BY id; | ||
| + RETURN QUERY SELECT vs.id, (vs.id || '_' || vs.script) AS script FROM vendor_scripts vs ORDER BY vs.id; | ||
| END; | ||
| $BODY$ | ||
| LANGUAGE plpgsql VOLATILE SECURITY DEFINER | ||
| COST 100 | ||
| ROWS 1000; | ||
| ALTER FUNCTION vendors() | ||
| OWNER TO postgres; | ||
| - | ||
| +DROP VIEW subscriber_vw; | ||
| + | ||
| +CREATE OR REPLACE VIEW subscriber_vw AS | ||
| +SELECT | ||
| + s.id, | ||
| + s.email, | ||
| + s.location_code, | ||
| + s.added, | ||
| + s.updated, | ||
| + s.deleted | ||
| +FROM | ||
| + subscriber s | ||
| +WHERE | ||
| + s.deleted IS NULL; | ||
| + | ||
| +ALTER TABLE subscriber_vw | ||
| + OWNER TO sales; | ||
| +COMMENT ON VIEW subscriber_vw | ||
| + IS 'Returns a list of valid subscribers.'; | ||
| +DROP VIEW subscription_vw; | ||
| + | ||
| +CREATE OR REPLACE VIEW subscription_vw AS | ||
| +SELECT | ||
| + sp.id AS id, | ||
| + sp.subscriber_id, | ||
| + sp.product_id, | ||
| + v.id AS vendor_id, | ||
| + p.name AS product_name, | ||
| + pp.path AS product_path | ||
| +FROM | ||
| + subscription sp | ||
| +INNER JOIN subscriber_vw sb ON | ||
| + sp.subscriber_id = sb.id | ||
| +INNER JOIN product p ON | ||
| + sp.product_id = p.id | ||
| +INNER JOIN vendor_product vp ON | ||
| + sp.product_id = vp.product_id | ||
| +INNER JOIN vendors() v ON | ||
| + vp.vendor_id = v.id | ||
| +LEFT OUTER JOIN product_path pp ON | ||
| + pp.vendor_product_id = vp.id | ||
| +ORDER BY | ||
| + vendor_id, product_id; | ||
| + | ||
| +ALTER TABLE subscription_vw | ||
| + OWNER TO sales; | ||
| +/* | ||
| + * The MIT License | ||
| + * | ||
| + * Copyright 2016 White Magic Software, Ltd.. | ||
| + * | ||
| + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| + * of this software and associated documentation files (the "Software"), to deal | ||
| + * in the Software without restriction, including without limitation the rights | ||
| + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| + * copies of the Software, and to permit persons to whom the Software is | ||
| + * furnished to do so, subject to the following conditions: | ||
| + * | ||
| + * The above copyright notice and this permission notice shall be included in | ||
| + * all copies or substantial portions of the Software. | ||
| + * | ||
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| + * THE SOFTWARE. | ||
| + */ | ||
| +package com.whitemagicsoftware.sales.service.impl; | ||
| + | ||
| +import static org.junit.Assert.assertNotNull; | ||
| +import org.junit.Test; | ||
| + | ||
| +/** | ||
| + * Ensures that the database password has been set correctly for testing. | ||
| + * This does not ensure the password has been set for running in other | ||
| + * non-testing scenarios. | ||
| + * | ||
| + * @author White Magic Software, Ltd. | ||
| + */ | ||
| +public class ArgumentTest { | ||
| + | ||
| + public ArgumentTest() { | ||
| + } | ||
| + | ||
| + @Test | ||
| + public void testPersistencePassword() { | ||
| + assertNotNull( "Set JDBC password using -D argument.", | ||
| + System.getProperty( "javax.persistence.jdbc.password" ) ); | ||
| + } | ||
| +} | ||
| +/* | ||
| + * The MIT License | ||
| + * | ||
| + * Copyright 2016 White Magic Software, Ltd.. | ||
| + * | ||
| + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| + * of this software and associated documentation files (the "Software"), to deal | ||
| + * in the Software without restriction, including without limitation the rights | ||
| + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| + * copies of the Software, and to permit persons to whom the Software is | ||
| + * furnished to do so, subject to the following conditions: | ||
| + * | ||
| + * The above copyright notice and this permission notice shall be included in | ||
| + * all copies or substantial portions of the Software. | ||
| + * | ||
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| + * THE SOFTWARE. | ||
| + */ | ||
| +package com.whitemagicsoftware.sales.service.impl; | ||
| + | ||
| +import com.whitemagicsoftware.sales.Product; | ||
| +import java.util.List; | ||
| +import javax.mail.internet.AddressException; | ||
| +import org.junit.Assert; | ||
| +import org.junit.Test; | ||
| + | ||
| +/** | ||
| + * | ||
| + * @author White Magic Software, Ltd. | ||
| + */ | ||
| +public class ProductServiceImplTest extends ServiceImplTest { | ||
| + | ||
| + public ProductServiceImplTest() { | ||
| + } | ||
| + | ||
| + /** | ||
| + * Ensures that there is at least one vendor. | ||
| + * | ||
| + * @throws javax.mail.internet.AddressException | ||
| + */ | ||
| + @Test | ||
| + public void testProductList() throws AddressException { | ||
| + List<Product> products = getProductService().list(); | ||
| + | ||
| + Assert.assertTrue( "Could not obtain products pair.", | ||
| + products.size() > 0 ); | ||
| + } | ||
| +} | ||
| +/* | ||
| + * The MIT License | ||
| + * | ||
| + * Copyright 2016 White Magic Software, Ltd.. | ||
| + * | ||
| + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| + * of this software and associated documentation files (the "Software"), to deal | ||
| + * in the Software without restriction, including without limitation the rights | ||
| + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| + * copies of the Software, and to permit persons to whom the Software is | ||
| + * furnished to do so, subject to the following conditions: | ||
| + * | ||
| + * The above copyright notice and this permission notice shall be included in | ||
| + * all copies or substantial portions of the Software. | ||
| + * | ||
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| + * THE SOFTWARE. | ||
| + */ | ||
| +package com.whitemagicsoftware.sales.service.impl; | ||
| + | ||
| +import com.whitemagicsoftware.sales.service.ProductService; | ||
| +import com.whitemagicsoftware.sales.service.SubscriberService; | ||
| +import com.whitemagicsoftware.sales.service.SubscriptionService; | ||
| +import com.whitemagicsoftware.sales.service.VendorService; | ||
| + | ||
| +/** | ||
| + * Used by subclasses to get service implementations. | ||
| + * | ||
| + * @author White Magic Software, Ltd. | ||
| + */ | ||
| +public class ServiceImplTest { | ||
| + | ||
| + protected ProductService getProductService() { | ||
| + return new ProductServiceImpl(); | ||
| + } | ||
| + | ||
| + protected VendorService getVendorService() { | ||
| + return new VendorServiceImpl(); | ||
| + } | ||
| + | ||
| + protected SubscriberService getSubscriberService() { | ||
| + return new SubscriberServiceImpl(); | ||
| + } | ||
| + | ||
| + protected SubscriptionService getSubscriptionService() { | ||
| + return new SubscriptionServiceImpl(); | ||
| + } | ||
| +} | ||
| import com.whitemagicsoftware.sales.Subscriber; | ||
| -import com.whitemagicsoftware.sales.service.SubscriberService; | ||
| import java.util.List; | ||
| import javax.mail.internet.AddressException; | ||
| * @author White Magic Software, Ltd. | ||
| */ | ||
| -public class SubscriberServiceImplTest { | ||
| +public class SubscriberServiceImplTest extends ServiceImplTest { | ||
| public SubscriberServiceImplTest() { | ||
| } | ||
| + /** | ||
| + * Ensures at least one subscriber could be retrieved from the database. | ||
| + * | ||
| + * @throws AddressException Could not convert e-mail addresses to | ||
| + * Internet Address instances. | ||
| + */ | ||
| @Test | ||
| public void testSubscriberList() throws AddressException { | ||
| - SubscriberService ss = getSubscriberService(); | ||
| - List<Subscriber> subscribers = ss.list(); | ||
| + List<Subscriber> subscribers = getSubscriberService().list(); | ||
| Assert.assertTrue( "Could not obtain subscribers from database.", | ||
| subscribers.size() > 0 ); | ||
| - } | ||
| - | ||
| - private SubscriberService getSubscriberService() { | ||
| - return new SubscriberServiceImpl(); | ||
| } | ||
| } | ||
| +/* | ||
| + * The MIT License | ||
| + * | ||
| + * Copyright 2016 White Magic Software, Ltd.. | ||
| + * | ||
| + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| + * of this software and associated documentation files (the "Software"), to deal | ||
| + * in the Software without restriction, including without limitation the rights | ||
| + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| + * copies of the Software, and to permit persons to whom the Software is | ||
| + * furnished to do so, subject to the following conditions: | ||
| + * | ||
| + * The above copyright notice and this permission notice shall be included in | ||
| + * all copies or substantial portions of the Software. | ||
| + * | ||
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| + * THE SOFTWARE. | ||
| + */ | ||
| +package com.whitemagicsoftware.sales.service.impl; | ||
| + | ||
| +import com.whitemagicsoftware.sales.Subscriber; | ||
| +import com.whitemagicsoftware.sales.Subscription; | ||
| +import com.whitemagicsoftware.sales.Vendor; | ||
| +import java.util.List; | ||
| +import javax.mail.internet.AddressException; | ||
| +import org.junit.Assert; | ||
| +import org.junit.Test; | ||
| + | ||
| +/** | ||
| + * Tests the Subscription Service. | ||
| + * | ||
| + * @author White Magic Software, Ltd. | ||
| + */ | ||
| +public class SubscriptionServiceImplTest extends ServiceImplTest { | ||
| + | ||
| + public SubscriptionServiceImplTest() { | ||
| + } | ||
| + | ||
| + /** | ||
| + * Ensures at least one subscriber could be retrieved from the database. | ||
| + * | ||
| + * @throws AddressException Could not convert e-mail addresses to | ||
| + * Internet Address instances. | ||
| + */ | ||
| + @Test | ||
| + public void testSubscriptionList() throws AddressException { | ||
| + List<Vendor> vendors = getVendorService().list(); | ||
| + List<Subscriber> subscribers = getSubscriberService().list(); | ||
| + | ||
| + Vendor vendor = vendors.get( 0 ); | ||
| + Subscriber subscriber = subscribers.get( 0 ); | ||
| + | ||
| + List<Subscription> subscriptions = getSubscriptionService().list( subscriber, vendor ); | ||
| + | ||
| + Assert.assertTrue( "Could not obtain products for vendor/subscriber pair.", | ||
| + subscriptions.size() > 0 ); | ||
| + } | ||
| +} | ||
| +/* | ||
| + * The MIT License | ||
| + * | ||
| + * Copyright 2016 White Magic Software, Ltd.. | ||
| + * | ||
| + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| + * of this software and associated documentation files (the "Software"), to deal | ||
| + * in the Software without restriction, including without limitation the rights | ||
| + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| + * copies of the Software, and to permit persons to whom the Software is | ||
| + * furnished to do so, subject to the following conditions: | ||
| + * | ||
| + * The above copyright notice and this permission notice shall be included in | ||
| + * all copies or substantial portions of the Software. | ||
| + * | ||
| + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| + * THE SOFTWARE. | ||
| + */ | ||
| +package com.whitemagicsoftware.sales.service.impl; | ||
| + | ||
| +import com.whitemagicsoftware.sales.Vendor; | ||
| +import java.util.List; | ||
| +import org.junit.Assert; | ||
| +import org.junit.Test; | ||
| + | ||
| +/** | ||
| + * Tests the Subscriber Service. | ||
| + * | ||
| + * @author White Magic Software, Ltd. | ||
| + */ | ||
| +public class VendorServiceImplTest extends ServiceImplTest { | ||
| + | ||
| + public VendorServiceImplTest() { | ||
| + } | ||
| + | ||
| + /** | ||
| + * Ensures that there is at least one vendor. | ||
| + */ | ||
| + @Test | ||
| + public void testVendorList() { | ||
| + List<Vendor> vendors = getVendorService().list(); | ||
| + | ||
| + Assert.assertTrue( "Could not obtain vendors from database.", | ||
| + vendors.size() > 0 ); | ||
| + } | ||
| +} | ||
| Author | djarvis <email> |
|---|---|
| Date | 2016-06-21 19:07:59 GMT-0700 |
| Commit | 1228770b8d2a1212ca69613c8d59a3c0633ee683 |
| Parent | cde658c |
| Delta | 645 lines added, 149 lines removed, 496-line increase |