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

src-main.org.awakefw.sql.servlet.ServerAwakeSqlDispatch Maven / Gradle / Ivy

/*
 * Awake File: Easy file upload & download through HTTP with Java
 * Awake SQL: Remote JDBC access through HTTP.                                    
 * Copyright (C) 2012, Kawan Softwares S.A.S.
 * (http://www.awakeframework.org). All rights reserved.                                
 *                                                                               
 * Awake File/SQL 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.            
 *                                                                               
 * Awake File/SQL 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.
 */

//SqlHttpServerDispatch
//Copyright (c) Kawan Softwares S.A.S, 2012
//
//Last Updates: 
// 3 d?c. 2009 17:33:16 Nicolas de Pomereu
// 15/12/09 14:35 NDP - comments
// 14/01/10 18:05 NDP - Add getSynchronizedMode()/setSynchronizedMode() per user
// 25/01/10 19:30 NDP - If the file sql operation is now allowed, return false when login
// 17/02/10 17:25 NDP - No more connection.set/setHoldability anymore: not always supported
// 23/02/10 21:10 NDP - ServerAwakeSqlDispatch: Add Connectikon parameters to checkLoginDiscardStatus()
// 23/03/10 12:00 NDP - ServerAwakeSqlDispatch: Send back an ok if sqlOrdersAndParmsStoreList is empty
// 04/10/10 20:50 NDP - ServerAwakeSqlDispatch: executeAfterDiscard was missing the ip address parameter
// 12/10/10 17:50 NDP : ServerAwakeSqlDispatch: all actions on files are dispatched with an AwakeFileActionManager
// 18/11/10 11:30 NDP : ServerAwakeSqlDispatch: Comments
// 12/04/12 17:05 NDP : ServerAwakeSqlDispatch: print class name, message & stack trace on servlet output stream
// 04/06/11 12:10 NDP - ServerAwakeSqlDispatch: rename login to username
// 08/06/11 10:45 NDP : ServerAwakeSqlDispatch: set debug to false;
// 19/07/11 18:55 NDP : ServerAwakeSqlDispatch: set debug to false;
// 26/09/11 18:05 NDP : ServerAwakeSqlDispatch: add SqlAction.ACTION_SQL_GET_METADATA management
// 29/09/11 14:45 NDP : ServerAwakeSqlDispatch: Suppress old commented methods with state full session
// 30/09/11 15:20 NDP : ServerAwakeSqlDispatch: use Parameter.ACTION instead of suppressed SqlAction.ACTION
// 19/10/11 12:20 NDP - ServerAwakeSqlDispatch: add ACTION_SQL_PREP_STATEMENT_BATCH
// 16/11/11 12:50 NDP - ServerAwakeSqlDispatch: use unique method per switch on SqlAction
// 19/11/11 17:40 NDP - ServerAwakeSqlDispatch: correctly reinit the Connection before release in the pool
// 21/11/11 17:00 NDP - ServerAwakeSqlDispatch: put out = response.getWriter() at top (after try)
// 22/11/11 17:25 NDP : ServerAwakeSqlDispatch: throw Exception on first getParameter(): means encryption fails
// 08/12/11 20:30 NDP : ServerAwakeSqlDispatch: no more fromHtml conversion (comments)
// 13/12/11 12:20 NDP : ServerAwakeSqlDispatch: add getTransactionIsolation()
// 19/12/11 21:05 NDP : ServerAwakeSqlDispatch: use InitConnectionPool class for re-init of connections properties
// 16/02/12 15:50 NDP : ServerAwakeSqlDispatch: use AwakeCommonsConfigurator.computeAuthToken()
// 24/03/12 18:35 NDP : ServerAwakeSqlDispatch: use new ConnectionDefaultsStore
// 29/03/12 20:05 NDP : ServerAwakeSqlDispatch: call ConnectionDefaultsStore anyway 
//		        (more secure if dynamic database change)
// 02/04/12 16:20 NDP : ServerAwakeSqlDispatch: add Tag.AWAKE_USER_CONFIG_FAIL to exception.getMessage()
//			thrown back to client if exception is thrown by a Configurator

package org.awakefw.sql.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.awakefw.commons.api.server.AwakeCommonsConfigurator;
import org.awakefw.file.api.server.AwakeFileConfigurator;
import org.awakefw.file.api.server.fileaction.AwakeFileActionManager;
import org.awakefw.file.api.util.AwakeDebug;
import org.awakefw.file.http.HttpTransfer;
import org.awakefw.file.http.HttpTransferOne;
import org.awakefw.file.servlet.ServerAwakeFileDispatch;
import org.awakefw.file.servlet.ServerFileUploadAction;
import org.awakefw.file.servlet.ServerLoginAction;
import org.awakefw.file.servlet.ServerUserException;
import org.awakefw.file.util.AwakeLogger;
import org.awakefw.file.util.Tag;
import org.awakefw.file.util.parms.Action;
import org.awakefw.file.util.parms.Parameter;
import org.awakefw.file.util.parms.ReturnCode;
import org.awakefw.sql.api.server.AwakeSqlConfigurator;
import org.awakefw.sql.util.ConnectionDefaultsStore;
import org.awakefw.sql.util.SqlAction;

/**
 * @author Nicolas de Pomereu
 * 
 *         The method executeRequest() is to to be called from the SqlHttpServer
 *         Servlet and Class. 
* It will execute a client side request with a HttpConnection * connection. * */ public class ServerAwakeSqlDispatch { private static boolean DEBUG = AwakeDebug .isSet(ServerAwakeSqlDispatch.class); // Errors in SqlHttpServer private static final String ERR_ACTION_NOT_SET = "ERR_ACTION_NOT_SET"; /** * Constructor */ public ServerAwakeSqlDispatch() { // Does nothing } /** * Execute the client sent sql request * * @param request * the http request * @param response * the http response * @param awakeCommonsConfigurator * the client commons http configurator specific class * @param awakeFileConfigurator * the client file http configurator specific class * @param awakeSqlConfigurator * the client sql http configurator specific class * @param awakeFileActionManager * the file action manager * @param connection * the Sql Jdbc Connection * @throws IOException * if any IOException occurs */ public void executeRequest(HttpServletRequest request, HttpServletResponse response, AwakeCommonsConfigurator awakeCommonsConfigurator, AwakeFileConfigurator awakeFileConfigurator, AwakeSqlConfigurator awakeSqlConfigurator, AwakeFileActionManager awakeFileActionManager) throws IOException { // Immediate catch if we are asking a file upload, because parameters // are // in unknown sequence. We know it's a upload action if it's mime // multipart if (ServletFileUpload.isMultipartContent(request)) { ServerFileUploadAction dispatchAction = new ServerFileUploadAction(); dispatchAction.executeAction(request, response, awakeCommonsConfigurator, awakeFileConfigurator, awakeFileActionManager); return; } PrintWriter out = null; try { debug("executeRequest Start"); // Prepare the response response.setContentType("text/html"); // Fist thing to do: Stores in static memory the user settings for this transaction // This method will also test the Connection is created, otw a // detailed Exception is thrown debug("Before new ConnectionDefaultsStore."); try { ConnectionDefaultsStore connectionDefaultsStore = new ConnectionDefaultsStore( awakeCommonsConfigurator); connectionDefaultsStore.init(); } catch (Exception e) { out = response.getWriter(); throw e; } debug("After new ConnectionDefaultsStore."); // Get the send string debug("ACTION retrieval"); String action = null; // We must trap the IllegalArgumentException to rethrow properly to // client // This happens if there is an encryption problem try { action = request.getParameter(Parameter.ACTION); } catch (IllegalArgumentException e) { debug("IllegalArgumentException : " + e.toString()); out = response.getWriter(); throw e; } debug("ACTION : " + action); // Redirect to Awake File if it's a File request (Blobs/Clobs) if (isActionForAwakeFile(action)) { ServerAwakeFileDispatch dispatch = new ServerAwakeFileDispatch(); dispatch.executeRequest(request, response, awakeCommonsConfigurator, awakeFileConfigurator, awakeFileActionManager); return; } debug("After isActionForAwakeFile"); out = response.getWriter(); String username = request.getParameter(Parameter.LOGIN); String token = request.getParameter(Parameter.TOKEN); if (action == null || action.equals("")) { // out.println(HttpTransferOne.SEND_FAILED + SPACE + // ERR_ACTION_NOT_SET); out.println(HttpTransferOne.SEND_FAILED); out.println(ERR_ACTION_NOT_SET); return; } debug("Before if (action.equals(Action.LOGIN_ACTION"); // Special action for Login, because Token does not exists and must // be built if (action.equals(Action.LOGIN_ACTION) || action.equals(Action.BEFORE_LOGIN_ACTION)) { ServerLoginAction dispatchAction = new ServerLoginAction(); dispatchAction.executeAction(request, response, awakeCommonsConfigurator, action); return; } debug("Before if (! ServerAwakeFileDispatch.isTokenValid(username, token, awakeCommonsConfigurator"); if (! ServerAwakeFileDispatch.isTokenValid(username, token, awakeCommonsConfigurator)) { out.println(HttpTransfer.SEND_OK); out.println(ReturnCode.INVALID_LOGIN_OR_PASSWORD); return; } debug("Before if (action.equals(SqlAction.ACTION_SQL_STATEMENT)) {"); if (action.equals(SqlAction.ACTION_SQL_STATEMENT)) { executeStatement(request, awakeCommonsConfigurator, awakeFileConfigurator, awakeSqlConfigurator, out); } else if (action.equals(SqlAction.ACTION_SQL_STATEMENT_BATCH)) { executeStatementBatch(request, awakeCommonsConfigurator, awakeFileConfigurator, awakeSqlConfigurator, out); } else if (action.equals(SqlAction.ACTION_SQL_PREP_STATEMENT_BATCH)) { executePrepStatementBatch(request, awakeCommonsConfigurator, awakeFileConfigurator, awakeSqlConfigurator, out); } else if (action.equals(SqlAction.ACTION_SQL_GET_METADATA)) { executeGetMetadata(request, awakeCommonsConfigurator, awakeSqlConfigurator, out); } else if (action.equals(SqlAction.ACTION_SQL_EXECUTE_RAW)) { executeRaw(request, awakeCommonsConfigurator, awakeFileConfigurator, awakeSqlConfigurator, out); } else if (action .equals(SqlAction.ACTION_SQL_GET_TRANSACTION_ISOLATION)) { getTransactionIsolation(awakeCommonsConfigurator, out); } else { throw new IllegalArgumentException("Invalid Sql Action: " + action); } } catch (Exception e) { out.println(HttpTransfer.SEND_FAILED); out.println(e.getClass().getName()); out.println(ServerUserException.getMessage(e)); out.println(ExceptionUtils.getStackTrace(e)); try { AwakeLogger.log(Level.WARNING, Tag.AWAKE_EXCEPTION_RAISED + ServerUserException.getMessage(e)); AwakeLogger.log(Level.WARNING, Tag.AWAKE_EXCEPTION_RAISED + ExceptionUtils.getStackTrace(e)); } catch (Exception e1) { e1.printStackTrace(); e1.printStackTrace(System.out); } } } /** * Returns to client the Connection.getTransactionIsolation() value * * @param awakeCommonsConfigurator * The commons configurator * @param out * the servlet print writer */ private void getTransactionIsolation( AwakeCommonsConfigurator awakeCommonsConfigurator, PrintWriter out) throws SQLException { Connection connection = null; int transactionIsolation = -1; try { connection = awakeCommonsConfigurator.getConnection(); transactionIsolation = connection.getTransactionIsolation(); } finally { // Release the connection ServerAwakeSqlDispatch.cleanAndFreeConnection(connection, awakeCommonsConfigurator); } debug("transactionIsolation: " + transactionIsolation); out.println(HttpTransferOne.SEND_OK); out.println("" + transactionIsolation); } /** * Execute a Statement or a PreparedStatement * * @param request * @param awakeCommonsConfigurator * @param awakeFileConfigurator * @param awakeSqlConfigurator * @param out * @throws IOException * @throws SQLException * @throws IllegalArgumentExceptionn */ private void executeStatement(HttpServletRequest request, AwakeCommonsConfigurator awakeCommonsConfigurator, AwakeFileConfigurator awakeFileConfigurator, AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out) throws IOException, SQLException, IllegalArgumentException { // Actions that trigger a (Pre)Statement.executeQuery()/executeUppdate() ServerSqlExecutor serverSqlExecutor = new ServerSqlExecutor(request, out, awakeCommonsConfigurator, awakeFileConfigurator, awakeSqlConfigurator); serverSqlExecutor.executeQueryOrUpdate(); } /** * Execute a Statement Batch * * @param request * @param awakeCommonsConfigurator * @param awakeFileConfigurator * @param awakeSqlConfigurator * @param out * @throws IOException * @throws SQLException * @throws IllegalArgumentException * @throws SecurityException */ private void executeStatementBatch(HttpServletRequest request, AwakeCommonsConfigurator awakeCommonsConfigurator, AwakeFileConfigurator awakeFileConfigurator, AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out) throws IOException, SQLException, IllegalArgumentException { // Actions that trigger a Statement batch ServerBatchStatementExecutor serverBatchStatementExecutor = new ServerBatchStatementExecutor( request, out, awakeCommonsConfigurator, awakeFileConfigurator, awakeSqlConfigurator); serverBatchStatementExecutor.execute(); } /** * Execute a PreparedStatement Batch * * @param request * @param awakeCommonsConfigurator * @param awakeFileConfigurator * @param awakeSqlConfigurator * @param out * @throws IOException * @throws SQLException * @throws IllegalArgumentException */ private void executePrepStatementBatch(HttpServletRequest request, AwakeCommonsConfigurator awakeCommonsConfigurator, AwakeFileConfigurator awakeFileConfigurator, AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out) throws IOException, SQLException, IllegalArgumentException { // Actions that trigger a PreparedStatement batch ServerBatchPrepStatementExecutor serverBatchPrepStatementExecutor = new ServerBatchPrepStatementExecutor( request, out, awakeCommonsConfigurator, awakeFileConfigurator, awakeSqlConfigurator); serverBatchPrepStatementExecutor.execute(); } /** * Execute a DatabaseMetaData call * * @param request * @param awakeCommonsConfigurator * @param awakeSqlConfigurator * @param out * @throws Exception */ private void executeGetMetadata(HttpServletRequest request, AwakeCommonsConfigurator awakeCommonsConfigurator, AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out) throws Exception { // Metadata retrieval DatabaseMetaDataExecutor databaseMetaDataExecutor = new DatabaseMetaDataExecutor( request, out, awakeCommonsConfigurator, awakeSqlConfigurator); databaseMetaDataExecutor.execute(); } /** * Execute a raw (Prepared)Statement.execute() * * @param request * @param awakeCommonsConfigurator * @param awakeFileConfigurator * @param awakeSqlConfigurator * @param out */ private void executeRaw(HttpServletRequest request, AwakeCommonsConfigurator awakeCommonsConfigurator, AwakeFileConfigurator awakeFileConfigurator, AwakeSqlConfigurator awakeSqlConfigurator, PrintWriter out) throws IOException, SQLException, IllegalArgumentException { ServerSqlExecutor serverSqlExecutor = new ServerSqlExecutor(request, out, awakeCommonsConfigurator, awakeFileConfigurator, awakeSqlConfigurator); serverSqlExecutor.executeRaw(); } /** * Clean the connection (aka put in write/read & DEFAULT_ISOLATION_LEVEL) * and then release it * * @param connection * @param awakeCommonsConfigurator */ public static void cleanAndFreeConnection(Connection connection, AwakeCommonsConfigurator awakeCommonsConfigurator) { // Reset the transaction to it's back state before realeasing it try { if (connection != null) { connection.setAutoCommit(true); connection.setReadOnly(false); ConnectionDefaultsStore connectionDefaultsStore = new ConnectionDefaultsStore( awakeCommonsConfigurator); connection.setTransactionIsolation(connectionDefaultsStore .getTransactionIsolation()); connection.setHoldability(connectionDefaultsStore .getHoldability()); // Release the Connection into the pool connection.close(); } } catch (SQLException e) { AwakeLogger.log(Level.WARNING, ExceptionUtils.getStackTrace(e)); } } /** * Says if an Action asked by the client is for Awake File * * @param action * the action asked by the client side * @return true if the action is for Awake File */ private boolean isActionForAwakeFile(String action) { if (action.startsWith(SqlAction.ACTION_SQL)) { return false; } else { return true; } } /** * Method called by children Servlet for debug purpose Println is done only * if class name name is in debug_list.ini */ public static void debug(String s) { if (DEBUG) { AwakeLogger.log(s); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy