| /* |
| * 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; |
| } |
| |
| } |