JDBCServiceManagerBase.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.generic_project.dao.jdbc;


  21. import java.io.File;
  22. import java.sql.Connection;
  23. import java.sql.DriverManager;
  24. import java.sql.SQLException;
  25. import java.util.Date;
  26. import java.util.Properties;

  27. import javax.sql.DataSource;

  28. import org.openspcoop2.generic_project.beans.IProjectInfo;
  29. import org.openspcoop2.generic_project.exception.ServiceException;
  30. import org.openspcoop2.generic_project.utils.ServiceManagerProperties;
  31. import org.openspcoop2.utils.LoggerWrapperFactory;
  32. import org.openspcoop2.utils.date.DateManager;
  33. import org.openspcoop2.utils.jdbc.JDBCUtilities;
  34. import org.openspcoop2.utils.resources.ClassLoaderUtilities;
  35. import org.openspcoop2.utils.resources.GestoreJNDI;
  36. import org.slf4j.Logger;

  37. /**
  38.  * JDBCServiceManager
  39.  *
  40.  * @author Poli Andrea (apoli@link.it)
  41.  * @author $Author$
  42.  * @version $Rev$, $Date$
  43.  */
  44. public class JDBCServiceManagerBase {

  45.     /** DataSource. */
  46.     protected DataSource datasource;
  47.     /** Connection */
  48.     protected Connection connection = null;
  49.     /** Logger */
  50.     protected Logger log = null;
  51.     /** JDBC Properties */
  52.     protected JDBCServiceManagerProperties jdbcProperties = null;
  53.    
  54.     /** Parametri per rinegoziare la connessione */
  55.     private String connectionUrl;
  56.     private String username;
  57.     private String password;
  58.     private int secondsToRefreshConnection = -1;
  59.     private Date connectionDate;
  60.    
  61.     private void logError(String msg, Exception e) {
  62.         if(this.log!=null) {
  63.             this.log.error(msg, e);
  64.         }
  65.     }
  66.    
  67.     private static final String CREATE_ERROR_PREFIX = "Creating failure: ";
  68.    
  69.     /** Tipo di costruttore */
  70.     private JDBCServiceManagerTipoCostruttore tipoCostruttore = null;
  71.    
  72.     protected JDBCServiceManagerBase(){}
  73.    
  74.     public JDBCServiceManagerBase(String jndiName, Properties contextJNDI,ServiceManagerProperties serviceManagerProperties) throws ServiceException{
  75.         this(jndiName, contextJNDI, new JDBCServiceManagerProperties(serviceManagerProperties), null);
  76.     }
  77.     public JDBCServiceManagerBase(String jndiName, Properties contextJNDI,JDBCServiceManagerProperties jdbcProperties) throws ServiceException{
  78.         this(jndiName, contextJNDI, jdbcProperties, null);
  79.     }
  80.     public JDBCServiceManagerBase(String jndiName, Properties contextJNDI,ServiceManagerProperties serviceManagerProperties,Logger alog) throws ServiceException{
  81.         this(jndiName, contextJNDI, new JDBCServiceManagerProperties(serviceManagerProperties), alog);
  82.     }
  83.     public JDBCServiceManagerBase(String jndiName, Properties contextJNDI,JDBCServiceManagerProperties jdbcProperties,Logger alog) throws ServiceException{
  84.        
  85.         this.tipoCostruttore = JDBCServiceManagerTipoCostruttore.DATASOURCE_CFG;
  86.        
  87.         if(alog==null){
  88.             this.log = LoggerWrapperFactory.getLogger(JDBCServiceManagerBase.class);
  89.         }else
  90.             this.log = alog;
  91.        
  92.         try{
  93.            
  94.             GestoreJNDI gestoreJNDI = new GestoreJNDI(contextJNDI);
  95.             this.datasource = (DataSource) gestoreJNDI.lookup(jndiName);
  96.             if(this.datasource == null){
  97.                 throw new ServiceException("Datasource is null");
  98.             }
  99.            
  100.             this.jdbcProperties = jdbcProperties;
  101.             jdbcProperties.getDatabase(); // check tipoDatabase fornito
  102.                        
  103.         } catch(Exception e) {
  104.             this.logError(CREATE_ERROR_PREFIX+e.getMessage(),e);
  105.             throw new ServiceException(CREATE_ERROR_PREFIX+e.getMessage(),e);
  106.         }
  107.     }
  108.    
  109.     public JDBCServiceManagerBase(DataSource ds,ServiceManagerProperties serviceManagerProperties) throws ServiceException{
  110.         this(ds, new JDBCServiceManagerProperties(serviceManagerProperties), null);
  111.     }
  112.     public JDBCServiceManagerBase(DataSource ds,JDBCServiceManagerProperties jdbcProperties) throws ServiceException{
  113.         this(ds, jdbcProperties, null);
  114.     }
  115.     public JDBCServiceManagerBase(DataSource ds,ServiceManagerProperties serviceManagerProperties,Logger alog) throws ServiceException{
  116.         this(ds, new JDBCServiceManagerProperties(serviceManagerProperties), alog);
  117.     }
  118.     public JDBCServiceManagerBase(DataSource ds,JDBCServiceManagerProperties jdbcProperties,Logger alog) throws ServiceException{
  119.        
  120.         this.tipoCostruttore = JDBCServiceManagerTipoCostruttore.DATASOURCE_OBJECT;
  121.        
  122.         if(alog==null){
  123.             this.log = LoggerWrapperFactory.getLogger(JDBCServiceManagerBase.class);
  124.         }else
  125.             this.log = alog;
  126.        
  127.         try{
  128.            
  129.             this.datasource = ds;
  130.             if(this.datasource == null){
  131.                 throw new ServiceException("Datasource is null");
  132.             }
  133.            
  134.             this.jdbcProperties = jdbcProperties;
  135.             jdbcProperties.getDatabase(); // check tipoDatabase fornito
  136.            
  137.         } catch(Exception e) {
  138.             this.logError(CREATE_ERROR_PREFIX+e.getMessage(),e);
  139.             throw new ServiceException(CREATE_ERROR_PREFIX+e.getMessage(),e);
  140.         }
  141.     }
  142.    
  143.     public JDBCServiceManagerBase(String connectionUrl,String driverJDBC,String username,String password,ServiceManagerProperties serviceManagerProperties) throws ServiceException{
  144.         this(connectionUrl,driverJDBC,username,password,new JDBCServiceManagerProperties(serviceManagerProperties),null);
  145.     }
  146.     public JDBCServiceManagerBase(String connectionUrl,String driverJDBC,String username,String password,JDBCServiceManagerProperties jdbcProperties) throws ServiceException{
  147.         this(connectionUrl,driverJDBC,username,password,jdbcProperties,null);
  148.     }
  149.     public JDBCServiceManagerBase(String connectionUrl,String driverJDBC,String username,String password,ServiceManagerProperties serviceManagerProperties,Logger alog) throws ServiceException{
  150.         this(connectionUrl,driverJDBC,username,password,new JDBCServiceManagerProperties(serviceManagerProperties),alog);
  151.     }
  152.     public JDBCServiceManagerBase(String connectionUrl,String driverJDBC,String username,String password,JDBCServiceManagerProperties jdbcProperties,Logger alog) throws ServiceException{
  153.        
  154.         this.tipoCostruttore = JDBCServiceManagerTipoCostruttore.CONNECTION_CFG;
  155.        
  156.         if(alog==null){
  157.             this.log = LoggerWrapperFactory.getLogger(JDBCServiceManagerBase.class);
  158.         }else
  159.             this.log = alog;
  160.        
  161.         try{
  162.            
  163.             this.connectionUrl = connectionUrl;
  164.             this.username = username;
  165.             this.password = password;
  166.             this.secondsToRefreshConnection = jdbcProperties.getSecondsToRefreshConnection();
  167.            
  168.             ClassLoaderUtilities.newInstance(driverJDBC);
  169.            
  170.             setConnection();
  171.            
  172.             this.jdbcProperties = jdbcProperties;
  173.             jdbcProperties.getDatabase(); // check tipoDatabase fornito
  174.            
  175.         } catch(Exception e) {
  176.             this.logError(CREATE_ERROR_PREFIX+e.getMessage(),e);
  177.             throw new ServiceException(CREATE_ERROR_PREFIX+e.getMessage(),e);
  178.         }
  179.     }
  180.     private void setConnection() throws SQLException {
  181.         if(this.username!=null){
  182.             this.connection = DriverManager.getConnection(this.connectionUrl,this.username,this.password);
  183.         }else{
  184.             this.connection = DriverManager.getConnection(this.connectionUrl);
  185.         }
  186.         /**if(this.connection == null){
  187.             throw new Exception("Connection is null");
  188.         }*/
  189.         this.connectionDate = DateManager.getDate();
  190.     }
  191.     private boolean isConnectionExpired() {
  192.         if(this.secondsToRefreshConnection>0) {
  193.             Date now = DateManager.getDate();
  194.             Date expireDate = new Date(this.connectionDate.getTime()+(this.secondsToRefreshConnection*1000));
  195.             if(expireDate.before(now)) {
  196.                 return true;
  197.             }
  198.         }
  199.         return false;
  200.     }
  201.     private void refreshConnection() throws SQLException {
  202.         if(this.isConnectionExpired()) {
  203.             this.internalRefreshConnection();
  204.         }
  205.     }
  206.     private synchronized void internalRefreshConnection() throws SQLException {
  207.         if(this.isConnectionExpired()) {
  208.             /**System.out.println("REFRESH (user:"+this.username+" connection-url: "+this.connectionUrl+")");*/
  209.             try {
  210.                 if(this.connection!=null) {
  211.                     JDBCUtilities.closeConnection(checkLogger, this.connection, checkAutocommit, checkIsClosed);
  212.                 }
  213.             }catch(Exception t) {
  214.                 // ignore
  215.             }
  216.             setConnection();
  217.         }
  218.     }
  219.    
  220.     public JDBCServiceManagerBase(Connection connection,ServiceManagerProperties serviceManagerProperties) throws ServiceException{
  221.         this(connection, new JDBCServiceManagerProperties(serviceManagerProperties), null);
  222.     }
  223.     public JDBCServiceManagerBase(Connection connection,JDBCServiceManagerProperties jdbcProperties) throws ServiceException{
  224.         this(connection, jdbcProperties, null);
  225.     }
  226.     public JDBCServiceManagerBase(Connection connection,ServiceManagerProperties serviceManagerProperties,Logger alog) throws ServiceException{
  227.         this(connection, new JDBCServiceManagerProperties(serviceManagerProperties), alog);
  228.     }
  229.     public JDBCServiceManagerBase(Connection connection,JDBCServiceManagerProperties jdbcProperties,Logger alog) throws ServiceException{
  230.        
  231.         this.tipoCostruttore = JDBCServiceManagerTipoCostruttore.CONNECTION_OBJECT;
  232.        
  233.         if(alog==null){
  234.             this.log = LoggerWrapperFactory.getLogger(JDBCServiceManagerBase.class);
  235.         }else
  236.             this.log = alog;
  237.        
  238.         try{
  239.            
  240.             this.connection = connection;
  241.             if(this.connection == null){
  242.                 throw new ServiceException("Connection is null");
  243.             }
  244.            
  245.             this.jdbcProperties = jdbcProperties;
  246.             jdbcProperties.getDatabase(); // check tipoDatabase fornito
  247.            
  248.         } catch(Exception e) {
  249.             this.logError(CREATE_ERROR_PREFIX+e.getMessage(),e);
  250.             throw new ServiceException(CREATE_ERROR_PREFIX+e.getMessage(),e);
  251.         }
  252.     }
  253.    
  254.    
  255.     /* ** Destrory Service Manager */
  256.    
  257.     public void close() throws ServiceException{
  258.         try{
  259.             if(this.tipoCostruttore!=null && JDBCServiceManagerTipoCostruttore.CONNECTION_CFG.equals(this.tipoCostruttore) &&
  260.                     this.connection!=null){
  261.                 /**System.out.println("CLOSE (user:"+this.username+" connection-url: "+this.connectionUrl+")");*/
  262.                 JDBCUtilities.closeConnection(checkLogger, this.connection, checkAutocommit, checkIsClosed);
  263.             }
  264.         }catch(Exception e){
  265.             throw new ServiceException("Close failure: "+e.getMessage(),e);
  266.         }
  267.     }
  268.    
  269.    
  270.     /* ** Utilities */
  271.        
  272.     // Metodi che non devono essere utilizzati dagli sviluppatori jdbc che implementano i metodi veri e propri
  273.    
  274.     private static Logger checkLogger = null;
  275.     private static boolean checkIsClosed = true;
  276.     private static boolean checkAutocommit = true;
  277.     public static boolean isCheckIsClosed() {
  278.         return checkIsClosed;
  279.     }
  280.     public static void setCheckIsClosed(boolean checkIsClosed) {
  281.         JDBCServiceManagerBase.checkIsClosed = checkIsClosed;
  282.     }
  283.     public static boolean isCheckAutocommit() {
  284.         return checkAutocommit;
  285.     }
  286.     public static void setCheckAutocommit(boolean checkAutocommit) {
  287.         JDBCServiceManagerBase.checkAutocommit = checkAutocommit;
  288.     }
  289.     public static Logger getCheckLogger() {
  290.         return checkLogger;
  291.     }
  292.     public static void setCheckLogger(Logger checkLogger) {
  293.         JDBCServiceManagerBase.checkLogger = checkLogger;
  294.     }
  295.    
  296.     protected Connection getConnection() throws ServiceException {
  297.         try{
  298.             if(this.datasource!=null){
  299.                 return this.datasource.getConnection();
  300.             }
  301.             else if(this.connection!=null){
  302.                 if(JDBCServiceManagerTipoCostruttore.CONNECTION_CFG.equals(this.tipoCostruttore)) {
  303.                     this.refreshConnection();
  304.                 }
  305.                 return this.connection;
  306.             }else{
  307.                 throw new ServiceException("ServiceManager not initialized");
  308.             }
  309.         }catch(Exception e){
  310.             throw new ServiceException("Get Connection failure: "+e.getMessage(),e);
  311.         }
  312.     }
  313.     protected void closeConnection(Connection connection) throws ServiceException {
  314.         try{
  315.             if(connection==null){
  316.                 throw new ServiceException("Connection is null");
  317.             }
  318.             if(this.datasource!=null){
  319.                 // DATASOURCE_*
  320.                 JDBCUtilities.closeConnection(checkLogger, connection, checkAutocommit, checkIsClosed);
  321.             }
  322.             else if(this.connection!=null){
  323.                 // CONNECTION_*
  324.                 // se la connessione e' stata fornita come parametro del costruttore del service manager (quindi salvata in this.connection instance variable)
  325.                 // non deve essere mai chiusa. La gestione e' a carico di chi ha inizializzato il service manager fornendo la connessione:
  326.                 // - se ha usato il costruttore fornendo l'oggetto connection, deve fare lui la close sulla clonnection
  327.                 // - se ha usato il costruttore fornendo i dati per creare una connessione (url,username,password) deve chiamare il metodo close del service manager.
  328.                 if(connection.isClosed()){
  329.                     throw new ServiceException("The connection provided shall not be closed");
  330.                 }
  331.             }else{
  332.                 throw new ServiceException("ServiceManager not initialized");
  333.             }
  334.         }catch(Exception e){
  335.             throw new ServiceException("Get Connection failure: "+e.getMessage(),e);
  336.         }
  337.     }
  338.     public Logger getLog() {
  339.         return this.log;
  340.     }
  341.     public JDBCServiceManagerProperties getJdbcProperties() {
  342.         return this.jdbcProperties;
  343.     }
  344.    
  345.     /* Logger */
  346.     public static void configureDefaultLog4jProperties(IProjectInfo project) throws ServiceException{
  347.         JDBCLoggerProperties loggerProperties = new JDBCLoggerProperties(project);
  348.         loggerProperties.configureLog4j();
  349.     }
  350.     public static void configureLog4jProperties(File log4jProperties) throws ServiceException{
  351.         JDBCLoggerProperties loggerProperties = new JDBCLoggerProperties(null,log4jProperties);
  352.         loggerProperties.configureLog4j();
  353.     }
  354. }