SlideShare a Scribd company logo
1 of 17
Download to read offline
OpenDMS
I couldnt think of anything to call it, but as Darren said it could be open sourced and it is a DMS this
seemed logical.
While I am working (at the moment) on eBay functionality, I have been mindful to do things is such a
way as to allow this to serve as a framework of sorts for the rest of the DMS proper. In this document I
hope to take you through the salient points of the design and how they would be extensible to
additional functionality.
Introduction
While I have split this project into a loose Model-View-Presenter architecture, it is not tied to any
paricular MVP framework or library, more a guiding principal than anything else. Still it serves well
enough to divide up the functionality
model
Database (appendix A)
As it stands currently, the core of the Model is the JDBC database integration, this begins with the
conection manager. I have used the C3PO connection pooling library to implement a pooled datasource
object which allows client objects request connections from (current max of 20 connections but that
can be changed easily).
Individual database queries are encapsulated as concrete commands in a command pattern with the
invoker being a factory. As it stands the invoker/factory keeps copies of the commands in a map for
easy access, but should there turn out to be a significant number of concrete database commands it
would make sense to have a specific factory class for each concrete command to avoid having to store
all of them in each instance of the invoker.
As a side point each concrete command has a 'List<String[]> execute(String[])' where the individual
query functionality is implemented. In the return type ach element of the String[] represents a column,
and each element of the list is a seperate row.
Obviously insert/update/delete queries only return a result code so there is a choice here. Seperate the
whole thing into two command patterns or treat every query equally and just use the ouput appropiately
and consistantly.
Services (appendix B)
This is the second part of the model and encompasses everything else that needs to go on in the
background. I can see two types of services that might need to be implemented: Scheduled services and
triggered services. i.e. a service that runs at set intervals and services that are expressly triggered by the
user.
I have implemented the Scheduled Services part but not the Triggered Services part as yet. The
Scheduled services are implemented using a class called ServiceScheduler, which creates a
ScheduledThreadPoolExecutor (from the java.util.concurrent lib) and stores AbstractService derived
types (AbstractService is an empty interface that implements runnable) in a List. It has an
add(AbstractService, delay, rate) method so that each service can run at its own pre-specified interval,
and delay; as well as a start method which iterates through the list calling the .get() method on each
services ScheduledFuture<?>, fairly self explanatory.
As I said I have not implemented the triggered services yet as I dont know what the best way of doing
this would be.
View/presenter (appendix C)
The View is Jetty based (embedded http server and servlet container). Currently the HTTP server has a
fairly basic configuration (no SSL, no sessions, no auth) but I figured that could be configured at a later
stage (jetty has built in database auth functionality, as well as support for SSL and sessions, and a
bunch of other fun stuff).
The HTTP Server is responsible for one servlet at the moment, cunningly named UIServlet. This
UIServlet uses a View/Presenter Abstract factory to select an appropriate pair of View and Presenter
based on the URL parameters passed to the servlets doGet method from individual HTTP requests.
The concrete View objects are responsible for reading .html files located in a resources directory and
providing a 'make' method for the presenter to use when putting a particular view together i.e. the
make method returns a string representing the particular part of a view that has been requested
header/footer/navbar/etc.
As a result the presenters responsibility is two-fold, firstly to assemble the static part of the view (the
static html from the concrete views) and to insert dynamic content from the database(using the JDBC
implementation described earlier). They do all of this within their String present(AbstractView)
methods.
The Abstract factory class brings this all together so that the UIServlet can do its job of selecting the
appropriate view based on the URL query strings from an http request.
I hope that this has been at least relatively clear. I know its a lot trying to get an overview of the system
as is in a couple of pages. I have included appendices after this if it helps.
jpchansondev@gmail.com
jpchanson@tomoparts.co.uk
07796311906
Appendix A
Connection Manager
/**
* This class provides access to a pool of database connections. It is a
threadsafe singleton
* so always use the instance method to get an instance of this class, NEVER STORE
THE INSTANCE.
* @author Jan P.C. Hanson
*
*/
public class ConnectionManager
{
/**Singleton instance with eager instanciation**/
private static ConnectionManager test = new ConnectionManager();
/**C3P0 Data pool**/
private ComboPooledDataSource cpds;
/**
* singleton contstructor, initialises the connection pool
*/
private ConnectionManager()
{
cpds = new ComboPooledDataSource();
try
{cpds.setDriverClass("com.mysql.jdbc.Driver");}
catch (PropertyVetoException e)
{e.printStackTrace();}
cpds.setJdbcUrl("jdbc:mysql://192.168.0.202:3306/ebay");
cpds.setUser("openDMS");
cpds.setPassword("0p3nDMS/*-");
cpds.setMinPoolSize(3);
cpds.setAcquireIncrement(5);
cpds.setMaxPoolSize(20);
cpds.setMaxStatements(180);
}
/**
* instance method returns an instance of the ConnectionManager class
* @return ConnectionManager instance
*/
public static ConnectionManager instance()
{return test;}
/**
* retrieves a database connection from the pool of available connections.
When
* Connection.close is called the connection is returned to the pool.
* @return
* @throws SQLException
*/
public Connection getConnection() throws SQLException
{return this.cpds.getConnection();}
}
Database Query (invoker)
public class DatabaseQuery
{
/**map of commands**/
private Map<QueryType, AbstractDBQuery> commandMap_M;
/**defensive enum for map**/
public enum QueryType
{
SELECT_EBAY_ORDERS, INSERT_EBAY_ORDERS
}
/**
* constructor, initialises the internal map.
*/
public DatabaseQuery()
{
super();
this.commandMap_M = new HashMap<QueryType, AbstractDBQuery>();
this.populateMap();
}
/**
*
* @param command enum value taken from the internal enum 'QueryType'
represents the type
* of query that you wish to execute.
* @param parameters a string array containing the parameters for the query
in question.
* Not all queries require parameters whereas others do. Check the concrete
query type
* documentation for more information
* @return List<String[]> the position within the list defines the row, and
the position
* withing the string array defines the column so list index 0, array index
2 would be the
* 3rd column of the 1st row.
* @throws SQLException
*/
public List<String[]> execute(QueryType command, String[] parameters) throws
SQLException
{return this.commandMap_M.get(command).execute(parameters);}
/**
* populates the map with the concrete AbstractDBQuery Types.
*/
private void populateMap()
{
this.commandMap_M.put(DatabaseQuery.QueryType.SELECT_EBAY_ORDERS, new
SelectEbayOrders());
this.commandMap_M.put(DatabaseQuery.QueryType.INSERT_EBAY_ORDERS, new
InsertEbayOrders());
}
Abstract Command interface
/**
* Interface that all database queries must adhere to. this is the Abstract
command class for
* this command pattern.
* @author Jan P.C. Hanson
*
*/
public interface AbstractDBQuery
{
/**
* executes the query.
* @param Parameter(s) to use in the query, see concrete type's class
documentation for more
* information
* @return String representing the output of a particular query.
*/
public List<String[]> execute(String[] Parameter) throws SQLException;
}
Concrete Ebay Command Select Example
public class SelectEbayOrders implements AbstractDBQuery
{
/**reference to the JDBC Statement**/
private PreparedStatement statement_M = null;
/**reference to the JDBC Database connection**/
private Connection connection_M = null;
/**SQL query string**/
private static final String query = "SELECT * FROM ebay.ebay_buyers;";
/**
* default constructor
*/
public SelectEbayOrders()
{super();}
/**
* execute the query
* @param parameter NOT USED for this query.
* @return String representing the results of the query.
* @throws SQLException
*/
public List<String[]> execute(String[] parameter) throws SQLException
{
this.initQuery();
ResultSet resultset = statement_M.executeQuery(query);
List<String[]> result = this.formatResults(resultset);
this.connection_M.commit();
this.cleanup();
return result;
}
/**
* formats the ResultSet (returned from the executed query) as a string
* @param results the ResultSet (post query execution)
* @return String containing the formatted results.
* @throws SQLException
*/
private List<String[]> formatResults(ResultSet results) throws SQLException
{
List<String[]> rows = new ArrayList<String[]>();
while (results.next())
{
String[] cols = new String[4];
cols[0] = results.getString("buyerID");
cols[1] = results.getString("name");
cols[2] = results.getString("shippingAddress");
cols[3] = results.getString("invoiceAddress");
rows.add(cols);
}
return rows;
}
/**
* initialise the connection and statement and set transaction variables.
* @throws SQLException
*/
private void initQuery() throws SQLException
{
this.connection_M = ConnectionManager.instance().getConnection();
this.connection_M.setAutoCommit(false);
statement_M = connection_M.prepareStatement(query);
}
/**
* do cleanup after the query has been executed
* @throws SQLException
*/
private void cleanup() throws SQLException
{
if (statement_M != null)
{statement_M.close();System.out.println("closing statement");}
if (connection_M != null)
{connection_M.close();System.out.println("closing connection");}
}
}
Concrete Command Insert Example
public class InsertEbayOrders implements AbstractDBQuery
{
/**reference to the JDBC Statement**/
private PreparedStatement statement_M = null;
/**reference to the JDBC Database connection**/
private Connection connection_M = null;
/**SQL query string**/
private String query ="INSERT IGNORE INTO ebay.ebay_orders (orderID,
transactionID, buyerID, salesRecNo, shippingType, createdTime)"
+ "VALUES (?,?,?,?,?,?);";
/**
* default constructor
*/
public InsertEbayOrders()
{super();}
/**
* execute the query
* @param parameter an array of strings where the 0th element is the
parameter for the
* first column, the 1st element is the parameter for the 2nd column and so
on. The Ebay
* Orders Table only has 6 columns so any element above the 3rd element will
be ignored.
* col1 =orderID:int(30), col2=transactionID:int(20),
col3=buyerID:varchar(40),
* col4=salesRecNo:int(10), col5=shippingType:varchar(200),
col6=createdTine:datetime
* @return List<String> representing the results of the query.
* @throws SQLException
*/
public List<String[]> execute(String[] parameter) throws SQLException
{
this.initQuery();
this.connection_M.prepareStatement(query);
this.statement_M.setInt(1, 0000);
this.statement_M.setInt(2, 1111);
this.statement_M.setString(3, "kirk");
this.statement_M.setInt(4, 42);
this.statement_M.setString(5, "carrier pidgeon");
java.util.Date date = new Date();
java.sql.Date sqlDate = new java.sql.Date(date.getTime());
this.statement_M.setTimestamp(6, new
java.sql.Timestamp(date.getTime()));
// this.statement_M.setInt(6, 20151013);
int resultCode = statement_M.executeUpdate();
this.connection_M.commit();
this.cleanup();
List<String[]> res = new ArrayList<String[]>();
res.add(new String[] {resultCode + ""});
return res;
}
/**
* initialise the connection and statement and set transaction variables.
* @throws SQLException
*/
private void initQuery() throws SQLException
{
this.connection_M = ConnectionManager.instance().getConnection();
this.connection_M.setAutoCommit(false);
statement_M = connection_M.prepareStatement(query);
}
/**
* do cleanup after the query has been executed
* @throws SQLException
*/
private void cleanup() throws SQLException
{
if (statement_M != null)
{statement_M.close();System.out.println("closing statement");}
if (connection_M != null)
{connection_M.close();System.out.println("closing connection");}
Appendix B
Service Scheduler
public class ServicesScheduler
{
/****/
ScheduledThreadPoolExecutor serviceScheduler_M;
/****/
List<ScheduledFuture<?>> services_M;
/**
*
* @param noOfThreads
*/
public ServicesScheduler(int noOfThreads)
{
this.serviceScheduler_M = new
ScheduledThreadPoolExecutor(noOfThreads);
this.serviceScheduler_M.setMaximumPoolSize(noOfThreads+2);
this.services_M = new ArrayList<ScheduledFuture<?>>();
}
/**
*
* @param service
*/
public void add(AbstractService service, long delay, long rate)
{
this.services_M.add(this.serviceScheduler_M.scheduleWithFixedDelay(service,
delay, rate, TimeUnit.MINUTES));
}
/**
*
*/
public void start()
{
try
{
for(int i = 0 ; i < this.services_M.size() ; ++i)
{
this.services_M.get(i).get();
}
}
catch(InterruptedException | ExecutionException e)
{e.printStackTrace();}
serviceScheduler_M.shutdown();
}
}
Abstract Service Interface
/**
* Convienience interface, allows the system to only accept runnable's that
implement this
* interface rather than all runnables.
* @author Jan P.C. Hanson
*
*/
public interface AbstractService extends Runnable
{
public void run();
}
eBay Service example
/**
* This class represents the start of the execution flow for the eBay Service, The
service
* quereies the eBay API for Order and Item information and
* @author Jan P.C. Hanson
*
*/
public class EbayService implements AbstractService
{
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
//index 0 = blank, index 1 = sandbox server string, index 2 = sandbox
user token
//index 3 = production server string, index 4 = production user token.
String[] credentials = ConfigReader.read("./config/", "ebay.cfg");
OrdersCall oCall = new OrdersCall(credentials[4], credentials[3]);
try
{
// OrderType[] orders = oCall.call(1);
this.insertOrders();
this.insertTransactions();
this.insertBuyers();
this.insertItems();
}
// catch (ApiException e)
// {e.printStackTrace();}
// catch (SdkException e)
// {e.printStackTrace();}
catch (Exception e)
{e.printStackTrace();}
}
private void insertOrders() throws SQLException
{
InsertEbayOrders iOrd = new InsertEbayOrders();
iOrd.execute(new String[] {});
}
private void insertTransactions()
{
}
private void insertBuyers()
{
}
private void insertItems()
{
}
}
Appendix C
Servlet
public class UIServlet extends HttpServlet
{
/**needed to avoid warnings**/
private static final long serialVersionUID = -417534770555839323L;
/**
* instantiates a servlet using the views provided.
* @param views
*/
public UIServlet()
{super();}
/**
* service method, this controls how the servlet responds to particular URL
query strings
* @param request the http request to the servlet
* @param response the http response to the servlet
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
PrintWriter out = response.getWriter();
// ViewPresenterFactory viewPresenterFactory =
ViewPresenterFactory.instance();
AbstractViewPresenterFactory factory;
String viewParam = request.getParameter("view");
if (ViewPresenterFactory.instance().hasFactory(viewParam)==true)
{
factory = ViewPresenterFactory.instance().getFactory(viewParam);
out.print(factory.makePresenter().present(factory.makeView()));
}
else
{
factory = ViewPresenterFactory.instance().getFactory("ROOT");
out.print(factory.makePresenter().present(factory.makeView()));
}
out.close();
}
}
Abstract Factory interface
/**
* the interface that all concrete factories should subscribe to.
* @author Jan P.C. Hanson
*
*/
public interface AbstractViewPresenterFactory
{
/**
* factory method that creates a view
* @return AbstractView the view that has been requested
*/
public AbstractView makeView();
/**
* factory method that creates a presenter
* @return AbstractPresenter the presenter than has been requested.
*/
public AbstractPresenter makePresenter();
}
concrete Factory for eBay View/Presenter
/**
* EbayAbstractFactory creates the presenter and view for the eBay view.
* @author Jan P.C. Hanson
*
*/
public class EbayFactory implements AbstractViewPresenterFactory
{
/* (non-Javadoc)
* @see
openDMS.helpers.viewPresenterFactory.AbstractViewPresenterFactory#makeView()
*/
@Override
public AbstractView makeView()
{return new EbayView();}
/* (non-Javadoc)
* @see
openDMS.helpers.viewPresenterFactory.AbstractViewPresenterFactory#makePresenter()
*/
@Override
public AbstractPresenter makePresenter()
{return new EbayPresenter();}
}
concrete Factory for root view/presenter
/**
* RootAbstractFactory creates the presenter and view for the root view.
* @author Jan P.C. Hanson
*
*/
public class RootFactory implements AbstractViewPresenterFactory
{
/* (non-Javadoc)
* @see
openDMS.helpers.viewPresenterFactory.AbstractViewPresenterFactory#makeView()
*/
@Override
public AbstractView makeView()
{return new RootView();}
/* (non-Javadoc)
* @see
openDMS.helpers.viewPresenterFactory.AbstractViewPresenterFactory#makePresenter()
*/
@Override
public AbstractPresenter makePresenter()
{return new RootPresenter();}
}
Abstract Factory implementation
public class ViewPresenterFactory
{
/**Singleton instance variable**/
private static final ViewPresenterFactory instance_M = new
ViewPresenterFactory();
/**enum to use for factory creation options**/
public enum Select {ROOT, EBAY}
/**map of enum constants to concrete factories**/
Map<Select, AbstractViewPresenterFactory> factory_M;
/**
* default constructor
*/
private ViewPresenterFactory()
{
super();
factory_M = new HashMap<Select, AbstractViewPresenterFactory>();
this.populateMap();
}
/**
* singleton instance method, returns an instance of this object.
* @return ViewPresenterFactory the singleton instance.
*/
public static ViewPresenterFactory instance()
{return ViewPresenterFactory.instance_M;}
/**
* creates a specific factory based on the string provided.
* @param factory string that is compared to enum values.
* @return AbstractViewPresenterFactory a concrete viewPresenterFactory
*/
public AbstractViewPresenterFactory getFactory(String factory)
{return this.factory_M.get(ViewPresenterFactory.Select.valueOf(factory));}
/**
* check to see if a factory type exists by comparing the string provided to
the
* internal enum 'Select'
* @param factory the string to compare to the internal enum
* @return boolean true if the factory is a valid type, false otherwise.
*/
public boolean hasFactory(String factory)
{
if (factory == null) {return false;}
else if (Select.valueOf(factory) != null) {return true;}
else {return false;}
}
/**
* populate the internal map with viewPresenterFactories.
*/
private void populateMap()
{
this.factory_M.put(ViewPresenterFactory.Select.ROOT, new
RootFactory());
this.factory_M.put(ViewPresenterFactory.Select.EBAY, new
EbayFactory());
}
}
public interface AbstractView
{
/**
* This method constructs the part of the view that is requested in the
parameters.
* @param part should be taken from the internal Enum defined within this
class. Each enum
* constant refers to a specific part of the view.
* @return String containing the HTML for the part of the view that has been
requested.
*/
public String make(AbstractViewPart part);
}
Views interface
/**
* This interface provides a root for all enums needed for the AbstractView
derived objects
* @author Jan P.C. Hanson
*
*/
public interface AbstractViewPart
{
/**root enum, to be implemented by the enums inside the Abstract view
derived classes**/
public enum Part {};
}
concrete view 1
public class EbayView implements AbstractView
{
/**mapping of enum constant keys to html strings**/
private Map<Part, String> viewPart_M;
/**enum containing constants relating to the view parts**/
public enum Part implements AbstractViewPart{HEADER, FOOTER};
/**
* default constructor
*/
public EbayView()
{
super();
viewPart_M = new HashMap<Part, String>();
this.populateMap();
}
/* (non-Javadoc)
* @see openDMS.view.AbstractView#make(openDMS.view.AbstractView.PART)
*/
@Override
public String make(AbstractViewPart part)
{return this.viewPart_M.get(part);}
/**
* populates the map with the
*/
protected void populateMap()
{
this.viewPart_M.put(EbayView.Part.HEADER,
FileToString.convert("./res/ebay/", "eBayHeader.html", "utf-8"));
this.viewPart_M.put(EbayView.Part.FOOTER,
FileToString.convert("./res/ebay/", "eBayFooter.html", "utf-8"));
}
}
concrete view 2
public class RootView implements AbstractView
{
/**mapping of enum constant keys to html strings**/
private Map<Part, String> viewPart_M;
/**enum containing constants relating to the view parts**/
public enum Part implements AbstractViewPart{INDEX}
public RootView()
{
super();
viewPart_M = new HashMap<Part, String>();
this.populateMap();
}
/* (non-Javadoc)
* @see openDMS.view.AbstractView#make(openDMS.view.AbstractViewPart)
*/
@Override
public String make(AbstractViewPart part)
{return this.viewPart_M.get(part);}
private void populateMap()
{
this.viewPart_M.put(RootView.Part.INDEX,
FileToString.convert("./res/", "index.html", "utf-8"));
}
}
presenter interface
public interface AbstractPresenter
{
/**
* this method is called when you actually want to present the information
contained in the
* view/presenter to the servlet
* @param view the view to be rpesented
* @return String representing the html contained in the view/presenter
*/
public String present(AbstractView view);
}
cocnrete presenter 2
public class RootPresenter implements AbstractPresenter
{
/**
* default constructor
*/
public RootPresenter()
{super();}
/* (non-Javadoc)
* @see
openDMS.presenters.AbstractPresenter#present(openDMS.view.views.AbstractView)
*/
@Override
public String present(AbstractView view)
{
String output = "";
output += view.make(RootView.Part.INDEX);
System.out.println("Root page loaded");
return output;
}
}
concrete presenter 1
public class EbayPresenter implements AbstractPresenter
{
/**
* default constructor
*/
public EbayPresenter()
{super();}
/* (non-Javadoc)
* @see
openDMS.presenters.AbstractPresenter#present(openDMS.view.views.AbstractView)
*/
@Override
public String present(AbstractView view)
{
String output = "";
output += view.make(EbayView.Part.HEADER);
output += this.doStuff();
output += view.make(EbayView.Part.FOOTER);
return output;
}
private String doStuff()
{
String result = "";
try
{
DatabaseQuery query = new DatabaseQuery();
query.execute(DatabaseQuery.QueryType.INSERT_EBAY_ORDERS, new
String[] {});
List<String[]> rows =
query.execute(DatabaseQuery.QueryType.SELECT_EBAY_ORDERS,new String[] {""});
result+= "<table class='table table-bordered'> n";
result+= "<thead>n<tr>n"
+ "<th>ID</th>n"
+ "<th>name</th>n"
+ "<th>Shipping Address</th>n"
+ "<th>Invoice Address</th>n"
+ "</tr>n</thead>n <tbody>";
for (String[] cols : rows)
{
result+="<tr>n";
result+="<td>"+ cols[0].trim() + "</td>n";
result+="<td>"+ cols[1].trim() + "</td>n";
result+="<td>"+ cols[2].trim() + "</td>n";
result+="<td>"+ cols[3].trim() + "</td>n";
result+="</tr>n";
}
result+="</tbody>n</table>";
}
catch(SQLException e)
{e.printStackTrace();}
return "<h1> eBay </h1> n <a class='btn btn-default'
href='/'>Root</a><br/>n" + result;
}
}

More Related Content

What's hot

JSP - Java Server Page
JSP - Java Server PageJSP - Java Server Page
JSP - Java Server PageVipin Yadav
 
JAVA EE DEVELOPMENT (JSP and Servlets)
JAVA EE DEVELOPMENT (JSP and Servlets)JAVA EE DEVELOPMENT (JSP and Servlets)
JAVA EE DEVELOPMENT (JSP and Servlets)Talha Ocakçı
 
Atul & shubha goswami jsp
Atul & shubha goswami jspAtul & shubha goswami jsp
Atul & shubha goswami jspAtul Giri
 
#29.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#29.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#29.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#29.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Box connector Mule ESB Integration
Box connector Mule ESB IntegrationBox connector Mule ESB Integration
Box connector Mule ESB IntegrationAnilKumar Etagowni
 
Introduction to JSP
Introduction to JSPIntroduction to JSP
Introduction to JSPGeethu Mohan
 
Bt0083 server side programing 2
Bt0083 server side programing  2Bt0083 server side programing  2
Bt0083 server side programing 2Techglyphs
 
Spring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topicsSpring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topicsGuy Nir
 
Salesforce, APEX Concepts
Salesforce, APEX ConceptsSalesforce, APEX Concepts
Salesforce, APEX ConceptsGaurish Goel
 
Angular 2 Component Communication - Talk by Rob McDiarmid
Angular 2 Component Communication - Talk by Rob McDiarmidAngular 2 Component Communication - Talk by Rob McDiarmid
Angular 2 Component Communication - Talk by Rob McDiarmidAmrita Chopra
 

What's hot (20)

JSP - Java Server Page
JSP - Java Server PageJSP - Java Server Page
JSP - Java Server Page
 
JAVA EE DEVELOPMENT (JSP and Servlets)
JAVA EE DEVELOPMENT (JSP and Servlets)JAVA EE DEVELOPMENT (JSP and Servlets)
JAVA EE DEVELOPMENT (JSP and Servlets)
 
Atul & shubha goswami jsp
Atul & shubha goswami jspAtul & shubha goswami jsp
Atul & shubha goswami jsp
 
Sel study notes
Sel study notesSel study notes
Sel study notes
 
Data Access with JDBC
Data Access with JDBCData Access with JDBC
Data Access with JDBC
 
#29.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#29.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#29.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#29.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
 
Jsp sasidhar
Jsp sasidharJsp sasidhar
Jsp sasidhar
 
Box connector Mule ESB Integration
Box connector Mule ESB IntegrationBox connector Mule ESB Integration
Box connector Mule ESB Integration
 
Java server pages
Java server pagesJava server pages
Java server pages
 
Java concurrency
Java concurrencyJava concurrency
Java concurrency
 
Java Server Pages
Java Server PagesJava Server Pages
Java Server Pages
 
Java jdbc
Java jdbcJava jdbc
Java jdbc
 
Introduction to JSP
Introduction to JSPIntroduction to JSP
Introduction to JSP
 
Implicit object.pptx
Implicit object.pptxImplicit object.pptx
Implicit object.pptx
 
Bt0083 server side programing 2
Bt0083 server side programing  2Bt0083 server side programing  2
Bt0083 server side programing 2
 
Spring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topicsSpring 3.x - Spring MVC - Advanced topics
Spring 3.x - Spring MVC - Advanced topics
 
Spring MVC Basics
Spring MVC BasicsSpring MVC Basics
Spring MVC Basics
 
Salesforce, APEX Concepts
Salesforce, APEX ConceptsSalesforce, APEX Concepts
Salesforce, APEX Concepts
 
Angular 2 Component Communication - Talk by Rob McDiarmid
Angular 2 Component Communication - Talk by Rob McDiarmidAngular 2 Component Communication - Talk by Rob McDiarmid
Angular 2 Component Communication - Talk by Rob McDiarmid
 
Spring annotation
Spring annotationSpring annotation
Spring annotation
 

Similar to OpenDMS - the first 2 weeks

Tuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paperTuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paperVinay Kumar
 
Advance Java Practical file
Advance Java Practical fileAdvance Java Practical file
Advance Java Practical filevarun arora
 
Introduction to JDBC and database access in web applications
Introduction to JDBC and database access in web applicationsIntroduction to JDBC and database access in web applications
Introduction to JDBC and database access in web applicationsFulvio Corno
 
SCWCD : The servlet container : CHAP : 4
SCWCD : The servlet container : CHAP : 4SCWCD : The servlet container : CHAP : 4
SCWCD : The servlet container : CHAP : 4Ben Abdallah Helmi
 
Web Technologies - forms and actions
Web Technologies -  forms and actionsWeb Technologies -  forms and actions
Web Technologies - forms and actionsAren Zomorodian
 
3.java database connectivity
3.java database connectivity3.java database connectivity
3.java database connectivityweb360
 
Integration of Backbone.js with Spring 3.1
Integration of Backbone.js with Spring 3.1Integration of Backbone.js with Spring 3.1
Integration of Backbone.js with Spring 3.1Michał Orman
 
Murach : How to work with session state and cookies
Murach : How to work with session state and cookiesMurach : How to work with session state and cookies
Murach : How to work with session state and cookiesMahmoudOHassouna
 

Similar to OpenDMS - the first 2 weeks (20)

Express node js
Express node jsExpress node js
Express node js
 
Sqlapi0.1
Sqlapi0.1Sqlapi0.1
Sqlapi0.1
 
Jdbc[1]
Jdbc[1]Jdbc[1]
Jdbc[1]
 
JDBC programming
JDBC programmingJDBC programming
JDBC programming
 
Jdbc
JdbcJdbc
Jdbc
 
Tuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paperTuning and optimizing webcenter spaces application white paper
Tuning and optimizing webcenter spaces application white paper
 
Advance Java Practical file
Advance Java Practical fileAdvance Java Practical file
Advance Java Practical file
 
Introduction to JDBC and database access in web applications
Introduction to JDBC and database access in web applicationsIntroduction to JDBC and database access in web applications
Introduction to JDBC and database access in web applications
 
Java beans
Java beansJava beans
Java beans
 
SCWCD : The servlet container : CHAP : 4
SCWCD : The servlet container : CHAP : 4SCWCD : The servlet container : CHAP : 4
SCWCD : The servlet container : CHAP : 4
 
J2EE pattern 5
J2EE pattern 5J2EE pattern 5
J2EE pattern 5
 
Data access
Data accessData access
Data access
 
Jsp and jstl
Jsp and jstlJsp and jstl
Jsp and jstl
 
Web Technologies - forms and actions
Web Technologies -  forms and actionsWeb Technologies -  forms and actions
Web Technologies - forms and actions
 
3.java database connectivity
3.java database connectivity3.java database connectivity
3.java database connectivity
 
Spring mvc
Spring mvcSpring mvc
Spring mvc
 
Integration of Backbone.js with Spring 3.1
Integration of Backbone.js with Spring 3.1Integration of Backbone.js with Spring 3.1
Integration of Backbone.js with Spring 3.1
 
Murach : How to work with session state and cookies
Murach : How to work with session state and cookiesMurach : How to work with session state and cookies
Murach : How to work with session state and cookies
 
ASP.NET 09 - ADO.NET
ASP.NET 09 - ADO.NETASP.NET 09 - ADO.NET
ASP.NET 09 - ADO.NET
 
Jdbc api
Jdbc apiJdbc api
Jdbc api
 

Recently uploaded

Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 

Recently uploaded (20)

Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Odoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting ServiceOdoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting Service
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 

OpenDMS - the first 2 weeks

  • 1. OpenDMS I couldnt think of anything to call it, but as Darren said it could be open sourced and it is a DMS this seemed logical. While I am working (at the moment) on eBay functionality, I have been mindful to do things is such a way as to allow this to serve as a framework of sorts for the rest of the DMS proper. In this document I hope to take you through the salient points of the design and how they would be extensible to additional functionality. Introduction While I have split this project into a loose Model-View-Presenter architecture, it is not tied to any paricular MVP framework or library, more a guiding principal than anything else. Still it serves well enough to divide up the functionality model Database (appendix A) As it stands currently, the core of the Model is the JDBC database integration, this begins with the conection manager. I have used the C3PO connection pooling library to implement a pooled datasource object which allows client objects request connections from (current max of 20 connections but that can be changed easily). Individual database queries are encapsulated as concrete commands in a command pattern with the invoker being a factory. As it stands the invoker/factory keeps copies of the commands in a map for easy access, but should there turn out to be a significant number of concrete database commands it would make sense to have a specific factory class for each concrete command to avoid having to store all of them in each instance of the invoker. As a side point each concrete command has a 'List<String[]> execute(String[])' where the individual query functionality is implemented. In the return type ach element of the String[] represents a column, and each element of the list is a seperate row. Obviously insert/update/delete queries only return a result code so there is a choice here. Seperate the whole thing into two command patterns or treat every query equally and just use the ouput appropiately and consistantly. Services (appendix B) This is the second part of the model and encompasses everything else that needs to go on in the background. I can see two types of services that might need to be implemented: Scheduled services and triggered services. i.e. a service that runs at set intervals and services that are expressly triggered by the user.
  • 2. I have implemented the Scheduled Services part but not the Triggered Services part as yet. The Scheduled services are implemented using a class called ServiceScheduler, which creates a ScheduledThreadPoolExecutor (from the java.util.concurrent lib) and stores AbstractService derived types (AbstractService is an empty interface that implements runnable) in a List. It has an add(AbstractService, delay, rate) method so that each service can run at its own pre-specified interval, and delay; as well as a start method which iterates through the list calling the .get() method on each services ScheduledFuture<?>, fairly self explanatory. As I said I have not implemented the triggered services yet as I dont know what the best way of doing this would be. View/presenter (appendix C) The View is Jetty based (embedded http server and servlet container). Currently the HTTP server has a fairly basic configuration (no SSL, no sessions, no auth) but I figured that could be configured at a later stage (jetty has built in database auth functionality, as well as support for SSL and sessions, and a bunch of other fun stuff). The HTTP Server is responsible for one servlet at the moment, cunningly named UIServlet. This UIServlet uses a View/Presenter Abstract factory to select an appropriate pair of View and Presenter based on the URL parameters passed to the servlets doGet method from individual HTTP requests. The concrete View objects are responsible for reading .html files located in a resources directory and providing a 'make' method for the presenter to use when putting a particular view together i.e. the make method returns a string representing the particular part of a view that has been requested header/footer/navbar/etc. As a result the presenters responsibility is two-fold, firstly to assemble the static part of the view (the static html from the concrete views) and to insert dynamic content from the database(using the JDBC implementation described earlier). They do all of this within their String present(AbstractView) methods. The Abstract factory class brings this all together so that the UIServlet can do its job of selecting the appropriate view based on the URL query strings from an http request. I hope that this has been at least relatively clear. I know its a lot trying to get an overview of the system as is in a couple of pages. I have included appendices after this if it helps. jpchansondev@gmail.com jpchanson@tomoparts.co.uk 07796311906
  • 3. Appendix A Connection Manager /** * This class provides access to a pool of database connections. It is a threadsafe singleton * so always use the instance method to get an instance of this class, NEVER STORE THE INSTANCE. * @author Jan P.C. Hanson * */ public class ConnectionManager { /**Singleton instance with eager instanciation**/ private static ConnectionManager test = new ConnectionManager(); /**C3P0 Data pool**/ private ComboPooledDataSource cpds; /** * singleton contstructor, initialises the connection pool */ private ConnectionManager() { cpds = new ComboPooledDataSource(); try {cpds.setDriverClass("com.mysql.jdbc.Driver");} catch (PropertyVetoException e) {e.printStackTrace();} cpds.setJdbcUrl("jdbc:mysql://192.168.0.202:3306/ebay"); cpds.setUser("openDMS"); cpds.setPassword("0p3nDMS/*-"); cpds.setMinPoolSize(3); cpds.setAcquireIncrement(5); cpds.setMaxPoolSize(20); cpds.setMaxStatements(180); } /** * instance method returns an instance of the ConnectionManager class * @return ConnectionManager instance */ public static ConnectionManager instance() {return test;} /** * retrieves a database connection from the pool of available connections. When * Connection.close is called the connection is returned to the pool. * @return * @throws SQLException */ public Connection getConnection() throws SQLException {return this.cpds.getConnection();} }
  • 4. Database Query (invoker) public class DatabaseQuery { /**map of commands**/ private Map<QueryType, AbstractDBQuery> commandMap_M; /**defensive enum for map**/ public enum QueryType { SELECT_EBAY_ORDERS, INSERT_EBAY_ORDERS } /** * constructor, initialises the internal map. */ public DatabaseQuery() { super(); this.commandMap_M = new HashMap<QueryType, AbstractDBQuery>(); this.populateMap(); } /** * * @param command enum value taken from the internal enum 'QueryType' represents the type * of query that you wish to execute. * @param parameters a string array containing the parameters for the query in question. * Not all queries require parameters whereas others do. Check the concrete query type * documentation for more information * @return List<String[]> the position within the list defines the row, and the position * withing the string array defines the column so list index 0, array index 2 would be the * 3rd column of the 1st row. * @throws SQLException */ public List<String[]> execute(QueryType command, String[] parameters) throws SQLException {return this.commandMap_M.get(command).execute(parameters);} /** * populates the map with the concrete AbstractDBQuery Types. */ private void populateMap() { this.commandMap_M.put(DatabaseQuery.QueryType.SELECT_EBAY_ORDERS, new SelectEbayOrders()); this.commandMap_M.put(DatabaseQuery.QueryType.INSERT_EBAY_ORDERS, new InsertEbayOrders()); } Abstract Command interface /**
  • 5. * Interface that all database queries must adhere to. this is the Abstract command class for * this command pattern. * @author Jan P.C. Hanson * */ public interface AbstractDBQuery { /** * executes the query. * @param Parameter(s) to use in the query, see concrete type's class documentation for more * information * @return String representing the output of a particular query. */ public List<String[]> execute(String[] Parameter) throws SQLException; } Concrete Ebay Command Select Example public class SelectEbayOrders implements AbstractDBQuery { /**reference to the JDBC Statement**/ private PreparedStatement statement_M = null; /**reference to the JDBC Database connection**/ private Connection connection_M = null; /**SQL query string**/ private static final String query = "SELECT * FROM ebay.ebay_buyers;"; /** * default constructor */ public SelectEbayOrders() {super();} /** * execute the query * @param parameter NOT USED for this query. * @return String representing the results of the query. * @throws SQLException */ public List<String[]> execute(String[] parameter) throws SQLException { this.initQuery(); ResultSet resultset = statement_M.executeQuery(query); List<String[]> result = this.formatResults(resultset); this.connection_M.commit(); this.cleanup(); return result; } /** * formats the ResultSet (returned from the executed query) as a string * @param results the ResultSet (post query execution)
  • 6. * @return String containing the formatted results. * @throws SQLException */ private List<String[]> formatResults(ResultSet results) throws SQLException { List<String[]> rows = new ArrayList<String[]>(); while (results.next()) { String[] cols = new String[4]; cols[0] = results.getString("buyerID"); cols[1] = results.getString("name"); cols[2] = results.getString("shippingAddress"); cols[3] = results.getString("invoiceAddress"); rows.add(cols); } return rows; } /** * initialise the connection and statement and set transaction variables. * @throws SQLException */ private void initQuery() throws SQLException { this.connection_M = ConnectionManager.instance().getConnection(); this.connection_M.setAutoCommit(false); statement_M = connection_M.prepareStatement(query); } /** * do cleanup after the query has been executed * @throws SQLException */ private void cleanup() throws SQLException { if (statement_M != null) {statement_M.close();System.out.println("closing statement");} if (connection_M != null) {connection_M.close();System.out.println("closing connection");} } } Concrete Command Insert Example public class InsertEbayOrders implements AbstractDBQuery { /**reference to the JDBC Statement**/ private PreparedStatement statement_M = null; /**reference to the JDBC Database connection**/ private Connection connection_M = null; /**SQL query string**/ private String query ="INSERT IGNORE INTO ebay.ebay_orders (orderID, transactionID, buyerID, salesRecNo, shippingType, createdTime)" + "VALUES (?,?,?,?,?,?);"; /** * default constructor */
  • 7. public InsertEbayOrders() {super();} /** * execute the query * @param parameter an array of strings where the 0th element is the parameter for the * first column, the 1st element is the parameter for the 2nd column and so on. The Ebay * Orders Table only has 6 columns so any element above the 3rd element will be ignored. * col1 =orderID:int(30), col2=transactionID:int(20), col3=buyerID:varchar(40), * col4=salesRecNo:int(10), col5=shippingType:varchar(200), col6=createdTine:datetime * @return List<String> representing the results of the query. * @throws SQLException */ public List<String[]> execute(String[] parameter) throws SQLException { this.initQuery(); this.connection_M.prepareStatement(query); this.statement_M.setInt(1, 0000); this.statement_M.setInt(2, 1111); this.statement_M.setString(3, "kirk"); this.statement_M.setInt(4, 42); this.statement_M.setString(5, "carrier pidgeon"); java.util.Date date = new Date(); java.sql.Date sqlDate = new java.sql.Date(date.getTime()); this.statement_M.setTimestamp(6, new java.sql.Timestamp(date.getTime())); // this.statement_M.setInt(6, 20151013); int resultCode = statement_M.executeUpdate(); this.connection_M.commit(); this.cleanup(); List<String[]> res = new ArrayList<String[]>(); res.add(new String[] {resultCode + ""}); return res; } /** * initialise the connection and statement and set transaction variables. * @throws SQLException */ private void initQuery() throws SQLException { this.connection_M = ConnectionManager.instance().getConnection(); this.connection_M.setAutoCommit(false); statement_M = connection_M.prepareStatement(query); } /** * do cleanup after the query has been executed * @throws SQLException */
  • 8. private void cleanup() throws SQLException { if (statement_M != null) {statement_M.close();System.out.println("closing statement");} if (connection_M != null) {connection_M.close();System.out.println("closing connection");} Appendix B Service Scheduler public class ServicesScheduler { /****/ ScheduledThreadPoolExecutor serviceScheduler_M; /****/ List<ScheduledFuture<?>> services_M; /** * * @param noOfThreads */ public ServicesScheduler(int noOfThreads) { this.serviceScheduler_M = new ScheduledThreadPoolExecutor(noOfThreads); this.serviceScheduler_M.setMaximumPoolSize(noOfThreads+2); this.services_M = new ArrayList<ScheduledFuture<?>>(); } /** * * @param service */ public void add(AbstractService service, long delay, long rate) { this.services_M.add(this.serviceScheduler_M.scheduleWithFixedDelay(service, delay, rate, TimeUnit.MINUTES)); } /** * */ public void start() { try { for(int i = 0 ; i < this.services_M.size() ; ++i) { this.services_M.get(i).get(); } } catch(InterruptedException | ExecutionException e) {e.printStackTrace();} serviceScheduler_M.shutdown();
  • 9. } } Abstract Service Interface /** * Convienience interface, allows the system to only accept runnable's that implement this * interface rather than all runnables. * @author Jan P.C. Hanson * */ public interface AbstractService extends Runnable { public void run(); } eBay Service example /** * This class represents the start of the execution flow for the eBay Service, The service * quereies the eBay API for Order and Item information and * @author Jan P.C. Hanson * */ public class EbayService implements AbstractService { /* (non-Javadoc) * @see java.lang.Runnable#run() */ @Override public void run() { //index 0 = blank, index 1 = sandbox server string, index 2 = sandbox user token //index 3 = production server string, index 4 = production user token. String[] credentials = ConfigReader.read("./config/", "ebay.cfg"); OrdersCall oCall = new OrdersCall(credentials[4], credentials[3]); try { // OrderType[] orders = oCall.call(1); this.insertOrders(); this.insertTransactions(); this.insertBuyers(); this.insertItems(); } // catch (ApiException e) // {e.printStackTrace();} // catch (SdkException e) // {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} } private void insertOrders() throws SQLException {
  • 10. InsertEbayOrders iOrd = new InsertEbayOrders(); iOrd.execute(new String[] {}); } private void insertTransactions() { } private void insertBuyers() { } private void insertItems() { } } Appendix C Servlet public class UIServlet extends HttpServlet { /**needed to avoid warnings**/ private static final long serialVersionUID = -417534770555839323L; /** * instantiates a servlet using the views provided. * @param views */ public UIServlet() {super();} /** * service method, this controls how the servlet responds to particular URL query strings * @param request the http request to the servlet * @param response the http response to the servlet */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); // ViewPresenterFactory viewPresenterFactory = ViewPresenterFactory.instance(); AbstractViewPresenterFactory factory; String viewParam = request.getParameter("view"); if (ViewPresenterFactory.instance().hasFactory(viewParam)==true) { factory = ViewPresenterFactory.instance().getFactory(viewParam);
  • 11. out.print(factory.makePresenter().present(factory.makeView())); } else { factory = ViewPresenterFactory.instance().getFactory("ROOT"); out.print(factory.makePresenter().present(factory.makeView())); } out.close(); } } Abstract Factory interface /** * the interface that all concrete factories should subscribe to. * @author Jan P.C. Hanson * */ public interface AbstractViewPresenterFactory { /** * factory method that creates a view * @return AbstractView the view that has been requested */ public AbstractView makeView(); /** * factory method that creates a presenter * @return AbstractPresenter the presenter than has been requested. */ public AbstractPresenter makePresenter(); } concrete Factory for eBay View/Presenter /** * EbayAbstractFactory creates the presenter and view for the eBay view. * @author Jan P.C. Hanson * */ public class EbayFactory implements AbstractViewPresenterFactory { /* (non-Javadoc) * @see openDMS.helpers.viewPresenterFactory.AbstractViewPresenterFactory#makeView() */ @Override public AbstractView makeView() {return new EbayView();} /* (non-Javadoc) * @see openDMS.helpers.viewPresenterFactory.AbstractViewPresenterFactory#makePresenter() */ @Override
  • 12. public AbstractPresenter makePresenter() {return new EbayPresenter();} } concrete Factory for root view/presenter /** * RootAbstractFactory creates the presenter and view for the root view. * @author Jan P.C. Hanson * */ public class RootFactory implements AbstractViewPresenterFactory { /* (non-Javadoc) * @see openDMS.helpers.viewPresenterFactory.AbstractViewPresenterFactory#makeView() */ @Override public AbstractView makeView() {return new RootView();} /* (non-Javadoc) * @see openDMS.helpers.viewPresenterFactory.AbstractViewPresenterFactory#makePresenter() */ @Override public AbstractPresenter makePresenter() {return new RootPresenter();} } Abstract Factory implementation public class ViewPresenterFactory { /**Singleton instance variable**/ private static final ViewPresenterFactory instance_M = new ViewPresenterFactory(); /**enum to use for factory creation options**/ public enum Select {ROOT, EBAY} /**map of enum constants to concrete factories**/ Map<Select, AbstractViewPresenterFactory> factory_M; /** * default constructor */ private ViewPresenterFactory() { super(); factory_M = new HashMap<Select, AbstractViewPresenterFactory>(); this.populateMap(); } /** * singleton instance method, returns an instance of this object.
  • 13. * @return ViewPresenterFactory the singleton instance. */ public static ViewPresenterFactory instance() {return ViewPresenterFactory.instance_M;} /** * creates a specific factory based on the string provided. * @param factory string that is compared to enum values. * @return AbstractViewPresenterFactory a concrete viewPresenterFactory */ public AbstractViewPresenterFactory getFactory(String factory) {return this.factory_M.get(ViewPresenterFactory.Select.valueOf(factory));} /** * check to see if a factory type exists by comparing the string provided to the * internal enum 'Select' * @param factory the string to compare to the internal enum * @return boolean true if the factory is a valid type, false otherwise. */ public boolean hasFactory(String factory) { if (factory == null) {return false;} else if (Select.valueOf(factory) != null) {return true;} else {return false;} } /** * populate the internal map with viewPresenterFactories. */ private void populateMap() { this.factory_M.put(ViewPresenterFactory.Select.ROOT, new RootFactory()); this.factory_M.put(ViewPresenterFactory.Select.EBAY, new EbayFactory()); } } public interface AbstractView { /** * This method constructs the part of the view that is requested in the parameters. * @param part should be taken from the internal Enum defined within this class. Each enum * constant refers to a specific part of the view. * @return String containing the HTML for the part of the view that has been requested. */ public String make(AbstractViewPart part); } Views interface /**
  • 14. * This interface provides a root for all enums needed for the AbstractView derived objects * @author Jan P.C. Hanson * */ public interface AbstractViewPart { /**root enum, to be implemented by the enums inside the Abstract view derived classes**/ public enum Part {}; } concrete view 1 public class EbayView implements AbstractView { /**mapping of enum constant keys to html strings**/ private Map<Part, String> viewPart_M; /**enum containing constants relating to the view parts**/ public enum Part implements AbstractViewPart{HEADER, FOOTER}; /** * default constructor */ public EbayView() { super(); viewPart_M = new HashMap<Part, String>(); this.populateMap(); } /* (non-Javadoc) * @see openDMS.view.AbstractView#make(openDMS.view.AbstractView.PART) */ @Override public String make(AbstractViewPart part) {return this.viewPart_M.get(part);} /** * populates the map with the */ protected void populateMap() { this.viewPart_M.put(EbayView.Part.HEADER, FileToString.convert("./res/ebay/", "eBayHeader.html", "utf-8")); this.viewPart_M.put(EbayView.Part.FOOTER, FileToString.convert("./res/ebay/", "eBayFooter.html", "utf-8")); } } concrete view 2 public class RootView implements AbstractView { /**mapping of enum constant keys to html strings**/ private Map<Part, String> viewPart_M;
  • 15. /**enum containing constants relating to the view parts**/ public enum Part implements AbstractViewPart{INDEX} public RootView() { super(); viewPart_M = new HashMap<Part, String>(); this.populateMap(); } /* (non-Javadoc) * @see openDMS.view.AbstractView#make(openDMS.view.AbstractViewPart) */ @Override public String make(AbstractViewPart part) {return this.viewPart_M.get(part);} private void populateMap() { this.viewPart_M.put(RootView.Part.INDEX, FileToString.convert("./res/", "index.html", "utf-8")); } } presenter interface public interface AbstractPresenter { /** * this method is called when you actually want to present the information contained in the * view/presenter to the servlet * @param view the view to be rpesented * @return String representing the html contained in the view/presenter */ public String present(AbstractView view); } cocnrete presenter 2 public class RootPresenter implements AbstractPresenter { /** * default constructor */ public RootPresenter() {super();} /* (non-Javadoc) * @see openDMS.presenters.AbstractPresenter#present(openDMS.view.views.AbstractView) */ @Override public String present(AbstractView view) { String output = "";
  • 16. output += view.make(RootView.Part.INDEX); System.out.println("Root page loaded"); return output; } } concrete presenter 1 public class EbayPresenter implements AbstractPresenter { /** * default constructor */ public EbayPresenter() {super();} /* (non-Javadoc) * @see openDMS.presenters.AbstractPresenter#present(openDMS.view.views.AbstractView) */ @Override public String present(AbstractView view) { String output = ""; output += view.make(EbayView.Part.HEADER); output += this.doStuff(); output += view.make(EbayView.Part.FOOTER); return output; } private String doStuff() { String result = ""; try { DatabaseQuery query = new DatabaseQuery(); query.execute(DatabaseQuery.QueryType.INSERT_EBAY_ORDERS, new String[] {}); List<String[]> rows = query.execute(DatabaseQuery.QueryType.SELECT_EBAY_ORDERS,new String[] {""}); result+= "<table class='table table-bordered'> n"; result+= "<thead>n<tr>n" + "<th>ID</th>n" + "<th>name</th>n" + "<th>Shipping Address</th>n" + "<th>Invoice Address</th>n" + "</tr>n</thead>n <tbody>"; for (String[] cols : rows) { result+="<tr>n";
  • 17. result+="<td>"+ cols[0].trim() + "</td>n"; result+="<td>"+ cols[1].trim() + "</td>n"; result+="<td>"+ cols[2].trim() + "</td>n"; result+="<td>"+ cols[3].trim() + "</td>n"; result+="</tr>n"; } result+="</tbody>n</table>"; } catch(SQLException e) {e.printStackTrace();} return "<h1> eBay </h1> n <a class='btn btn-default' href='/'>Root</a><br/>n" + result; } }