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.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.no_obfuscation.CallableStatementHolder; 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.CallableStatementHolderListReader; import org.kawanfw.sql.servlet.sql.ServerCallableStatement; import org.kawanfw.sql.servlet.sql.ServerSqlUtil; import org.kawanfw.sql.servlet.sql.ServerStatement; import org.kawanfw.sql.transport.TransportConverter; import org.kawanfw.sql.util.ConnectionParms; import org.kawanfw.sql.util.SqlAction; import org.kawanfw.sql.util.SqlReturnCode; import org.kawanfw.sql.util.crypto.CallableStatementHolderListDecryptor; /** * Execute transported statements on the server * * @author Nicolas de Pomereu * */ public class ServerSqlExecutorCallable { private static boolean DEBUG = FrameworkDebug.isSet(ServerSqlExecutorCallable.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 CallableStatement.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 ServerSqlExecutorCallable(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; } /** * Will call a list of CallableStatement.executeQuery() * * @throws IOException * @throws SQLException * @throws IllegalArgumentException */ public void executeQuery() throws IOException, SQLException, IllegalArgumentException { isExecuteRaw = false; callStatement(); } /** * Will call a list of CallableStatement.execute() * * @throws IOException * @throws SQLException * @throws IllegalArgumentException */ public void execute() throws IOException, SQLException, IllegalArgumentException { isExecuteRaw = true; callStatement(); } /** * Execute the Callable Statement * * @throws IOException * @throws SQLException * @throws IllegalArgumentException */ public void callStatement() 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")) { // stateless mode was set on PC 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 callStatementsFromFile(username, fileName, connection, tempFilesForResultSet); } else { // All statements are in single param callStatementsFromList(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 callStatementsFromFile(username, fileName, connection, tempFilesForResultSet); } else { // All statements are in single param callStatementsFromList(username, statementHolderParam, connection, tempFilesForResultSet); } } // Of, if the list is not empty, dump it to out on servlet out stream FileDumper.dumpFile(tempFilesForResultSet, out); } private void callStatementsFromList(String username, String statementHolderParam, Connection connection, List<File> tempFilesForResultSet) throws SQLException, IOException { // All statements are in param List<CallableStatementHolder> callableStatementHolderList = CallableStatementHolderListDecryptor .decryptFromJson(statementHolderParam, commonsConfigurator); File file = ServerStatement.createTempFileForResultSet(); for (CallableStatementHolder callableStatementHolder : callableStatementHolderList) { ServerCallableStatement serverStatement = new ServerCallableStatement(request, commonsConfigurator, fileConfigurator, sqlConfigurator, connection, username, callableStatementHolder, isExecuteRaw); serverStatement.execute(file); } // end for tempFilesForResultSet.add(file); } private void callStatementsFromFile(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); } CallableStatementHolder callableStatementHolder = null; CallableStatementHolderListReader callableStatementHolderListReader = null; callableStatementHolderListReader = new CallableStatementHolderListReader(file, commonsConfigurator); try { File fileExecute = ServerStatement.createTempFileForResultSet(); // boolean isFistStatement = true; while ((callableStatementHolder = callableStatementHolderListReader.readLine()) != null) { ServerCallableStatement serverStatement = new ServerCallableStatement(request, commonsConfigurator, fileConfigurator, sqlConfigurator, connection, username, callableStatementHolder, isExecuteRaw); // if (!callableStatementHolder.isExecuteUpdate()) { // serverStatement.execute(fileExecute); // } else { // // In case of execute update, we store only the first // // result of // // the list of statements // if (isFistStatement) { // serverStatement.execute(fileExecute); // } else { // serverStatement.execute(); // } // } // This is not an execute update, so we execute on file: serverStatement.execute(fileExecute); // isFistStatement = false; } tempFilesForResultSet.add(fileExecute); } finally { if (callableStatementHolderListReader != null) { callableStatementHolderListReader.close(); callableStatementHolderListReader = null; } } } /** * 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); } } }