blob: 00c4add6285a21ae752e5fd1348497394f4a0d90 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.empire.jsf2.websample.web;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.Locale;
import javax.servlet.ServletContext;
import javax.sql.DataSource;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.db.DBCommand;
import org.apache.empire.db.DBContext;
import org.apache.empire.db.DBDatabase;
import org.apache.empire.db.DBRecord;
import org.apache.empire.db.context.DBContextStatic;
import org.apache.empire.db.context.DBRollbackManager;
import org.apache.empire.db.context.DBRollbackManager.ReleaseAction;
import org.apache.empire.dbms.DBMSHandler;
import org.apache.empire.jsf2.app.WebApplication;
import org.apache.empire.jsf2.controls.InputControlManager;
import org.apache.empire.jsf2.custom.controls.FileInputControl;
import org.apache.empire.jsf2.websample.db.SampleDB;
import org.apache.empire.jsf2.websample.db.SampleDBwithMeta;
import org.apache.empire.jsf2.websample.web.pages.SamplePages;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SampleApplication extends WebApplication {
// Logger
private static final Logger log = LoggerFactory
.getLogger(SampleApplication.class);
protected static final String MANAGED_BEAN_NAME = "sampleApplication";
protected static final Locale DEFAULT_LOCALE = Locale.ENGLISH;
// Non-Static
private SampleConfig config = new SampleConfig();
private SampleDB sampleDB = null;
private Connection conn = null;
public static SampleApplication get() {
return (SampleApplication)WebApplication.getInstance();
}
public SampleApplication() {
// trace
SampleApplication.log.trace("SampleApplication created");
// register custom control types
InputControlManager.registerControl(new FileInputControl());
}
@Override
public void init(ServletContext servletContext) {
// register all controls
// InputControlManager.registerControl("myType", new
// MyTypeInputControl());
config.init(servletContext.getRealPath("WEB-INF/config.xml"));
// Get a JDBC Connection
log.info("*** getJDBCConnection() ***");
conn = getJDBCConnection(servletContext);
log.info("*** initDatabase() ***");
initDatabase();
log.info("*** initPages() ***");
initPages(servletContext);
// Set Database to Servlet Context
servletContext.setAttribute("db", sampleDB);
// Done
}
/*
* getJDBCConnection
*/
private Connection getJDBCConnection(ServletContext appContext)
{
// Establish a new database connection
Connection conn = null;
String jdbcURL = config.getJdbcURL();
if (jdbcURL.indexOf("file:") > 0)
jdbcURL = StringUtils.replace(jdbcURL, "file:", "file:" + appContext.getRealPath("/"));
// Connect
log.info("Connecting to Database'" + jdbcURL + "' / User=" + config.getJdbcUser());
try
{ // Connect to the database
Class.forName(config.getJdbcClass()).newInstance();
conn = DriverManager.getConnection(jdbcURL, config.getJdbcUser(), config.getJdbcPwd());
log.info("Connected successfully");
// set the AutoCommit to false this session. You must commit
// explicitly now
conn.setAutoCommit(false);
log.info("AutoCommit is " + conn.getAutoCommit());
}
catch (Exception e)
{
log.error("Failed to connect directly to '" + config.getJdbcURL() + "' / User=" + config.getJdbcUser());
log.error(e.toString());
throw new RuntimeException(e);
}
return conn;
}
private void initDatabase() {
// Create Database with Metadata!
sampleDB = new SampleDBwithMeta();
// Open Database (and create if not existing)
DBMSHandler dbmsHandler = getDBMSHandler(config.getDatabaseProvider(), conn);
log.info("Opening database '{}' using '{}'", sampleDB.getClass().getSimpleName(), dbmsHandler.getClass().getSimpleName());
Connection conn = null;
DBContext context = null;
try {
conn = getConnection(sampleDB);
context = new DBContextStatic(dbmsHandler, conn);
sampleDB.open(context);
// check if database was just created
DBCommand cmd = context.createCommand();
cmd.select(sampleDB.EMPLOYEES.count());
if (context.getUtils().querySingleInt(cmd)==0)
{ // Populate Database
populateDatabase(context);
}
} finally {
context.discard();
releaseConnection(conn, true, null);
}
}
/**
* Creates an Empire-db DatabaseDriver for the given provider and applies dbms specific configuration
*/
private DBMSHandler getDBMSHandler(String provider, Connection conn)
{
try
{ // Get Driver Class Name
String dbmsHandlerClass = config.getDbmsHandlerClass();
if (StringUtils.isEmpty(dbmsHandlerClass))
throw new RuntimeException("Configuration error: Element 'dbmsHandlerClass' not found in node 'properties-"+provider+"'");
// Create dbms
DBMSHandler dbms = (DBMSHandler) Class.forName(dbmsHandlerClass).newInstance();
// Configure dbms
config.readProperties(dbms, "properties-"+provider, "dbmsHandlerProperties");
// done
return dbms;
} catch (Exception e)
{ // catch any checked exception and forward it
e.printStackTrace();
throw new RuntimeException(e);
}
}
private void initPages(ServletContext sc) {
// register Page Beans
new SamplePages().registerPageBeans(this.getFacesImplementation());
}
public SampleDB getDatabase() {
return sampleDB;
}
/*
* creates a DDL Script for the entire SampleDB Database then checks if the
* department table exists by running "select count(*) from DEPARTMENTS" if
* the department tables does not exist, the entire dll-script is executed
* line by line
*/
private void populateDatabase(DBContext context) {
// Insert Sample Departments
insertDepartmentSampleRecord(context, "Procurement", "ITTK");
int idDevDep = insertDepartmentSampleRecord(context, "Development", "ITTK");
int idSalDep = insertDepartmentSampleRecord(context, "Sales", "ITTK");
// Insert Sample Employees
insertEmployeeSampleRecord(context, "Mr.", "Eugen", "Miller", "M", 30000, idDevDep);
insertEmployeeSampleRecord(context, "Mr.", "Max", "Mc. Callahan", "M", 22500, idDevDep);
insertEmployeeSampleRecord(context, "Mrs.", "Anna", "Smith", "F", 44250, idSalDep);
// Commit
context.commit();
}
/*
* Insert a department
*/
private int insertDepartmentSampleRecord(DBContext context, String department_name, String businessUnit) {
// Insert a Department
DBRecord rec = new DBRecord(context, sampleDB.DEPARTMENTS);
rec.create()
.set(sampleDB.DEPARTMENTS.NAME, department_name)
.set(sampleDB.DEPARTMENTS.BUSINESS_UNIT, businessUnit)
.update();
// Return Department ID
return rec.getInt(sampleDB.DEPARTMENTS.ID);
}
/*
* Insert a person
*/
private int insertEmployeeSampleRecord(DBContext context, String salutation, String firstName, String lastName, String gender, int salary, int depID) {
// Insert an Employee
SampleDB.TEmployees EMP = sampleDB.EMPLOYEES;
DBRecord rec = new DBRecord(context, sampleDB.EMPLOYEES);
rec.create()
.set(EMP.SALUTATION, salutation)
.set(EMP.FIRST_NAME, firstName)
.set(EMP.LAST_NAME, lastName)
.set(EMP.GENDER, gender)
.set(EMP.DEPARTMENT_ID, depID)
.set(EMP.SALARY, salary)
.update();
// insert Payments
insertPayments(rec);
// Return Employee ID
return rec.getInt(sampleDB.EMPLOYEES.ID);
}
/**
* <PRE>
* Inserts an Payments for a particular Employee
* </PRE>
*/
private void insertPayments(DBRecord employee)
{
if (employee.isNull(sampleDB.EMPLOYEES.SALARY))
return; // No salary
// monthlySalary
BigDecimal monthlySalary = employee.getDecimal(sampleDB.EMPLOYEES.SALARY).divide(new BigDecimal(12), 2, RoundingMode.HALF_UP);
// Insert an Employee
LocalDate date = LocalDate.now();
date = date.minusDays(date.getDayOfMonth()-1); // first day of this month
// Add Payment for each month
SampleDB.TPayments PAY = sampleDB.PAYMENTS;
DBRecord rec = new DBRecord(employee.getContext(), PAY);
int months = (int)(Math.random()*6)+11;
for (LocalDate month=date.minusMonths(months); !month.isAfter(date); month=month.plusMonths(1))
{
BigDecimal variation = new BigDecimal((Math.random()*200) - 100.0);
variation = variation.setScale(2, RoundingMode.HALF_UP);
// insert
rec.create(DBRecord.key(employee.getIdentity(), month.getYear(), month.getMonth()));
rec.set(PAY.AMOUNT, monthlySalary.add(variation));
rec.update();
}
}
@Override
/**
* returns null as connection pooling is not used
*/
protected DataSource getAppDataSource(DBDatabase db) {
return null;
}
/**
* Usually returns a connection from the connection pool
* As the sample does not use connection pooling, a static connection is returned
* @return a connection for the requested db
*/
@Override
protected Connection getConnection(DBDatabase db)
{
return conn;
}
/**
* Usually releases a connection from the connection pool
* As the sample does not use connection pooling, only a commit or rollback is performed
*/
@Override
protected void releaseConnection(Connection conn, boolean commit, DBRollbackManager dbrm)
{
try
{ // release connection
if (conn == null)
{
return;
}
log.trace("releasing Connection {}", conn.hashCode());
// Commit or rollback connection depending on the exit code
if (commit)
{ // success: commit all changes
if (dbrm!=null)
dbrm.releaseConnection(conn, ReleaseAction.Discard); // before commit
conn.commit();
log.debug("REQUEST commited.");
}
else
{ // failure: rollback all changes
conn.rollback();
if (dbrm!=null)
dbrm.releaseConnection(conn, ReleaseAction.Rollback); // after rollback
log.debug("REQUEST rolled back.");
}
// Release Connection (don't do that here!)
// conn.close();
// done
if (log.isDebugEnabled())
log.debug("Connection released but not closed.");
}
catch (SQLException e)
{
log.error("Error releasing connection", e);
e.printStackTrace();
}
}
protected SampleConfig getSampleConfig() {
if (config == null) {
SampleApplication.log
.error("Application configuration not initialized!");
}
return config;
}
}