Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/sales.git
src/main/java/com/whitemagicsoftware/sales/BusinessEntity.java
@MappedSuperclass
public class BusinessEntity implements Serializable {
-
+
@Id
private int id;
/**
* Full name, first name, last name, etc.
*/
@Transient
private EntityName entityName;
-
+
public BusinessEntity() {
}
-
+
protected void setId( int id ) {
this.id = id;
return this.id;
}
-
+
protected String getName() {
return getEntityName().getName();
}
-
+
protected void setName( String name ) {
setEntityName( name );
* @return A non-null instance.
*/
- protected EntityName getEntityName() {
+ protected synchronized EntityName getEntityName() {
+ if( this.entityName == null ) {
+ this.entityName = new EntityName( "" );
+ }
+
return this.entityName;
}
-
+
protected String nullSafe( String s ) {
return s == null ? "" : s;
*/
protected static abstract class Builder<T extends BusinessEntity, B extends Builder<T, B>> {
-
+
private final T object;
private final B builder;
-
+
protected abstract T createObject();
-
+
protected abstract B getBuilder();
-
+
@SuppressWarnings( "OverridableMethodCallInConstructor" )
public Builder() {
this.object = createObject();
this.builder = getBuilder();
}
-
+
public B withId( int id ) {
getObject().setId( id );
return getBuilder();
}
-
+
public B withEntityName( EntityName entityName ) {
getObject().setEntityName( entityName );
return getBuilder();
}
-
+
public B withName( String name ) {
withEntityName( new EntityName( name ) );
return getBuilder();
}
-
+
public T build() {
return getObject();
}
-
+
protected T getObject() {
return this.object;
src/main/java/com/whitemagicsoftware/sales/Main.java
package com.whitemagicsoftware.sales;
+import static com.whitemagicsoftware.sales.SystemProperty.APP_NOTIFY_CREDENTIALS_PASSWORD;
+import static com.whitemagicsoftware.sales.SystemProperty.APP_NOTIFY_CREDENTIALS_SENDER_ADDR;
+import static com.whitemagicsoftware.sales.SystemProperty.APP_NOTIFY_CREDENTIALS_SENDER_NAME;
+import static com.whitemagicsoftware.sales.SystemProperty.APP_NOTIFY_CREDENTIALS_USERNAME;
import com.whitemagicsoftware.sales.service.NotifyService;
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 com.whitemagicsoftware.sales.service.impl.DefaultNotifyService;
+import com.whitemagicsoftware.sales.service.impl.DefaultProductService;
+import com.whitemagicsoftware.sales.service.impl.DefaultSubscriberService;
+import com.whitemagicsoftware.sales.service.impl.DefaultSubscriptionService;
+import com.whitemagicsoftware.sales.service.impl.DefaultVendorService;
import java.io.File;
import java.io.IOException;
*/
public class Main {
-
- private final static String DIRECTORY_PREFIX = "scrape";
private final static int DEFAULT_STRING_SIZE = 8192;
private void Main() {
}
/**
* Iterates over all the subscribers to notify them of when their
- * subscriptions are ready.
+ * subscriptions are ready. The list of subscriptions must be sorted first by
+ * subscriber then by vendor.
*
- * @throws Exception
+ * @throws Exception Failed to process the subscriptions.
*/
private void process() throws Exception {
- for( Subscriber subscriber : getSubscribers() ) {
- try {
- notify( subscriber, process( subscriber ) );
- } catch( Exception e ) {
- notify( e );
- }
- }
- }
-
- /**
- * Iterates over all the vendors for each subscriber
- *
- * @param subscriber
- *
- * @return
- *
- * @throws Exception
- */
- private String process( Subscriber subscriber )
- throws Exception {
- StringBuilder result = new StringBuilder( DEFAULT_STRING_SIZE );
+ StringBuilder message = new StringBuilder( DEFAULT_STRING_SIZE );
- for( Vendor vendor : getVendors() ) {
- result.append( process( subscriber, vendor ) );
- }
+ // Current and previous to detect when a notification must be sent.
+ Subscriber cSubscriber = null;
+ Subscriber pSubscriber = null;
+ Vendor cVendor;
+ Vendor pVendor = null;
- return result.toString();
- }
+ for( Subscription subscription : getSubscriptions() ) {
+ cSubscriber = subscription.getSubscriber();
+ cVendor = subscription.getVendor();
- private String process( Subscriber subscriber, Vendor vendor )
- throws Exception {
- StringBuilder result = new StringBuilder( DEFAULT_STRING_SIZE );
+ // There won't be a message to send on the first iteration, even
+ // though this test evaluates to true.
+ if( !cSubscriber.equals( pSubscriber ) ) {
+ // Let the message fly, assuming it exists.
+ notify( pSubscriber, message );
- // Include the vendor name on the first products loop iteration.
- boolean includeVendorName = true;
+ // Force inclusion of the vendor name in the message.
+ pVendor = null;
- for( Subscription subscription : getSubscriptions( subscriber, vendor ) ) {
- Scraper scraper = getScraper( vendor );
+ // Start a new message.
+ message.setLength( 0 );
+ }
Product product = subscription.getProduct();
+ Scraper scraper = createScraper( cVendor );
- scraper.addVariableToContext( "vendor_name_include", includeVendorName );
- scraper.addVariableToContext( "location_code", subscriber.getLocationCode() );
+ scraper.addVariableToContext( "include_vendor_name",
+ !cVendor.equals( pVendor ) );
+ scraper.addVariableToContext( "location_code",
+ cSubscriber.getLocationCode() );
scraper.addVariableToContext( "product_name", product.getName() );
scraper.addVariableToContext( "product_path", product.getUrlPath() );
scraper.execute();
- Variable message = scraper.getContext().getVar( "message_body" );
- result.append( message.toString() );
+ Variable body = scraper.getContext().getVar( "message_body" );
+ message.append( body.toString() );
- // Presumably, the template added the vendor's name to deliniate its
- // products from the other vendors' products.
- includeVendorName = false;
+ // On the next iteration, if the previous and current subscribers are
+ // different, then send the message to the previous subscriber.
+ pSubscriber = cSubscriber;
+ pVendor = cVendor;
}
- return result.toString();
+ // The last iteration through the loop won't send a message.
+ notify( cSubscriber, message );
}
/**
* Uses the notify service to notify the subscriber of the given message
* content.
*
* @param subscriber The person to notify.
- * @param message
+ * @param message The message to deliver, cannot be null.
*
- * @throws Exception
+ * @throws Exception Could not deliver the message.
*/
- private void notify( Subscriber subscriber, String message ) throws Exception {
- if( !empty( message ) ) {
- getNotifyService().notify( subscriber.getAddress(), "Subject", message );
+ private void notify( Subscriber subscriber, StringBuilder message )
+ throws Exception {
+ assert message != null;
+
+ notify( subscriber, message.toString() );
+ }
+
+ /**
+ * Uses the notify service to notify the subscriber of the given message
+ * content. If the message is empty (or contains only whitespace), this will
+ * not transmit a notification.
+ *
+ * @param subscriber The person to notify.
+ * @param message The message to deliver, can be empty or null.
+ *
+ * @throws Exception Could not deliver the message.
+ */
+ private void notify( Subscriber subscriber, String message )
+ throws Exception {
+ if( subscriber != null && !empty( message ) ) {
+ createNotifyService().notify(
+ subscriber.getAddress(), "Subject", message
+ );
}
}
- private void notify( Exception e ) {
- getNotifyService().notify( e );
+ /**
+ * Sends an e-mail on any exception.
+ *
+ * @param e The unexpected problem, cannot be null.
+ */
+ private static void notify( Exception e ) {
+ assert e != null;
+
+ createNotifyService().notify( e );
}
/**
* Answers whether the string is null or empty or contains only whitespace.
*
- * @param s The string to validate.
+ * @param s The string to validate, can be null.
*
- * @return true The string has no content. F
+ * @return true The string has no content.
*/
- private boolean empty( String s ) {
- return s == null || s.trim().length() == 0;
+ private static boolean empty( final String s ) {
+ return s == null || s.trim().isEmpty();
}
/**
* Returns a scraper for a given resource (configuration).
*
- * @param resource Name of script file to execute.
+ * @param vendor Non-null instance.
*
- * @return A Scraper that can extract data.
+ * @return A Scraper that can extract data from the vendor's site (or page).
*/
- private Scraper getScraper( Vendor vendor ) throws IOException {
+ private Scraper createScraper( Vendor vendor ) throws IOException {
String resource = "scripts/" + vendor.getScriptName();
final ScraperConfiguration config = getScraperConfiguration( resource );
private SubscriberService getSubscriberService() {
- return new SubscriberServiceImpl();
+ return new DefaultSubscriberService();
}
private VendorService getVendorService() {
- return new VendorServiceImpl();
+ return new DefaultVendorService();
}
private ProductService getProductService() {
- return new ProductServiceImpl();
- }
-
- private NotifyService getNotifyService() {
- return new NotifyServiceImpl();
+ return new DefaultProductService();
}
private SubscriptionService getSubscriptionService() {
- return new SubscriptionServiceImpl();
+ return new DefaultSubscriptionService();
}
}
- private List<Subscription> getSubscriptions( Subscriber subscriber, Vendor vendor ) {
- return getSubscriptionService().list( subscriber, vendor );
+ /**
+ * Returns a list of subscriptions, sorted by subscriber then by vendor.
+ *
+ * @return A sorted list of subscriptions.
+ */
+ private List<Subscription> getSubscriptions() {
+ return getSubscriptionService().list();
+ }
+
+ private static NotifyService createNotifyService() {
+ return new DefaultNotifyService();
+ }
+
+ private static void showEnvironmentVariables() {
+ System.out.println( APP_NOTIFY_CREDENTIALS_USERNAME.getValue() );
+ System.out.println( APP_NOTIFY_CREDENTIALS_PASSWORD.getValue() );
+ System.out.println( APP_NOTIFY_CREDENTIALS_SENDER_ADDR.getValue() );
+ System.out.println( APP_NOTIFY_CREDENTIALS_SENDER_NAME.getValue() );
}
/**
- * Run with <code>-Djavax.persistence.jdbc.password=</code> set to the
- * database password.
+ * See the SystemProperty class for values that must be set prior to running
+ * the program.
*
* @param args Unused.
- *
- * @throws Exception Failed to notify subscribers of product sales.
*/
- public static void main( String args[] ) throws Exception {
- new Main().process();
+ public static void main( String args[] ) {
+ try {
+ new Main().process();
+ } catch( Exception e ) {
+ notify( e );
+ }
}
}
src/main/java/com/whitemagicsoftware/sales/Subscriber.java
import java.util.Date;
+import java.util.Objects;
import javax.mail.Address;
import javax.mail.internet.AddressException;
private Address address;
- /* Required by JPA. */
+ /* Email address transmogrified into the Address instance. */
@Column( name = "email" )
private String email;
/**
* Returns the e-mail address associated with the subscriber.
- *
+ *
* @return A non-null, possibly empty, instance.
*/
private synchronized String getEmail() {
- return nullSafe(this.email);
+ return nullSafe( this.email );
}
/**
* Used by the builder to set the address.
- *
- * @param address
+ *
+ * @param address
*/
protected void setAddress( Address address ) {
protected String getLocationCode() {
- return nullSafe(this.locationCode);
+ return nullSafe( this.locationCode );
}
protected Address createAddress() throws AddressException {
return new InternetAddress( getEmail() );
+ }
+
+ /**
+ * Returns true iff the internal address matches the given address.
+ *
+ * @param address The addresses to compare against.
+ *
+ * @return true That address and this address match.
+ */
+ public boolean addressEquals( Address address ) {
+ boolean result = false;
+
+ try {
+ getAddress().equals( address );
+ result = true;
+ } catch( AddressException ex ) {
+ // Not equal at all.
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns true iff the internal location code matches the given code.
+ *
+ * @param locationCode The location code to compare against.
+ *
+ * @return true That locationCode and this locationCode match.
+ */
+ public boolean locationCodeEquals( String locationCode ) {
+ return getLocationCode().equals( locationCode );
+ }
+
+ /**
+ * Returns true iff this is the same subscriber as the given object.
+ *
+ * @param o The object to compare against.
+ * @return true The given object is equal to this instance.
+ */
+ @Override
+ public boolean equals( Object o ) {
+ if( this != o ) {
+ if( o != null & o.getClass() == this.getClass() ) {
+ try {
+ Subscriber that = (Subscriber)o;
+ return that.addressEquals( this.getAddress() )
+ && that.locationCodeEquals( this.getLocationCode() );
+ } catch( AddressException e ) {
+ }
+ }
+ }
+
+ // Same object reference.
+ return true;
+ }
+
+ /**
+ * Hashes the address and location code.
+ *
+ * @return Hashed value for this instance.
+ */
+ @Override
+ public int hashCode() {
+ int hash = 101;
+ hash = 53 * hash + Objects.hashCode( this.address );
+ hash = 53 * hash + Objects.hashCode( this.locationCode );
+ return hash;
}
src/main/java/com/whitemagicsoftware/sales/Subscription.java
package com.whitemagicsoftware.sales;
-import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
+ * Associates a subscriber with a product and vendor.
*
* @author White Magic Software, Ltd.
@OneToOne()
@JoinColumn( name = "product_id", referencedColumnName = "id" )
- private Product product;
-
- @Column( name = "subscriber_id", insertable = false, updatable = false, nullable = false )
- private int subscriberId;
+ private Product product = new Product.Builder().build();
- @Column( name = "vendor_id", insertable = false, updatable = false, nullable = false )
- private int vendorId;
+ @OneToOne()
+ @JoinColumn( name = "subscriber_id", referencedColumnName = "id" )
+ private Subscriber subscriber = new Subscriber.Builder().build();
- @Column( name = "product_id", insertable = false, updatable = false, nullable = false )
- private int productId;
+ @OneToOne()
+ @JoinColumn( name = "vendor_id", referencedColumnName = "id" )
+ private Vendor vendor = new Vendor.Builder().build();
+ /**
+ * Default (empty) constructor.
+ */
public Subscription() {
}
- public void setProduct( Product product ) {
- this.product = product;
+ /**
+ * Called to set the product for this subscription.
+ *
+ * @param product The product associated with a subscriber (and vendor).
+ */
+ protected void setProduct( Product product ) {
+ if( product != null ) {
+ this.product = product;
+ }
}
+ /**
+ * Returns the product associated with a subscriber/vendor pair.
+ *
+ * @return A non-null product instance.
+ */
protected Product getProduct() {
return this.product;
- }
-
- protected int getSubscriberId() {
- return this.subscriberId;
- }
-
- protected void setSubscriberId( int subscriberId ) {
- this.subscriberId = subscriberId;
}
- protected int getVendorId() {
- return this.vendorId;
+ /**
+ * Returns the subscriber for this vendor/product pair.
+ *
+ * @return A non-null subscriber instance.
+ */
+ protected Subscriber getSubscriber() {
+ return this.subscriber;
}
- protected void setVendorId( int vendorId ) {
- this.vendorId = vendorId;
+ /**
+ * Sets the subscriber for this vendor/product pair.
+ *
+ * @param subscriber A subscriber to associate with a vendor/product.
+ */
+ protected void setSubscriber( Subscriber subscriber ) {
+ if( subscriber != null ) {
+ this.subscriber = subscriber;
+ }
}
- protected int getProductId() {
- return this.productId;
+ /**
+ * Associates a vendor with a subscriber/product pair.
+ *
+ * @param vendor The vendor to associate with the subscriber/product pair.
+ */
+ protected void setVendor( Vendor vendor ) {
+ if( vendor != null ) {
+ this.vendor = vendor;
+ }
}
- protected void setProductId( int productId ) {
- this.productId = productId;
+ /**
+ * Returns the vendor with this subscriber/product pair.
+ *
+ * @return A non-null vendor instance.
+ */
+ protected Vendor getVendor() {
+ return this.vendor;
}
}
src/main/java/com/whitemagicsoftware/sales/Vendor.java
package com.whitemagicsoftware.sales;
+import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
protected String getScriptName() {
return nullSafe( this.scriptName );
+ }
+
+ /**
+ * Returns true iff the given script name matches this script name.
+ *
+ * @param scriptName The script name to compare against.
+ * @return true The script names (and hence vendors) are equal.
+ */
+ public boolean scriptNameEquals( String scriptName ) {
+ return getScriptName().equals( scriptName );
+ }
+
+ /**
+ * Returns true iff this is the same vendor as the given object.
+ *
+ * @param o The object to compare against.
+ *
+ * @return true The given object is equal to this instance.
+ */
+ @Override
+ public boolean equals( Object o ) {
+ if( this != o ) {
+ if( o != null & o.getClass() == this.getClass() ) {
+ Vendor that = (Vendor)o;
+ return that.scriptNameEquals( this.getScriptName() );
+ }
+ }
+
+ // Same object reference.
+ return true;
+ }
+
+ /**
+ * Returns a hashed value for this vendor.
+ *
+ * @return A unique integer value.
+ */
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 29 * hash + Objects.hashCode( getScriptName() );
+ return hash;
}
src/main/java/com/whitemagicsoftware/sales/service/SubscriptionService.java
package com.whitemagicsoftware.sales.service;
-import com.whitemagicsoftware.sales.Subscriber;
import com.whitemagicsoftware.sales.Subscription;
-import com.whitemagicsoftware.sales.Vendor;
import java.util.List;
/**
* Returns a list of products 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 );
+ public List<Subscription> list();
}
src/main/java/com/whitemagicsoftware/sales/service/impl/DefaultNotifyService.java
+/*
+ * 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.notify.ElasticEmailTransport;
+import com.whitemagicsoftware.notify.HttpTransport;
+import com.whitemagicsoftware.notify.TextHtmlMultipart;
+import static com.whitemagicsoftware.sales.SystemProperty.*;
+import com.whitemagicsoftware.sales.service.NotifyService;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Properties;
+import javax.mail.Address;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import org.pegdown.PegDownProcessor;
+
+/**
+ * Responsible for notifying a recipient of a message. The message should be
+ * written in Markdown format, which is then converted internally to HTML.
+ *
+ * @author White Magic Software, Ltd.
+ */
+public class DefaultNotifyService extends DefaultService
+ implements NotifyService {
+
+ private Session session;
+
+ public DefaultNotifyService() {
+ }
+
+ /**
+ * Send a notification to the given address.
+ *
+ * @param recipient The address to receive the notification.
+ * @param subject The message subject line.
+ * @param markdown The message body.
+ *
+ * @throws MessagingException Could not send the message.
+ * @throws UnsupportedEncodingException Could not create the message in a
+ * given encoding.
+ */
+ @Override
+ public void notify( Address recipient, String subject, String markdown )
+ throws MessagingException, UnsupportedEncodingException {
+ String textBody = markdown;
+ String htmlBody = toHtml( markdown );
+
+ Message message = createMessage( recipient, subject );
+ message.setContent( new TextHtmlMultipart( textBody, htmlBody ) );
+ send( message );
+ }
+
+ /**
+ * Sends a notification to the alert contact when an exception occurs.
+ *
+ * @param e The exception that was not handled while notifying subscribers.
+ */
+ @Override
+ public void notify( Exception e ) {
+ try(
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter( sw ) ) {
+ Message message = createMessage( getAlertContact(), getSubject( e ) );
+
+ // Include the stack trace in the message body.
+ e.printStackTrace( pw );
+
+ message.setText( sw.toString() );
+ send( message );
+ } catch( Exception ex ) {
+ // TODO: Log this.
+ }
+ }
+
+ /**
+ * TODO: Convert from Markdown to HTML (using PegDown?).
+ *
+ * @param markdown The markdown to HTML-ify.
+ *
+ * @return The given markdown as an HTML fragment.s
+ */
+ private String toHtml( String markdown ) {
+ return new PegDownProcessor().markdownToHtml( markdown );
+ }
+
+ private String getUsername() {
+ return APP_NOTIFY_CREDENTIALS_USERNAME.getValue();
+ }
+
+ private String getPassword() {
+ return APP_NOTIFY_CREDENTIALS_PASSWORD.getValue();
+ }
+
+ private String getSenderAddress() {
+ return APP_NOTIFY_CREDENTIALS_SENDER_ADDR.getValue();
+ }
+
+ private String getSenderName() {
+ return APP_NOTIFY_CREDENTIALS_SENDER_NAME.getValue();
+ }
+
+ /**
+ * Creates a new InternetAddress based on the System property for the sender
+ * address and sender name.
+ *
+ * @return A non-null InternetAddress instance.
+ *
+ * @throws UnsupportedEncodingException Couldn't convert the address to an
+ * e-mail address.
+ */
+ private Address createSender() throws UnsupportedEncodingException {
+ return new InternetAddress( getSenderAddress(), getSenderName() );
+ }
+
+ private void send( Message message ) throws MessagingException {
+ HttpTransport transport = getTransport();
+ transport.sendMessage( message, message.getAllRecipients() );
+ transport.close();
+ }
+
+ private HttpTransport getTransport() {
+ HttpTransport transport = new ElasticEmailTransport( getSession() );
+ transport.setAuthentication( getUsername(), getPassword() );
+
+ // TODO: Track the result token for the HTTP request?
+// transport.addTransportListener(new TransportTestListener());
+ return transport;
+
+ }
+
+ /**
+ * Convenience method to a new message with the sender, recipient, and subject
+ * filled in.
+ *
+ * @param recipient Destination address for the message.
+ * @param subject Subject line.
+ *
+ * @return A new Message instance, never null.
+ *
+ * @throws MessagingException Could not create the message instance.
+ * @throws UnsupportedEncodingException The address was not properly
+ * formatted.
+ */
+ private Message createMessage( Address recipient, String subject )
+ throws MessagingException, UnsupportedEncodingException {
+ Message message = new MimeMessage( getSession() );
+
+ message.setFrom( createSender() );
+ message.addRecipient( Message.RecipientType.TO, recipient );
+ message.setSubject( subject );
+ return message;
+ }
+
+ /**
+ * Returns a lazily initialized session instance.
+ *
+ * @return A new Session instance, never null.
+ */
+ private synchronized Session getSession() {
+ if( this.session == null ) {
+ this.session = Session.getInstance( new Properties() );
+ }
+
+ // Make sure to always use the same instance of session, pedant.
+ return this.session;
+ }
+
+ /**
+ * Returns the recipient address to contact in case of a breakage.
+ *
+ * @return A non-null InternetAddress.
+ *
+ * @throws AddressException Could not create an InternetAddress from the
+ * APPLICATION_FAILURE_CONTACT property.
+ */
+ private Address getAlertContact() throws AddressException {
+ return new InternetAddress( APP_NOTIFY_FAILURE_ADDR.getValue() );
+ }
+
+ /**
+ * Returns a formatted subject line.
+ *
+ * @param e The exception that happened to trigger a notification to support.
+ *
+ * @return A formatted String, never null.
+ */
+ private String getSubject( Exception e ) {
+ return "[Error] " + e.getMessage();
+ }
+}
src/main/java/com/whitemagicsoftware/sales/service/impl/DefaultProductService.java
+/*
+ * 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 com.whitemagicsoftware.sales.service.ProductService;
+import java.util.List;
+
+/**
+ * Responsible for obtaining a list of all products.
+ *
+ * @author White Magic Software, Ltd.
+ */
+public class DefaultProductService extends DefaultService<Product>
+ implements ProductService {
+
+ /**
+ * Returns all the products.
+ *
+ * @return A list of products, possibly empty, never null.
+ */
+ @Override
+ public List<Product> list() {
+ return getResultList( Product.class );
+ }
+}
src/main/java/com/whitemagicsoftware/sales/service/impl/DefaultService.java
+/*
+ * 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 com.whitemagicsoftware.sales.SystemProperty.PERSISTENCE_PASSWORD_PROPERTY;
+import com.whitemagicsoftware.sales.service.Service;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+/**
+ * Superclass to all services.
+ *
+ * @author White Magic Software, Ltd.
+ * @param <T> The type of classes this service returns.
+ */
+public abstract class DefaultService<T> implements Service {
+
+ /**
+ * Only one instance is allowed.
+ */
+ private static EntityManagerFactory ENTITY_MANAGER_FACTORY;
+
+ private EntityManager entityManager;
+
+ /**
+ * Returns the list of all entries in the database for the given class type.
+ *
+ * @param clazz The class that represents an entity that has rows in a table
+ * within a database.
+ *
+ * @return The instances of the class populated with data from the database.
+ */
+ protected List<T> getResultList( Class<T> clazz ) {
+ CriteriaQuery<T> cq = createQuery( clazz );
+ Root<T> root = cq.from( clazz );
+ CriteriaQuery<T> all = cq.select( root );
+
+ List<T> result = createQuery( all ).getResultList();
+
+ closeEntityManager();
+
+ return result;
+ }
+
+ protected synchronized EntityManager getEntityManager() {
+ if( this.entityManager == null ) {
+ this.entityManager = getEntityManagerFactory().createEntityManager();
+ }
+
+ return this.entityManager;
+ }
+
+ private void closeEntityManager() {
+ getEntityManager().close();
+ }
+
+ private synchronized EntityManagerFactory getEntityManagerFactory() {
+ if( ENTITY_MANAGER_FACTORY == null ) {
+ ENTITY_MANAGER_FACTORY = createEntityManagerFactory();
+ }
+
+ return ENTITY_MANAGER_FACTORY;
+ }
+
+ private EntityManagerFactory createEntityManagerFactory() {
+ return Persistence.createEntityManagerFactory( getPersistenceUnitName(),
+ createPersistenceProperties() );
+ }
+
+ protected CriteriaBuilder getCriteriaBuilder() {
+ return getEntityManager().getCriteriaBuilder();
+ }
+
+ 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 );
+ }
+
+ private Map<String, String> createPersistenceProperties() {
+ Map<String, String> result = new HashMap<>();
+ result.put(
+ PERSISTENCE_PASSWORD_PROPERTY.getKey(),
+ PERSISTENCE_PASSWORD_PROPERTY.getValue() );
+
+ return result;
+ }
+
+ private String getPersistenceUnitName() {
+ return "SALES";
+ }
+
+ /**
+ * Returns the empty string if the given string is null.
+ *
+ * @param s The string to un-nullify.
+ *
+ * @return s or "" if s is null.
+ */
+ private String nullSafe( String s ) {
+ return s == null ? "" : s;
+ }
+}
src/main/java/com/whitemagicsoftware/sales/service/impl/DefaultSubscriberService.java
+/*
+ * 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.service.SubscriberService;
+import java.util.List;
+import javax.mail.internet.AddressException;
+
+/**
+ * Responsible for obtaining a list of all subscribers.
+ *
+ * @author White Magic Software, Ltd.
+ */
+public class DefaultSubscriberService extends DefaultService<Subscriber>
+ implements SubscriberService {
+
+ /**
+ * Returns all the subscribers.
+ *
+ * @return A list of subscribers, possibly empty, never null.
+ */
+ @Override
+ public List<Subscriber> list() throws AddressException {
+ return getResultList( Subscriber.class );
+ }
+}
src/main/java/com/whitemagicsoftware/sales/service/impl/DefaultSubscriptionService.java
+/*
+ * 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.Subscription;
+import com.whitemagicsoftware.sales.service.SubscriptionService;
+import java.util.List;
+
+/**
+ * Responsible for obtaining a list of all subscriptions.
+ *
+ * @author White Magic Software, Ltd.
+ */
+public class DefaultSubscriptionService extends DefaultService<Subscription> implements SubscriptionService {
+
+ /**
+ * Returns all the subscriptions.
+ *
+ * @return A list of subscriptions, possibly empty, never null.
+ */
+ @Override
+ public List<Subscription> list() {
+ return getResultList( Subscription.class );
+ }
+}
src/main/java/com/whitemagicsoftware/sales/service/impl/DefaultVendorService.java
+/*
+ * 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 com.whitemagicsoftware.sales.service.VendorService;
+import java.util.List;
+
+/**
+ * Responsible for obtaining a list of all vendors.
+ *
+ * @author White Magic Software, Ltd.
+ */
+public class DefaultVendorService extends DefaultService<Vendor>
+ implements VendorService {
+
+ /**
+ * Returns all the vendors.
+ *
+ * @return A list of vendors, possibly empty, never null.
+ */
+ @Override
+ public List<Vendor> list() {
+ return getResultList( Vendor.class );
+ }
+}
src/main/java/com/whitemagicsoftware/sales/service/impl/NotifyServiceImpl.java
-/*
- * 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 com.whitemagicsoftware.notify.Credentials.ALERT_CONTACT;
-import static com.whitemagicsoftware.notify.Credentials.PASSWORD;
-import static com.whitemagicsoftware.notify.Credentials.SENDER;
-import static com.whitemagicsoftware.notify.Credentials.SENDER_NAME;
-import static com.whitemagicsoftware.notify.Credentials.USERNAME;
-import com.whitemagicsoftware.notify.ElasticEmailTransport;
-import com.whitemagicsoftware.notify.HttpTransport;
-import com.whitemagicsoftware.notify.TextHtmlMultipart;
-import com.whitemagicsoftware.sales.service.NotifyService;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.util.Properties;
-import javax.mail.Address;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-import org.pegdown.PegDownProcessor;
-
-/**
- * @author White Magic Software, Ltd.
- */
-public class NotifyServiceImpl extends ServiceImpl
- implements NotifyService {
-
- private Session session;
-
- public NotifyServiceImpl() {
- }
-
- @Override
- public void notify( Address recipient, String subject, String markdown )
- throws MessagingException, UnsupportedEncodingException {
- String textBody = markdown;
- String htmlBody = toHtml( markdown );
-
- Message message = createMessage( recipient, subject );
- message.setContent( new TextHtmlMultipart( textBody, htmlBody ) );
- send( message );
- }
-
- @Override
- public void notify( Exception e ) {
- try(
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter( sw ) ) {
- Message message = createMessage(
- ALERT_CONTACT.asAddress(),
- "[Error] " + e.getMessage() );
-
- e.printStackTrace( pw );
-
- message.setText( sw.toString() );
- send( message );
- } catch( Exception ex ) {
- // TODO: Log this.
- }
- }
-
- /**
- * TODO: Convert from Markdown to HTML (using PegDown?).
- *
- * @param markdown The markdown to HTML-ify.
- *
- * @return The given markdown as an HTML fragment.s
- */
- private String toHtml( String markdown ) {
- return new PegDownProcessor().markdownToHtml( markdown );
- }
-
- /**
- * Returns an authenticated transport.
- *
- * @param session Session to associate with the transport.
- *
- * @return A non-null instance.
- */
- private String getUsername() {
- return USERNAME.toString();
- }
-
- private String getPassword() {
- return PASSWORD.toString();
- }
-
- private String getSenderAddress() {
- return SENDER.toString();
- }
-
- private String getSenderName() {
- return SENDER_NAME.toString();
- }
-
- private Address getSender() throws UnsupportedEncodingException {
- return new InternetAddress( getSenderAddress(), getSenderName() );
- }
-
- private void send( Message message ) throws MessagingException {
- HttpTransport transport = getTransport();
- transport.sendMessage( message, message.getAllRecipients() );
- transport.close();
- }
-
- private HttpTransport getTransport() {
- HttpTransport transport = new ElasticEmailTransport( getSession() );
- transport.setAuthentication( getUsername(), getPassword() );
-
- // TODO: Track the result token for the HTTP request?
-// transport.addTransportListener(new TransportTestListener());
- return transport;
-
- }
-
- /**
- * Convenience method to a new message with the sender, recipient, and subject
- * filled in.
- *
- * @param recipient Destination address for the message.
- * @param subject Subject line.
- *
- * @return A new Message instance, never null.
- *
- * @throws MessagingException Could not create the message instance.
- * @throws UnsupportedEncodingException The address was not properly
- * formatted.
- */
- private Message createMessage( Address recipient, String subject )
- throws MessagingException, UnsupportedEncodingException {
- Message message = new MimeMessage( getSession() );
-
- message.setFrom( getSender() );
- message.addRecipient( Message.RecipientType.TO, recipient );
- message.setSubject( subject );
- return message;
- }
-
- /**
- * Returns a lazily initialized session instance.
- *
- * @return A new Session instance, never null.
- */
- private synchronized Session getSession() {
- if( this.session == null ) {
- this.session = Session.getInstance( new Properties() );
- }
-
- // Make sure to always use the same instance of session, pedant.
- return this.session;
- }
-}
src/main/java/com/whitemagicsoftware/sales/service/impl/ProductServiceImpl.java
-/*
- * 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 com.whitemagicsoftware.sales.service.ProductService;
-import java.util.List;
-
-/**
- * @author White Magic Software, Ltd.
- */
-public class ProductServiceImpl extends ServiceImpl<Product>
- implements ProductService {
-
- @Override
- public List<Product> list() {
- return getResultList( Product.class );
- }
-}
src/main/java/com/whitemagicsoftware/sales/service/impl/ServiceImpl.java
-/*
- * 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.Service;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
-import javax.persistence.TypedQuery;
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Root;
-
-/**
- * Superclass to all services.
- *
- * @author White Magic Software, Ltd.
- * @param <T> The type of classes this service returns.
- */
-public abstract class ServiceImpl<T> implements Service {
-
- /**
- * 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";
-
- /**
- * Returns the list of all entries in the database for the given class type.
- *
- * @param clazz The class that represents an entity that has rows in a table
- * within a database.
- *
- * @return The instances of the class populated with data from the database.
- */
- protected List<T> getResultList( Class<T> clazz ) {
- CriteriaQuery<T> cq = createQuery( clazz );
- Root<T> root = cq.from( clazz );
- CriteriaQuery<T> all = cq.select( root );
-
- List<T> result = createQuery( all ).getResultList();
-
- closeEntityManager();
-
- return result;
- }
-
- protected synchronized EntityManager getEntityManager() {
- if( this.entityManager == null ) {
- this.entityManager = getEntityManagerFactory().createEntityManager();
- }
-
- return this.entityManager;
- }
-
- private void closeEntityManager() {
- getEntityManager().close();
- }
-
- private synchronized EntityManagerFactory getEntityManagerFactory() {
- if( ENTITY_MANAGER_FACTORY == null ) {
- ENTITY_MANAGER_FACTORY = createEntityManagerFactory();
- }
-
- return ENTITY_MANAGER_FACTORY;
- }
-
- private EntityManagerFactory createEntityManagerFactory() {
- return Persistence.createEntityManagerFactory( getPersistenceUnitName(),
- getPersistenceProperties() );
- }
-
- protected CriteriaBuilder getCriteriaBuilder() {
- return getEntityManager().getCriteriaBuilder();
- }
-
- 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 );
- }
-
- private Map getPersistenceProperties() {
- Map result = new HashMap();
- result.put( PERSISTENCE_PASSWORD_PROPERTY, getPersistencePassword() );
-
- return result;
- }
-
- private String getPersistencePassword() {
- return System.getProperty( PERSISTENCE_PASSWORD_PROPERTY );
- }
-
- private String getPersistenceUnitName() {
- return "SALES";
- }
-
- /**
- * Returns the empty string if the given string is null.
- *
- * @param s The string to un-nullify.
- *
- * @return s or "" if s is null.
- */
- private String nullSafe( String s ) {
- return s == null ? "" : s;
- }
-}
src/main/java/com/whitemagicsoftware/sales/service/impl/SubscriberServiceImpl.java
-/*
- * 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.service.SubscriberService;
-import java.util.List;
-import javax.mail.internet.AddressException;
-
-/**
- * @author White Magic Software, Ltd.
- */
-public class SubscriberServiceImpl extends ServiceImpl<Subscriber>
- implements SubscriberService {
-
- @Override
- public List<Subscriber> list() throws AddressException {
- return getResultList( Subscriber.class );
- }
-}
src/main/java/com/whitemagicsoftware/sales/service/impl/SubscriptionServiceImpl.java
-/*
- * 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.Subscription_;
-import com.whitemagicsoftware.sales.Vendor;
-import com.whitemagicsoftware.sales.service.SubscriptionService;
-import java.util.List;
-import javax.persistence.TypedQuery;
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Root;
-
-/**
- * @author White Magic Software, Ltd.
- */
-public class SubscriptionServiceImpl extends ServiceImpl<Subscription> implements SubscriptionService {
-
- @Override
- public synchronized List<Subscription> list(
- Subscriber subscriber,
- Vendor vendor ) {
- Class clazz = Subscription.class;
-
- CriteriaBuilder builder = getCriteriaBuilder();
- CriteriaQuery<Subscription> criteria = builder.createQuery( clazz );
- Root<Subscription> root = criteria.from( clazz );
-
- criteria.select( root );
- criteria.where(
- builder.equal(
- root.get( Subscription_.subscriberId ), subscriber.getId() ),
- builder.equal(
- root.get( Subscription_.vendorId ), vendor.getId() )
- );
-
- TypedQuery<Subscription> subscriptions = createQuery( criteria );
-
- return subscriptions.getResultList();
- }
-}
src/main/java/com/whitemagicsoftware/sales/service/impl/VendorServiceImpl.java
-/*
- * 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 com.whitemagicsoftware.sales.service.VendorService;
-import java.util.List;
-
-/**
- * @author White Magic Software, Ltd.
- */
-public class VendorServiceImpl extends ServiceImpl<Vendor>
- implements VendorService {
-
- @Override
- public List<Vendor> list() {
- return getResultList( Vendor.class );
- }
-}
src/main/resources/META-INF/persistence.xml
<property name="hibernate.c3p0.acquireRetryDelay" value="250"/>
<!-- Show SQL statements for debugging purposes. -->
- <property name="hibernate.show_sql" value="true"/>
+ <property name="hibernate.show_sql" value="false"/>
<!-- Disabled because "vendor" isn't a table, it's a function. -->
<property name="hibernate.hbm2ddl.auto" value=""/>
src/main/resources/scripts/1_com_thriftyfoods.xml
<var-def name="message_body">
<case>
- <if condition="${vendor_name_include}">
+ <if condition="${include_vendor_name}">
<template>
<file path="templates/header-vendor-name.md"/>
src/test/java/com/whitemagicsoftware/notify/HttpTransportTest.java
package com.whitemagicsoftware.notify;
-import static com.whitemagicsoftware.notify.Credentials.PASSWORD;
-import static com.whitemagicsoftware.notify.Credentials.SENDER;
-import static com.whitemagicsoftware.notify.Credentials.SENDER_NAME;
-import static com.whitemagicsoftware.notify.Credentials.USERNAME;
+import static com.whitemagicsoftware.sales.SystemProperty.*;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
Session session = Session.getInstance( new Properties() );
HttpTransport transport = new ElasticEmailTransport( session );
- transport.setAuthentication( USERNAME.toString(), PASSWORD.toString() );
+ transport.setAuthentication(
+ getUsername(),
+ getPassword()
+ );
transport.addTransportListener( new TransportTestListener() );
- Address recipient = new InternetAddress( USERNAME.toString() );
+ Address recipient = new InternetAddress( getUsername() );
Address sender = new InternetAddress(
- SENDER.toString(),
- SENDER_NAME.toString() );
+ getSenderAddress(),
+ getSenderName() );
Message message = new MimeMessage( session );
}
}
-
+
+ private String getUsername() {
+ return APP_NOTIFY_CREDENTIALS_USERNAME.getValue();
+ }
+
+ private String getPassword() {
+ return APP_NOTIFY_CREDENTIALS_PASSWORD.getValue();
+ }
+
+ private String getSenderAddress() {
+ return APP_NOTIFY_CREDENTIALS_SENDER_ADDR.getValue();
+ }
+
+ private String getSenderName() {
+ return APP_NOTIFY_CREDENTIALS_SENDER_NAME.getValue();
+ }
+
private class TransportTestListener implements TransportListener {
src/test/java/com/whitemagicsoftware/sales/service/impl/DefaultProductServiceTest.java
+/*
+ * 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 DefaultProductServiceTest extends DefaultServiceTest {
+
+ public DefaultProductServiceTest() {
+ }
+
+ /**
+ * 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 );
+ }
+}
src/test/java/com/whitemagicsoftware/sales/service/impl/DefaultServiceTest.java
+/*
+ * 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 DefaultServiceTest {
+
+ protected ProductService getProductService() {
+ return new DefaultProductService();
+ }
+
+ protected VendorService getVendorService() {
+ return new DefaultVendorService();
+ }
+
+ protected SubscriberService getSubscriberService() {
+ return new DefaultSubscriberService();
+ }
+
+ protected SubscriptionService getSubscriptionService() {
+ return new DefaultSubscriptionService();
+ }
+}
src/test/java/com/whitemagicsoftware/sales/service/impl/DefaultSubscriberServiceTest.java
+/*
+ * 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 java.util.List;
+import javax.mail.internet.AddressException;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests the Subscriber Service.
+ *
+ * @author White Magic Software, Ltd.
+ */
+public class DefaultSubscriberServiceTest extends DefaultServiceTest {
+
+ public DefaultSubscriberServiceTest() {
+ }
+
+ /**
+ * 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 {
+ List<Subscriber> subscribers = getSubscriberService().list();
+
+ Assert.assertTrue( "Could not obtain subscribers from database.",
+ subscribers.size() > 0 );
+ }
+}
src/test/java/com/whitemagicsoftware/sales/service/impl/DefaultSubscriptionServiceTest.java
+/*
+ * 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.Subscription;
+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 DefaultSubscriptionServiceTest extends DefaultServiceTest {
+
+ public DefaultSubscriptionServiceTest() {
+ }
+
+ /**
+ * 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<Subscription> subscriptions = getSubscriptionService().list();
+
+ Assert.assertTrue( "Could not obtain subscriptions.",
+ subscriptions.size() > 0 );
+ }
+}
src/test/java/com/whitemagicsoftware/sales/service/impl/DefaultVendorServiceTest.java
+/*
+ * 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 DefaultVendorServiceTest extends DefaultServiceTest {
+
+ public DefaultVendorServiceTest() {
+ }
+
+ /**
+ * 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 );
+ }
+}
src/test/java/com/whitemagicsoftware/sales/service/impl/ProductServiceImplTest.java
-/*
- * 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 );
- }
-}
src/test/java/com/whitemagicsoftware/sales/service/impl/ServiceImplTest.java
-/*
- * 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();
- }
-}
src/test/java/com/whitemagicsoftware/sales/service/impl/SubscriberServiceImplTest.java
-/*
- * 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 java.util.List;
-import javax.mail.internet.AddressException;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Tests the Subscriber Service.
- *
- * @author White Magic Software, Ltd.
- */
-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 {
- List<Subscriber> subscribers = getSubscriberService().list();
-
- Assert.assertTrue( "Could not obtain subscribers from database.",
- subscribers.size() > 0 );
- }
-}
src/test/java/com/whitemagicsoftware/sales/service/impl/SubscriptionServiceImplTest.java
-/*
- * 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();
-
- Subscriber subscriber = subscribers.get( 0 );
- Vendor vendor = vendors.get( 0 );
-
- List<Subscription> subscriptions = getSubscriptionService().list(
- subscriber, vendor );
-
- Assert.assertTrue( "Could not obtain products for vendor/subscriber pair.",
- subscriptions.size() > 0 );
- }
-}
src/test/java/com/whitemagicsoftware/sales/service/impl/VendorServiceImplTest.java
-/*
- * 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 );
- }
-}

Removed Credentials in favour of command line arguments. Renamed Impls to Defaults. Replaced triple-loop (subscriber, vendor, subsription) Cartesian with single-loop subscription iterator. Added equals methods for comparing vendors and comparing subscribers. Added direct object relation dependencies through containment and JPA. Updated tests accordingly.

Author djarvis <email>
Date 2016-06-25 23:13:20 GMT-0700
Commit a5567ce32b21fab32c49cedd01804c6032f1909f
Parent d52072b
Delta 1147 lines added, 926 lines removed, 221-line increase