| /* |
| * 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.rest.app; |
| import java.sql.Connection; |
| import java.sql.DriverManager; |
| import java.sql.SQLException; |
| import java.util.HashMap; |
| import java.util.LinkedList; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Queue; |
| import java.util.ResourceBundle; |
| |
| import javax.servlet.ServletContext; |
| import javax.servlet.ServletContextEvent; |
| import javax.servlet.ServletContextListener; |
| |
| import org.apache.empire.commons.StringUtils; |
| import org.apache.empire.db.DBCommand; |
| import org.apache.empire.db.DBContext; |
| import org.apache.empire.db.DBRecord; |
| import org.apache.empire.db.context.DBContextStatic; |
| import org.apache.empire.dbms.DBMSHandler; |
| import org.apache.empire.rest.service.Service; |
| import org.apache.empire.vue.sample.db.SampleDB; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| public class SampleServiceApp |
| { |
| private static final Logger log = LoggerFactory.getLogger(SampleServiceApp.class); |
| |
| /** |
| * Implementation of ServletContextListener which create the SampleServiceApp Singleton |
| * @author doebele |
| */ |
| public static class ContextListener implements ServletContextListener { |
| |
| @Override |
| public void contextInitialized(ServletContextEvent sce) { |
| |
| System.out.println("ServletContextListener:contextInitialized"); |
| // check singleton |
| if (app!=null) |
| throw new RuntimeException("FATAL: SampleServiceApp already created!"); |
| // create application |
| ServletContext ctx = sce.getServletContext(); |
| app = new SampleServiceApp(ctx); |
| // done |
| log.debug("SampleServiceApp created sucessfully!"); |
| } |
| |
| @Override |
| public void contextDestroyed(ServletContextEvent sce) { |
| System.out.println("ServletContextListener:contextDestroyed"); |
| } |
| } |
| |
| private static SampleServiceApp app; |
| |
| public static SampleServiceApp instance() |
| { |
| return app; |
| } |
| |
| private SampleConfig config = new SampleConfig(); |
| |
| private Map<Locale, ResourceTextResolver> textResolverMap = new HashMap<Locale, ResourceTextResolver>(); |
| |
| protected SampleServiceApp(ServletContext ctx) |
| { |
| // Logging |
| config.init(ctx.getRealPath("WEB-INF/config.xml")); |
| |
| String messageBundle ="lang.messages"; |
| textResolverMap.put(Locale.ENGLISH, new ResourceTextResolver(ResourceBundle.getBundle(messageBundle, Locale.ENGLISH))); |
| textResolverMap.put(Locale.GERMAN, new ResourceTextResolver(ResourceBundle.getBundle(messageBundle, Locale.GERMAN))); |
| |
| // get connection |
| Connection conn = getJDBCConnection(ctx); |
| try { |
| // DB |
| DBMSHandler dbms = getDBMSHandler(config.getDatabaseProvider(), conn); |
| DBContext context = new DBContextStatic(dbms, conn); |
| SampleDB db = initDatabase(ctx, context); |
| // Add to context |
| ctx.setAttribute(Service.Consts.ATTRIBUTE_DB, db); |
| // sce.getServletContext().setAttribute(MobileImportServiceConsts.ATTRIBUTE_DATASOURCE, ds); |
| // sce.getServletContext().setAttribute(MobileImportServiceConsts.ATTRIBUTE_CONFIG, config); |
| } finally { |
| releaseConnection(conn, true); |
| } |
| } |
| |
| public TextResolver getTextResolver(Locale locale) { |
| TextResolver tr = textResolverMap.get(locale); |
| return (tr!=null ? tr : textResolverMap.get(Locale.ENGLISH)); |
| } |
| |
| /** |
| * 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); |
| } |
| } |
| |
| /* |
| * Our own simple Connection pool |
| */ |
| private final Queue<Connection> connPool = new LinkedList<Connection>(); |
| |
| /* |
| * getJDBCConnection |
| */ |
| public Connection getJDBCConnection(ServletContext appContext) |
| { |
| Connection conn = connPool.poll(); |
| if (conn!=null) |
| return conn; |
| |
| // Establish a new database connection |
| 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()); |
| return conn; |
| } |
| catch (Exception e) |
| { |
| log.error("Failed to connect directly to '" + config.getJdbcURL() + "' / User=" + config.getJdbcUser()); |
| log.error(e.toString()); |
| throw new RuntimeException(e); |
| } |
| } |
| |
| public void releaseConnection(Connection conn, boolean commit) { |
| // release connection |
| try |
| { // release connection |
| if (conn == null) |
| { |
| return; |
| } |
| // Commit or rollback connection depending on the exit code |
| if (commit) |
| { // success: commit all changes |
| conn.commit(); |
| log.debug("REQUEST commited."); |
| } |
| else |
| { // failure: rollback all changes |
| conn.rollback(); |
| log.debug("REQUEST rolled back."); |
| } |
| // close connection / return to pool |
| // conn.close(); |
| connPool.add(conn); |
| } |
| catch (SQLException e) |
| { |
| log.error("Error releasing connection", e); |
| throw new RuntimeException(e); |
| } |
| } |
| |
| |
| // ********************* private ********************* |
| |
| private SampleDB initDatabase(ServletContext ctx, DBContext context) { |
| SampleDB db = new SampleDB(); |
| // Open Database (and create if not existing) |
| DBMSHandler dbms = context.getDbms(); |
| log.info("Opening database '{}' using handler '{}'", db.getClass().getSimpleName(), dbms.getClass().getSimpleName()); |
| db.open(context); |
| // check if database was just created |
| DBCommand cmd = context.createCommand(); |
| cmd.select(db.EMPLOYEES.count()); |
| if (context.getUtils().querySingleInt(cmd)==0) |
| { // Populate Database |
| populateDatabase(db, context); |
| } |
| return db; |
| } |
| |
| private static void populateDatabase(SampleDB db, DBContext context) { |
| // Insert Sample Departments |
| insertDepartmentSampleRecord(db, context, "Procurement", "ITTK"); |
| int idDevDep = insertDepartmentSampleRecord(db, context, "Development", "ITTK"); |
| int idSalDep = insertDepartmentSampleRecord(db, context, "Sales", "ITTK"); |
| // Insert Sample Employees |
| insertEmployeeSampleRecord(db, context, "Mr.", "Eugen", "Miller", "M", idDevDep); |
| insertEmployeeSampleRecord(db, context, "Mr.", "Max", "Mc. Callahan", "M", idDevDep); |
| insertEmployeeSampleRecord(db, context, "Mrs.", "Anna", "Smith", "F", idSalDep); |
| // Commit |
| context.commit(); |
| } |
| |
| private static int insertDepartmentSampleRecord(SampleDB db, DBContext context, String department_name, String businessUnit) { |
| // Insert a Department |
| DBRecord rec = new DBRecord(context, db.DEPARTMENTS); |
| rec.create(); |
| rec.set(db.DEPARTMENTS.NAME, department_name); |
| rec.set(db.DEPARTMENTS.BUSINESS_UNIT, businessUnit); |
| try { |
| rec.update(); |
| } catch (Exception e) { |
| log.error(e.getLocalizedMessage()); |
| return 0; |
| } |
| // Return Department ID |
| return rec.getInt(db.DEPARTMENTS.ID); |
| } |
| |
| /* |
| * Insert a person |
| */ |
| private static int insertEmployeeSampleRecord(SampleDB db, DBContext context, String salutation, String firstName, String lastName, String gender, int depID) { |
| // Insert an Employee |
| DBRecord rec = new DBRecord(context, db.EMPLOYEES); |
| rec.create(); |
| rec.set(db.EMPLOYEES.SALUTATION, salutation); |
| rec.set(db.EMPLOYEES.FIRST_NAME, firstName); |
| rec.set(db.EMPLOYEES.LAST_NAME, lastName); |
| rec.set(db.EMPLOYEES.GENDER, gender); |
| rec.set(db.EMPLOYEES.DEPARTMENT_ID, depID); |
| try { |
| rec.update(); |
| } catch (Exception e) { |
| log.error(e.getLocalizedMessage()); |
| return 0; |
| } |
| // Return Employee ID |
| return rec.getInt(db.EMPLOYEES.ID); |
| } |
| |
| /* |
| private void initLogging() { |
| |
| // Init Logging |
| ConsoleAppender consoleAppender = new ConsoleAppender(); |
| String pattern = "%-5p [%d{yyyy/MM/dd HH:mm}]: %m at %l %n"; |
| consoleAppender.setLayout(new PatternLayout(pattern)); |
| consoleAppender.activateOptions(); |
| |
| org.apache.log4j.Logger.getRootLogger().addAppender(consoleAppender); |
| org.apache.log4j.Logger.getRootLogger().setLevel(Level.ALL); |
| |
| Level loglevel = Level.DEBUG; |
| log.info("Setting LogLevel to {}", loglevel); |
| |
| // RootLogger |
| org.apache.log4j.Logger.getRootLogger().setLevel(Level.INFO); |
| |
| // Empire-db Logs |
| org.apache.log4j.Logger empireLog = org.apache.log4j.Logger.getLogger("org.apache.empire.db.DBDatabase"); |
| empireLog.setLevel(loglevel); |
| |
| // Vue.js Sample |
| org.apache.log4j.Logger miLog = org.apache.log4j.Logger.getLogger("org.apache.empire.rest"); |
| miLog.setLevel(loglevel); |
| } |
| */ |
| |
| } |