All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kawanfw.sql.servlet.ServerSqlManager Maven / Gradle / Ivy

/*
 * 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
//				    + "  \"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: [email protected]";
	    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
     */
    private 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);
	    }
	}
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy