org.kawanfw.sql.servlet.executor.ServerSqlExecutorNew.java Source code

Java tutorial

Introduction

Here is the source code for org.kawanfw.sql.servlet.executor.ServerSqlExecutorNew.java

Source

/*
 * 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.executor;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.kawanfw.commons.api.server.CommonsConfigurator;
import org.kawanfw.commons.server.util.ServerLogger;
import org.kawanfw.commons.util.FrameworkDebug;
import org.kawanfw.commons.util.Tag;
import org.kawanfw.commons.util.TransferStatus;
import org.kawanfw.file.api.server.FileConfigurator;
import org.kawanfw.file.servlet.util.HttpConfigurationUtil;
import org.kawanfw.file.util.parms.Parameter;
import org.kawanfw.sql.api.server.SqlConfigurator;
import org.kawanfw.sql.json.StatementHolder;
import org.kawanfw.sql.servlet.ConnectionCloser;
import org.kawanfw.sql.servlet.ServerSqlManager;
import org.kawanfw.sql.servlet.connection.ConnectionStore;
import org.kawanfw.sql.servlet.sql.ServerSqlUtil;
import org.kawanfw.sql.servlet.sql.ServerStatement;
import org.kawanfw.sql.servlet.sql.ServerStatementRawExecute;
import org.kawanfw.sql.servlet.sql.StatementHolderListDecryptor;
import org.kawanfw.sql.servlet.sql.StatementHolderListReader;
import org.kawanfw.sql.transport.TransportConverter;
import org.kawanfw.sql.util.ConnectionParms;
import org.kawanfw.sql.util.SqlAction;
import org.kawanfw.sql.util.SqlReturnCode;

/**
 * O Execute transported statements on the server
 * 
 * @author Nicolas de Pomereu
 * 
 */
public class ServerSqlExecutorNew {
    private static boolean DEBUG = FrameworkDebug.isSet(ServerSqlExecutorNew.class);

    // When executing a non-query (Prepared) Statement
    public static final String STATEMENT_NORMAL_EXECUTED = "0";

    private HttpServletRequest request = null;
    private OutputStream out = null;

    private CommonsConfigurator commonsConfigurator = null;
    private FileConfigurator fileConfigurator = null;
    private SqlConfigurator sqlConfigurator = null;

    /** If true, we will ask to to a raw Statement.execute() */
    private boolean isExecuteRaw = false;

    /**
     * Constructor
     * 
     * @param request
     *            the servlet http request
     * @param out
     *            the servlet output stream
     * @param fileConfigurator
     *            the FILE Configurator
     * @param commonsConfigurator
     *            the Commons Configurator
     * @param sqlConfigurator
     *            the SQL Configurator
     */
    public ServerSqlExecutorNew(HttpServletRequest request, OutputStream out,
            CommonsConfigurator commonsConfigurator, FileConfigurator fileConfigurator,
            SqlConfigurator sqlConfigurator)

    {
        this.request = request;
        this.out = out;

        this.commonsConfigurator = commonsConfigurator;
        this.fileConfigurator = fileConfigurator;
        this.sqlConfigurator = sqlConfigurator;

    }

    /**
     * Execute the Sql Action
     */
    private void execute() throws IOException, SQLException, IllegalArgumentException {

        String username = request.getParameter(Parameter.USERNAME);
        String connectionId = request.getParameter(ConnectionParms.CONNECTION_ID);

        String conHolderParam = request.getParameter(SqlAction.CONNECTION_HOLDER);
        String statementHolderParam = request.getParameter(SqlAction.STATEMENT_HOLDER);

        debug("SqlAction.CONNECTION_HOLDER: " + conHolderParam);
        debug("SqlAction.STATEMENT_HOLDER : " + statementHolderParam);

        Connection connection = null;
        List<File> tempFilesForResultSet = new Vector<File>();

        if (connectionId.equals("0")) {
            try {
                connection = commonsConfigurator.getConnection();
                ServerSqlUtil.setConnectionProperties(conHolderParam, connection);

                if (statementHolderParam.startsWith(TransportConverter.KAWANFW_BYTES_STREAM_FILE)) {
                    String fileName = StringUtils.substringAfter(statementHolderParam,
                            TransportConverter.KAWANFW_BYTES_STREAM_FILE);
                    // Param contains only the file to read from the statements
                    executeStatementsFromFile(username, fileName, connection, tempFilesForResultSet);
                } else {
                    // All statements are in single param
                    executeStatementsFromList(username, statementHolderParam, connection, tempFilesForResultSet);
                }

                if (!connection.getAutoCommit()) {
                    connection.commit();
                }
            } catch (IOException e) {
                if (!connection.getAutoCommit()) {
                    connection.rollback();
                }

                throw e;
            } catch (SQLException e) {
                if (!connection.getAutoCommit()) {
                    connection.rollback();
                }

                throw e;
            } finally {
                // Release the connection
                ConnectionCloser.freeConnection(connection, sqlConfigurator);
            }
        } else {

            ConnectionStore connectionStore = new ConnectionStore(username, connectionId);
            connection = connectionStore.get();

            if (connection == null) {
                //out.println(TransferStatus.SEND_OK);
                //out.println(SqlReturnCode.SESSION_INVALIDATED);
                ServerSqlManager.writeLine(out, TransferStatus.SEND_OK);
                ServerSqlManager.writeLine(out, SqlReturnCode.SESSION_INVALIDATED);
                return;
            }

            if (statementHolderParam.startsWith(TransportConverter.KAWANFW_BYTES_STREAM_FILE)) {
                String fileName = StringUtils.substringAfter(statementHolderParam,
                        TransportConverter.KAWANFW_BYTES_STREAM_FILE);
                // Param contains only the file to read from the statements
                executeStatementsFromFile(username, fileName, connection, tempFilesForResultSet);
            } else {
                // All statements are in single param
                executeStatementsFromList(username, statementHolderParam, connection, tempFilesForResultSet);
            }
        }

        // Of, if the list is not empty, dump it to out on servlet out stream
        FileDumper.dumpFile(tempFilesForResultSet, out);

    }

    /**
     * Execute the Sql Action with is a query or update
     */
    public void executeQueryOrUpdate() throws IOException, SQLException, IllegalArgumentException {
        this.isExecuteRaw = false;
        execute();
    }

    /**
     * Execute the Sql Action with is a raw execute()
     */
    public void executeRaw() throws IOException, SQLException, IllegalArgumentException {
        this.isExecuteRaw = true;
        execute();
    }

    /**
     * Execute the statements from file name passed in parameter
     * 
     * @param username
     *            the user username
     * @param fileName
     *            the filename containing all the statements in json format, one
     *            perline
     * @param connection
     *            the JDBC Connection
     * @param tempFilesForResultSet
     *            The list of files to write
     * @throws SQLException
     * @throws IOException
     */
    private void executeStatementsFromFile(String username, String fileName, Connection connection,
            List<File> tempFilesForResultSet) throws SQLException, IOException {

        fileName = HttpConfigurationUtil.addRootPath(fileConfigurator, username, fileName);

        File file = new File(fileName);

        if (!file.exists()) {
            throw new IOException(Tag.PRODUCT_PRODUCT_FAIL
                    + "The file corresponding to a list of Statements does not exist on remote Server: "
                    + fileName);
        }

        StatementHolder statementHolder = null;

        StatementHolderListReader statementHolderListReader = null;

        statementHolderListReader = new StatementHolderListReader(file, commonsConfigurator);

        try {

            File fileExecute = ServerStatement.createTempFileForResultSet();

            boolean isFistStatement = true;

            while ((statementHolder = statementHolderListReader.readLine()) != null) {

                if (isExecuteRaw) {
                    ServerStatementRawExecute serverStatementRawExecute = new ServerStatementRawExecute(request,
                            commonsConfigurator, fileConfigurator, sqlConfigurator, connection, username,
                            statementHolder);

                    serverStatementRawExecute.execute(fileExecute);

                } else {
                    ServerStatement serverStatement = new ServerStatement(request, commonsConfigurator,
                            fileConfigurator, sqlConfigurator, connection, username, statementHolder);

                    if (!statementHolder.isExecuteUpdate()) {
                        serverStatement.executeQueryOrUpdate(fileExecute);
                    } else {
                        // In case of execute update, we store only the first
                        // result of
                        // the list of statements

                        debug("isFistStatement: " + isFistStatement);

                        if (isFistStatement) {
                            serverStatement.executeQueryOrUpdate(fileExecute);
                        } else {
                            serverStatement.executeQueryOrUpdate();
                        }
                    }
                }

                isFistStatement = false;
            }

            tempFilesForResultSet.add(fileExecute);

        } finally {
            if (statementHolderListReader != null) {
                statementHolderListReader.close();
                statementHolderListReader = null;
            }
        }

    }

    /**
     * Execute the statements from the parameter that contains the list of
     * StatementHolder in JSon format
     * 
     * @param username
     *            the user username
     * @param statementHolderParam
     *            the statement request parameter
     * @param connection
     *            the JDBC Connection
     * @param tempFilesForResultSet
     *            The list of files to write
     * @throws SQLException
     * @throws IOException
     */
    private void executeStatementsFromList(String username, String statementHolderParam, Connection connection,
            List<File> tempFilesForResultSet) throws SQLException, IOException {
        // All statements are in param
        List<StatementHolder> preparedStatementHolderList = StatementHolderListDecryptor
                .decryptFromJson(statementHolderParam, commonsConfigurator);

        File file = ServerStatement.createTempFileForResultSet();

        for (StatementHolder statementHolder : preparedStatementHolderList) {

            if (isExecuteRaw) {
                ServerStatementRawExecute serverStatementRawExecute = new ServerStatementRawExecute(request,
                        commonsConfigurator, fileConfigurator, sqlConfigurator, connection, username,
                        statementHolder);

                serverStatementRawExecute.execute(file);

            } else {
                ServerStatement serverStatement = new ServerStatement(request, commonsConfigurator,
                        fileConfigurator, sqlConfigurator, connection, username, statementHolder);

                serverStatement.executeQueryOrUpdate(file);

            }
        } // end for

        tempFilesForResultSet.add(file);
    }

    /**
     * Method called by children Servlest for debug purpose Println is done only
     * if class name name is in kawansoft-debug.ini
     */
    public static void debug(String s) {
        if (DEBUG) {
            ServerLogger.getLogger().log(Level.WARNING, s);
        }
    }

}