Java tutorial
/* * This file is part of AceQL. * AceQL: Remote JDBC access over HTTP. * Copyright (C) 2015, KawanSoft SAS * (http://www.kawansoft.com). All rights reserved. * * AceQL is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * AceQL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * Any modifications to this file must keep this entire header * intact. */ package org.kawanfw.sql.servlet; import static org.kawanfw.file.servlet.ServerFileManager.COMMONS_CONFIGURATOR_CLASS_NAME; import static org.kawanfw.file.servlet.ServerFileManager.FILE_CONFIGURATOR_CLASS_NAME; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.kawanfw.commons.api.server.CommonsConfigurator; import org.kawanfw.commons.api.server.DefaultCommonsConfigurator; import org.kawanfw.commons.server.util.ServerLogger; import org.kawanfw.commons.server.util.embed.TomcatModeStore; import org.kawanfw.commons.util.FrameworkDebug; import org.kawanfw.commons.util.Tag; import org.kawanfw.commons.util.TransferStatus; import org.kawanfw.file.api.server.DefaultFileConfigurator; import org.kawanfw.file.api.server.FileConfigurator; import org.kawanfw.file.servlet.RequestInfoStore; import org.kawanfw.file.servlet.ServerFileManager; import org.kawanfw.file.servlet.convert.HttpServletRequestConvertor; import org.kawanfw.sql.api.server.DefaultSqlConfigurator; import org.kawanfw.sql.api.server.SqlConfigurationException; import org.kawanfw.sql.api.server.SqlConfigurator; import org.kawanfw.sql.tomcat.ServletParametersStore; import org.kawanfw.sql.tomcat.TomcatStarterUtil; import org.kawanfw.sql.util.SqlTag; import org.kawanfw.sql.version.Version; /** * Http JDBC Server * * @author Nicolas de Pomereu */ @SuppressWarnings("serial") public class ServerSqlManager extends HttpServlet { private static boolean DEBUG = FrameworkDebug.isSet(ServerSqlManager.class); public static String CR_LF = System.getProperty("line.separator"); public static final String SQL_CONFIGURATOR_CLASS_NAME = "sqlConfiguratorClassName"; private CommonsConfigurator commonsConfigurator = null; private FileConfigurator fileConfigurator = null; private SqlConfigurator sqlConfigurator = null; /** Says that the ServerLogger is ok and we can log the exceptions */ private boolean serverLoggerOk = false; /** The Exception thrown at init */ private Exception exception = null; /** The init error message trapped */ private String initErrrorMesage = null; /** Required to pass license parameters at doPost() */ private Properties properties; /** * Init */ public void init(ServletConfig config) throws ServletException { super.init(config); // Variable use to store the current name when loading, used to // detail // the exception in the catch clauses String classNameToLoad = null; String commonsConfiguratorClassName; String fileConfiguratorClassName; String sqlConfiguratorClassName; String servletName = this.getServletName(); String index = null; if (!TomcatModeStore.isTomcatEmbedded()) { System.out.println(SqlTag.SQL_PRODUCT_START + " " + Version.getServerVersion()); } // We are in SQL Framework TomcatModeStore.setFrameworkSql(true); try { if (!TomcatModeStore.isTomcatEmbedded()) { String propertiesFileStr = config.getInitParameter("properties"); if (propertiesFileStr == null || propertiesFileStr.isEmpty()) { String aceqlHome = System.getenv("ACEQL_HOME"); if (aceqlHome != null) { // Remove surrounding " if present aceqlHome = aceqlHome.replaceAll("\"", ""); if (aceqlHome.endsWith(File.separator)) { aceqlHome = StringUtils.substringBeforeLast(aceqlHome, File.separator); } propertiesFileStr = aceqlHome + File.separator + "conf" + File.separator + "aceql-server.properties"; } else { throw new SqlConfigurationException(Tag.PRODUCT_USER_CONFIG_FAIL + " ACEQL_HOME property not set. Impossible to use the default ACEQL_HOME" + File.separator + "conf" + File.separator + "aceql-server.properties file"); } // throw new SqlConfigurationException( // Tag.PRODUCT_USER_CONFIG_FAIL // + " <param-name> \"properties\" not found for servlet " // + servletName); } File propertiesFile = new File(propertiesFileStr); if (!propertiesFile.exists()) { throw new SqlConfigurationException( Tag.PRODUCT_USER_CONFIG_FAIL + " properties file not found: " + propertiesFile); } System.out.println(SqlTag.SQL_PRODUCT_START + " " + "Using properties file: " + propertiesFile); properties = TomcatStarterUtil.getProperties(propertiesFile); index = TomcatStarterUtil.getIndexFromServletName(properties, servletName); TomcatStarterUtil.setInitParametersInStore(properties, index); // Create the default DataSource if necessary TomcatStarterUtil.createAndStoreDataSource(properties, index); } commonsConfiguratorClassName = ServletParametersStore.getInitParameter(servletName, COMMONS_CONFIGURATOR_CLASS_NAME); fileConfiguratorClassName = ServletParametersStore.getInitParameter(servletName, FILE_CONFIGURATOR_CLASS_NAME); sqlConfiguratorClassName = ServletParametersStore.getInitParameter(servletName, SQL_CONFIGURATOR_CLASS_NAME); debug("commonsConfiguratorClassName: " + commonsConfiguratorClassName); debug("fileConfiguratorClassName : " + fileConfiguratorClassName); debug("sqlConfiguratorClassName : " + sqlConfiguratorClassName); // Check spelling with first letter capitalized if (commonsConfiguratorClassName == null || commonsConfiguratorClassName.isEmpty()) { String capitalized = StringUtils.capitalize(ServerFileManager.COMMONS_CONFIGURATOR_CLASS_NAME); commonsConfiguratorClassName = ServletParametersStore.getInitParameter(servletName, capitalized); } if (fileConfiguratorClassName == null || fileConfiguratorClassName.isEmpty()) { String capitalized = StringUtils.capitalize(ServerFileManager.FILE_CONFIGURATOR_CLASS_NAME); fileConfiguratorClassName = ServletParametersStore.getInitParameter(servletName, capitalized); } if (sqlConfiguratorClassName == null || sqlConfiguratorClassName.isEmpty()) { String capitalized = StringUtils.capitalize(SQL_CONFIGURATOR_CLASS_NAME); sqlConfiguratorClassName = ServletParametersStore.getInitParameter(servletName, capitalized); } // Call the specific Configurator class to use classNameToLoad = commonsConfiguratorClassName; if (commonsConfiguratorClassName != null && !commonsConfiguratorClassName.isEmpty()) { Class<?> c = Class.forName(commonsConfiguratorClassName); commonsConfigurator = (CommonsConfigurator) c.newInstance(); } else { commonsConfigurator = new DefaultCommonsConfigurator(); } // Immediately create the ServerLogger Logger logger = null; try { logger = commonsConfigurator.getLogger(); ServerLogger.createLogger(logger); serverLoggerOk = true; } catch (Exception e) { exception = e; initErrrorMesage = Tag.PRODUCT_USER_CONFIG_FAIL + " Impossible to create the Logger: " + logger + ". Reason: " + e.getMessage(); } classNameToLoad = fileConfiguratorClassName; if (fileConfiguratorClassName != null && !fileConfiguratorClassName.isEmpty()) { Class<?> c = Class.forName(fileConfiguratorClassName); fileConfigurator = (FileConfigurator) c.newInstance(); } else { fileConfigurator = new DefaultFileConfigurator(); } classNameToLoad = sqlConfiguratorClassName; if (sqlConfiguratorClassName != null && !sqlConfiguratorClassName.isEmpty()) { Class<?> c = Class.forName(sqlConfiguratorClassName); sqlConfigurator = (SqlConfigurator) c.newInstance(); } else { sqlConfigurator = new DefaultSqlConfigurator(); } } catch (ClassNotFoundException e) { initErrrorMesage = Tag.PRODUCT_USER_CONFIG_FAIL + " Impossible to load (ClassNotFoundException) Configurator class: " + classNameToLoad; exception = e; } catch (InstantiationException e) { initErrrorMesage = Tag.PRODUCT_USER_CONFIG_FAIL + " Impossible to load (InstantiationException) Configurator class: " + classNameToLoad; exception = e; } catch (IllegalAccessException e) { initErrrorMesage = Tag.PRODUCT_USER_CONFIG_FAIL + " Impossible to load (IllegalAccessException) Configurator class: " + classNameToLoad; exception = e; } catch (SqlConfigurationException e) { initErrrorMesage = e.getMessage(); exception = e; } catch (Exception e) { initErrrorMesage = Tag.PRODUCT_PRODUCT_FAIL + " Please contact support at: support@kawansoft.com"; exception = e; } if (commonsConfigurator == null) { commonsConfiguratorClassName = COMMONS_CONFIGURATOR_CLASS_NAME; } else { commonsConfiguratorClassName = commonsConfigurator.getClass().getName(); } if (fileConfigurator == null) { fileConfiguratorClassName = FILE_CONFIGURATOR_CLASS_NAME; } else { fileConfiguratorClassName = fileConfigurator.getClass().getName(); } if (sqlConfigurator == null) { sqlConfiguratorClassName = SQL_CONFIGURATOR_CLASS_NAME; } else { sqlConfiguratorClassName = sqlConfigurator.getClass().getName(); } System.out.println(SqlTag.SQL_PRODUCT_START + " " + servletName + " Servlet Configurators:"); System.out.println( SqlTag.SQL_PRODUCT_START + " -> commonsConfiguratorClassName: " + commonsConfiguratorClassName); System.out.println( SqlTag.SQL_PRODUCT_START + " -> sqlConfiguratorClassName : " + sqlConfiguratorClassName); System.out.println( SqlTag.SQL_PRODUCT_START + " -> fileConfiguratorClassName : " + fileConfiguratorClassName); if (exception == null) { System.out.println(SqlTag.SQL_PRODUCT_START + " -> Configurators Status: OK."); } else { if (!TomcatModeStore.isTomcatEmbedded()) { String errorMessage1 = SqlTag.SQL_PRODUCT_START + " -> Configurators Status: KO."; String errorMessage2 = initErrrorMesage; String errorMessage3 = ExceptionUtils.getStackTrace(exception); System.out.println(errorMessage1); System.out.println(errorMessage2); System.out.println(errorMessage3); if (serverLoggerOk) { ServerLogger.getLogger().log(Level.WARNING, errorMessage1); ServerLogger.getLogger().log(Level.WARNING, errorMessage2); ServerLogger.getLogger().log(Level.WARNING, errorMessage3); } System.out.println(); } } } /** * Test the configurators main methods to see if they throw Exceptions */ /** * Get request. */ @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { request.setCharacterEncoding("UTF-8"); // Store the host info in RequestInfoStore RequestInfoStore.init(request); response.setContentType("text/html"); PrintWriter out = response.getWriter(); String servletName = this.getServletName(); if (commonsConfigurator != null) { debug("doGet commonsConfigurator: " + commonsConfigurator.getClass().getName()); } else { debug("doGet commonsConfigurator is null"); } if (fileConfigurator != null) { debug("doGet fileConfigurator : " + fileConfigurator.getClass().getName()); } else { debug("doGet fileConfigurator is null"); } if (sqlConfigurator != null) { debug("doGet sqlConfigurator : " + sqlConfigurator.getClass().getName()); } else { debug("doGet sqlConfigurator is null"); } // Must be done in doPost() and do Get() because we need // request.getServerName() // That is not available in init... // checkOnceLicenseInfo(request, commonsConfigurator); ServerSqlManagerDoGetTester serverSqlManagerDoGetTester = new ServerSqlManagerDoGetTester(); serverSqlManagerDoGetTester.doGetTest(servletName, out, exception, commonsConfigurator, fileConfigurator, sqlConfigurator); } /** * Post request. */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { request.setCharacterEncoding("UTF-8"); // Store the host info in RequestInfoStore RequestInfoStore.init(request); // If init fail, say it cleanly to client, instead of bad 500 Servlet // Error if (exception != null) { OutputStream out = response.getOutputStream(); writeLine(out, TransferStatus.SEND_FAILED); writeLine(out, exception.getClass().getName()); // Exception class // name writeLine(out, initErrrorMesage + " Reason: " + exception.getMessage()); // Exception // message writeLine(out, ExceptionUtils.getStackTrace(exception)); return; } debug("after RequestInfoStore.init(request);"); debug(request.getRemoteAddr()); // Configure a repository (to ensure a secure temp location is used) ServletContext servletContext = this.getServletConfig().getServletContext(); File servletContextTempDir = (File) servletContext.getAttribute("javax.servlet.context.tempdir"); // Wrap the HttpServletRequest with HttpServletRequestEncrypted for // parameters decryption HttpServletRequestConvertor requestEncrypted = new HttpServletRequestConvertor(request, commonsConfigurator); ServerSqlDispatch dispatch = new ServerSqlDispatch(); debug("before dispatch.executeRequest()"); dispatch.executeRequest(requestEncrypted, response, servletContextTempDir, commonsConfigurator, fileConfigurator, sqlConfigurator); } /** * Write a line of string on the servlet output stream. Will add the * necessary CR_LF * * @param out * the servlet output stream * @param s * the string to write * @throws IOException */ public static void writeLine(OutputStream out, String s) throws IOException { out.write((s + CR_LF).getBytes()); } /** * Method called by children Servlet for debug purpose Println is done only * if class name name is in kawansoft-debug.ini */ public static void debug(String s) { if (DEBUG) { try { ServerLogger.getLogger().log(Level.WARNING, s); } catch (Exception e1) { System.out.println(s); } } } }