JDBCUtilities.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */


  20. package org.openspcoop2.utils.jdbc;

  21. import java.sql.Connection;
  22. import java.sql.DatabaseMetaData;
  23. import java.sql.PreparedStatement;
  24. import java.sql.ResultSet;
  25. import java.sql.SQLException;
  26. import java.sql.Statement;
  27. import java.util.ArrayList;
  28. import java.util.Map;

  29. import org.openspcoop2.utils.LoggerWrapperFactory;
  30. import org.openspcoop2.utils.TipiDatabase;
  31. import org.openspcoop2.utils.UtilsException;
  32. import org.slf4j.Logger;

  33. /**
  34.  * JDBC Utilities
  35.  *
  36.  *
  37.  * @author Poli Andrea (apoli@link.it)
  38.  * @author $Author$
  39.  * @version $Rev$, $Date$
  40.  */

  41. public class JDBCUtilities {
  42.    
  43.     private JDBCUtilities() {}

  44.     /**
  45.      * Chiude tutte le PreparedStatement presenti nella tabella hash.
  46.      *
  47.      * @param tablePstmt Tabella Hash contenente PreparedStatement da chiudere.
  48.      *
  49.      */
  50.     public static void closePreparedStatement(Map<String,PreparedStatement> tablePstmt,Logger log){
  51.         if(tablePstmt!=null && !tablePstmt.isEmpty()){
  52.             java.util.ArrayList<String> listKeys = new ArrayList<>();
  53.             for (String key : tablePstmt.keySet()) {
  54.                 listKeys.add(key);
  55.             }
  56.             java.util.Collections.sort(listKeys);
  57.             for(int i=0; i<listKeys.size(); i++ ) {
  58.                 String key = listKeys.get(i);
  59.                 PreparedStatement pstmt = tablePstmt.get(key);
  60.                 try{
  61.                     pstmt.close();
  62.                 }catch(Exception e){
  63.                     String msg = "Utilities.closePreparedStatement error: Riscontrato errore durante la chiusura della PreparedStatement ["+key+"]: "+e;
  64.                     log.debug(msg, e);
  65.                 }
  66.                 tablePstmt.remove(key);
  67.             }
  68.         }
  69.     }


  70.     /**
  71.      * Esegue e Chiude tutte le PreparedStatement presenti nella tabella hash.
  72.      *
  73.      * @param tablePstmt Tabella Hash contenente PreparedStatement da eseguire e chiudere.
  74.      *
  75.      */
  76.     public static void executePreparedStatement(Map<String,PreparedStatement> tablePstmt) throws UtilsException{
  77.         if(tablePstmt!=null && !tablePstmt.isEmpty()){
  78.             java.util.ArrayList<String> listKeys = new ArrayList<>();
  79.             for (String key : tablePstmt.keySet()) {
  80.                 listKeys.add(key);
  81.             }
  82.             java.util.Collections.sort(listKeys);

  83.             /**System.out.println("---------- ("+listKeys.size()+") ------------");
  84.             for(int i=0; i<listKeys.size(); i++ ) {
  85.                 String key = listKeys.get(i);
  86.                 System.out.println("Pos["+i+"]: "+key);
  87.             }*/
  88.            
  89.             for(int i=0; i<listKeys.size(); i++ ) {
  90.                 String key = listKeys.get(i);
  91.                 PreparedStatement pstmt = tablePstmt.get(key);
  92.                 /**System.out.println("EXECUTE["+i+"]: "+key);*/
  93.                 try{
  94.                     pstmt.execute();
  95.                 }catch(Exception e){
  96.                     /**System.out.println("ERRORE: "+key);*/
  97.                     throw new UtilsException("Utilities.executePreparedStatement error: Riscontrato errore durante l'esecuzione della PreparedStatement ["+key+"]: "+e,e);
  98.                 }
  99.                 try{
  100.                     pstmt.close();
  101.                 }catch(Exception e){
  102.                     /**System.out.println("ERRORE: "+key);*/
  103.                     throw new UtilsException("Utilities.executePreparedStatement error: Riscontrato errore durante la chiusura della PreparedStatement ["+key+"]: "+e,e);
  104.                 }
  105.                 tablePstmt.remove(key);
  106.             }
  107.         }
  108.     }

  109.     /**
  110.      * Aggiunge prepared Statement
  111.      *
  112.      * @param pstmtSorgente
  113.      * @param pstmtDestinazione
  114.      * @param log
  115.      */
  116.     public static void addPreparedStatement(Map<String,PreparedStatement> pstmtSorgente,
  117.             Map<String,PreparedStatement> pstmtDestinazione,Logger log) throws UtilsException{
  118.         if(log!=null) {
  119.             // nop
  120.         }
  121.         if(pstmtSorgente!=null && !pstmtSorgente.isEmpty()){
  122.             for (String key : pstmtSorgente.keySet()) {
  123.                 if(!pstmtDestinazione.containsKey(key)){
  124.                     pstmtDestinazione.put(key,pstmtSorgente.get(key));
  125.                 }else{
  126.                     /**log.debug("Prepared Statement ["+key+"] gia' presente");*/
  127.                     try{
  128.                         PreparedStatement pstmt = pstmtSorgente.get(key);
  129.                         pstmt.close();
  130.                     }catch(Exception e){
  131.                         throw new UtilsException("Utilities.closePreparedStatementGiaPresente error: Riscontrato errore durante la chiusura della PreparedStatement ["+key+"]: "+e,e);
  132.                     }
  133.                 }
  134.             }
  135.         }
  136.     }
  137.    
  138.    
  139.    
  140.    
  141.     public static void setSQLStringValue(PreparedStatement pstmt,int index,String value) throws SQLException{
  142.         if(value!=null && (!"".equals(value)))
  143.             pstmt.setString(index,value);
  144.         else
  145.             pstmt.setString(index,null);
  146.     }
  147.    
  148.    
  149.     private static final int SQL_SERVER_TRANSACTION_SNAPSHOT = 4096;
  150.    
  151.     public static boolean isTransactionIsolationNone(int transactionIsolationLevel){
  152.         return transactionIsolationLevel == java.sql.Connection.TRANSACTION_NONE;
  153.     }
  154.     public static boolean isTransactionIsolationReadUncommitted(int transactionIsolationLevel){
  155.         return transactionIsolationLevel == java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
  156.     }
  157.     public static boolean isTransactionIsolationReadCommitted(int transactionIsolationLevel){
  158.         return transactionIsolationLevel == java.sql.Connection.TRANSACTION_READ_COMMITTED;
  159.     }
  160.     public static boolean isTransactionIsolationRepeatableRead(int transactionIsolationLevel){
  161.         return transactionIsolationLevel == java.sql.Connection.TRANSACTION_REPEATABLE_READ;
  162.     }
  163.     public static boolean isTransactionIsolationSerializable(int transactionIsolationLevel){
  164.         return transactionIsolationLevel == java.sql.Connection.TRANSACTION_SERIALIZABLE;
  165.     }
  166.     public static boolean isTransactionIsolationSqlServerSnapshot(int transactionIsolationLevel){
  167.         return transactionIsolationLevel == JDBCUtilities.SQL_SERVER_TRANSACTION_SNAPSHOT;
  168.     }
  169.     public static boolean isTransactionIsolationSerializable(int transactionIsolationLevel,TipiDatabase tipoDatabase){
  170.         if(tipoDatabase!=null && TipiDatabase.SQLSERVER.equals(tipoDatabase)){
  171.             return JDBCUtilities.isTransactionIsolationSqlServerSnapshot(transactionIsolationLevel);
  172.         }
  173.         else {
  174.             return JDBCUtilities.isTransactionIsolationSerializable(transactionIsolationLevel);
  175.         }
  176.     }
  177.    
  178.     public static void setTransactionIsolationSerializable(String tipoDatabase,Connection connection) throws SQLException{
  179.         JDBCUtilities.setTransactionIsolationSerializable(TipiDatabase.toEnumConstant(tipoDatabase), connection);
  180.     }
  181.     public static void setTransactionIsolationSerializable(TipiDatabase tipoDatabase,Connection connection) throws SQLException{
  182.         if(tipoDatabase!=null && TipiDatabase.SQLSERVER.equals(tipoDatabase)){
  183.             connection.setTransactionIsolation(JDBCUtilities.SQL_SERVER_TRANSACTION_SNAPSHOT); /**4096 corresponds to SQLServerConnection.TRANSACTION_SNAPSHOT }*/
  184.         }
  185.         else{
  186.             connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
  187.         }
  188.     }
  189.    
  190.    
  191.    
  192.    
  193.    
  194.     public static void addInformazioniDatabaseFromMetaData(Connection c, StringBuilder bf) throws SQLException{
  195.        
  196.         DatabaseMetaData dbMetaDati = c.getMetaData();
  197.         if(dbMetaDati!=null){

  198.             if(bf.length()>0){
  199.                 bf.append("\n");
  200.             }

  201.             try {
  202.                 String productName = dbMetaDati.getDatabaseProductName();
  203.                 bf.append("DatabaseProductName: "+productName);
  204.                 bf.append("\n");
  205.             } catch (SQLException e) {
  206.                 // ignore
  207.             }

  208.             try {
  209.                 String productVersion = dbMetaDati.getDatabaseProductVersion();
  210.                 bf.append("DatabaseProductVersion: "+productVersion);
  211.                 bf.append("\n");
  212.             } catch (SQLException e) {
  213.                 // ignore
  214.             }

  215.             try {
  216.                 int v = dbMetaDati.getDatabaseMajorVersion();
  217.                 bf.append("DatabaseMajorVersion: "+v);
  218.                 bf.append("\n");
  219.             } catch (SQLException e) {
  220.                 // ignore
  221.             }

  222.             try {
  223.                 int v = dbMetaDati.getDatabaseMinorVersion();
  224.                 bf.append("DatabaseMinorVersion: "+v);
  225.                 bf.append("\n");
  226.             } catch (SQLException e) {
  227.                 // ignore
  228.             }

  229.             addInformazioniDatabaseFromMetaDataDriver(dbMetaDati, bf);

  230.             try {
  231.                 String username = dbMetaDati.getUserName();
  232.                 bf.append("Username: "+username);
  233.                 bf.append("\n");
  234.             } catch (SQLException e) {
  235.                 // ignore
  236.             }

  237.             addInformazioniDatabaseFromMetaDataCatalog(dbMetaDati, bf);

  238.         }

  239.     }
  240.     private static void addInformazioniDatabaseFromMetaDataDriver(DatabaseMetaData dbMetaDati, StringBuilder bf) throws SQLException{
  241.         try {
  242.             String driverName = dbMetaDati.getDriverName();
  243.             bf.append("DriverName: "+driverName);
  244.             bf.append("\n");
  245.         } catch (SQLException e) {
  246.             // ignore
  247.         }

  248.         try {
  249.             String productVersion = dbMetaDati.getDriverVersion();
  250.             bf.append("DriverVersion: "+productVersion);
  251.             bf.append("\n");
  252.         } catch (SQLException e) {
  253.             // ignore
  254.         }

  255.         int v = dbMetaDati.getDriverMajorVersion();
  256.         bf.append("DriverMajorVersion: "+v);
  257.         bf.append("\n");
  258.        
  259.         v = dbMetaDati.getDriverMinorVersion();
  260.         bf.append("DriverMinorVersion: "+v);
  261.         bf.append("\n");
  262.        
  263.         try {
  264.             v = dbMetaDati.getJDBCMajorVersion();
  265.             bf.append("JDBCMajorVersion: "+v);
  266.             bf.append("\n");
  267.         } catch (SQLException e) {
  268.             // ignore
  269.         }

  270.         try {
  271.             v = dbMetaDati.getJDBCMinorVersion();
  272.             bf.append("JDBCMinorVersion: "+v);
  273.             bf.append("\n");
  274.         } catch (SQLException e) {
  275.             // ignore
  276.         }
  277.     }
  278.     private static void addInformazioniDatabaseFromMetaDataCatalog(DatabaseMetaData dbMetaDati, StringBuilder bf) throws SQLException{
  279.         try {
  280.             ResultSet catalogs = dbMetaDati.getCatalogs();
  281.             int size = 0;
  282.             while (catalogs.next()) {
  283.                 size++;
  284.             }
  285.            
  286.             catalogs = dbMetaDati.getCatalogs();
  287.             int index = 0;
  288.             while (catalogs.next()) {
  289.                 if(size==1){
  290.                     bf.append("Catalog: " + catalogs.getString(1) );
  291.                 }
  292.                 else{
  293.                     bf.append("Catalogs["+index+"]: " + catalogs.getString(1) );
  294.                 }
  295.                 bf.append("\n");
  296.                 index++;
  297.             }
  298.             catalogs.close();
  299.         } catch (SQLException e) {
  300.             // ignore
  301.         }
  302.     }
  303.    
  304.     public static void closeResources(ResultSet rs, PreparedStatement stm) {
  305.         try{
  306.             if(rs!=null)
  307.                 rs.close();
  308.         }catch (Exception e) {
  309.             //ignore
  310.         }
  311.         try{
  312.             if(stm!=null)
  313.                 stm.close();
  314.         }catch (Exception e) {
  315.             //ignore
  316.         }
  317.     }
  318.     public static void closeResources(ResultSet rs, Statement stm) {
  319.         try{
  320.             if(rs!=null)
  321.                 rs.close();
  322.         }catch (Exception e) {
  323.             //ignore
  324.         }
  325.         try{
  326.             if(stm!=null)
  327.                 stm.close();
  328.         }catch (Exception e) {
  329.             //ignore
  330.         }
  331.     }
  332.     public static void closeResources(PreparedStatement stm) {
  333.         try{
  334.             if(stm!=null)
  335.                 stm.close();
  336.         }catch (Exception e) {
  337.             //ignore
  338.         }
  339.     }
  340.     public static void closeResources(Statement stm) {
  341.         try{
  342.             if(stm!=null)
  343.                 stm.close();
  344.         }catch (Exception e) {
  345.             //ignore
  346.         }
  347.     }
  348.    
  349.    
  350.     public static void closeConnection(Logger log, Connection connectionDB, boolean checkAutocommit, boolean checkIsClosed) throws SQLException {
  351.         if(connectionDB!=null) {
  352.             if(checkAutocommit) {
  353.                 checkAutocommit(log, connectionDB);
  354.             }
  355.             if(checkIsClosed) {
  356.                 checkIsClosed(log, connectionDB);
  357.             }
  358.         }
  359.     }
  360.     private static void checkAutocommit(Logger log, Connection connectionDB) throws SQLException {
  361.         if(!connectionDB.getAutoCommit()) {
  362.             String msg = "Connection detected in transaction mode";
  363.             if(log==null) {
  364.                 log = LoggerWrapperFactory.getLogger(JDBCUtilities.class);
  365.             }
  366.             log.error(msg,new UtilsException(msg)); // aggiungo eccezione per registrare lo stack trace della chiamata e vedere dove viene chiamato il metodo
  367.             connectionDB.setAutoCommit(true);
  368.         }
  369.         else {
  370.             // nop
  371.         }
  372.     }
  373.     private static void checkIsClosed(Logger log, Connection connectionDB) throws SQLException {
  374.         if(connectionDB.isClosed()) {
  375.             String msg = "Connection already closed detected";
  376.             if(log==null) {
  377.                 log = LoggerWrapperFactory.getLogger(JDBCUtilities.class);
  378.             }
  379.             log.error(msg,new UtilsException(msg)); // aggiungo eccezione per registrare lo stack trace della chiamata e vedere dove viene chiamato il metodo
  380.         }
  381.         else {
  382.             connectionDB.close();
  383.         }
  384.     }
  385. }