DAOUtilTransactionManager.java

  1. /*
  2.  * Copyright (c) 2002-2022, City of Paris
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  *  1. Redistributions of source code must retain the above copyright notice
  10.  *     and the following disclaimer.
  11.  *
  12.  *  2. Redistributions in binary form must reproduce the above copyright notice
  13.  *     and the following disclaimer in the documentation and/or other materials
  14.  *     provided with the distribution.
  15.  *
  16.  *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
  17.  *     contributors may be used to endorse or promote products derived from
  18.  *     this software without specific prior written permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
  24.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30.  * POSSIBILITY OF SUCH DAMAGE.
  31.  *
  32.  * License 1.0
  33.  */
  34. package fr.paris.lutece.portal.service.database;

  35. import fr.paris.lutece.portal.service.plugin.PluginEvent;
  36. import fr.paris.lutece.portal.service.plugin.PluginEventListener;
  37. import fr.paris.lutece.portal.service.plugin.PluginService;
  38. import fr.paris.lutece.util.sql.TransactionManager;

  39. import org.apache.commons.lang3.StringUtils;
  40. import org.apache.logging.log4j.LogManager;
  41. import org.apache.logging.log4j.Logger;
  42. import org.springframework.jdbc.datasource.DataSourceTransactionManager;

  43. import java.io.PrintWriter;

  44. import java.sql.Connection;
  45. import java.sql.SQLException;
  46. import java.sql.SQLFeatureNotSupportedException;

  47. import javax.sql.DataSource;

  48. /**
  49.  * DataSource transaction manager. This transaction manager use Spring transaction manager, and do not use {@link TransactionManager}. This transaction manager
  50.  * allow to use transaction in a given plugin, but does not influence other plugins. To create transactions throw multiple plugins, use
  51.  * {@link LuteceTransactionManager}
  52.  */
  53. public class DAOUtilTransactionManager extends DataSourceTransactionManager implements PluginEventListener
  54. {
  55.     private static final long serialVersionUID = -654531540978261621L;
  56.     private transient Logger _logger = LogManager.getLogger( "lutece.debug.sql.tx" );
  57.     private String _strPluginName;
  58.     private boolean _bInit;

  59.     /**
  60.      * Registers the listener to {@link PluginService}.
  61.      */
  62.     public DAOUtilTransactionManager( )
  63.     {
  64.         PluginService.registerPluginEventListener( this );
  65.     }

  66.     /**
  67.      * Gets the plugin name
  68.      *
  69.      * @return the plugin name
  70.      */
  71.     public String getPluginName( )
  72.     {
  73.         return _strPluginName;
  74.     }

  75.     /**
  76.      * Sets the plugin name
  77.      *
  78.      * @param strPluginName
  79.      *            the plugin name
  80.      */
  81.     public void setPluginName( String strPluginName )
  82.     {
  83.         _strPluginName = strPluginName;
  84.     }

  85.     /**
  86.      * {@inheritDoc}
  87.      */
  88.     @Override
  89.     public void processPluginEvent( PluginEvent event )
  90.     {
  91.         if ( getPluginName( ).equals( event.getPlugin( ).getName( ) ) )
  92.         {
  93.             if ( ( event.getEventType( ) == PluginEvent.PLUGIN_INSTALLED ) || ( event.getEventType( ) == PluginEvent.PLUGIN_POOL_CHANGED ) )
  94.             {
  95.                 if ( StringUtils.isNotBlank( event.getPlugin( ).getDbPoolName( ) )
  96.                         && !AppConnectionService.NO_POOL_DEFINED.equals( event.getPlugin( ).getDbPoolName( ) ) )
  97.                 {
  98.                     try
  99.                     {
  100.                         getLogger( ).debug( "DAOUtilTransactionManager changed datasource status..." );
  101.                         setDataSource( AppConnectionService.getPoolManager( ).getDataSource( event.getPlugin( ).getDbPoolName( ) ) );
  102.                         _bInit = true;
  103.                     }
  104.                     catch( Exception ex )
  105.                     {
  106.                         _bInit = false;
  107.                         getLogger( ).error(
  108.                                 "An error occured getting pool for DAOUtilTransactionManager for plugin {} , please check plugin is activated and pool is correctly set : {}",
  109.                                 event.getPlugin( ).getName( ), ex.getMessage( ), ex );
  110.                     }
  111.                 }
  112.                 else
  113.                 {
  114.                     getLogger( ).debug( "Pool for plugin {} is set to null, clearing transaction manager", event.getPlugin( ).getName( ) );
  115.                     setDataSource( null );
  116.                     _bInit = false;
  117.                 }
  118.             }
  119.             else
  120.                 if ( event.getEventType( ) == PluginEvent.PLUGIN_UNINSTALLED )
  121.                 {
  122.                     setDataSource( null );
  123.                     _bInit = false;
  124.                 }
  125.         }
  126.     }

  127.     private Logger getLogger( )
  128.     {
  129.         if ( _logger == null )
  130.         {
  131.             _logger = LogManager.getLogger( "lutece.debug.sql.tx" );
  132.         }
  133.         return _logger;
  134.     }

  135.     /**
  136.      * Returns a "fake" datasource to avoid spring checks failure when pool are not initialized. Returns the current datasource otherwise.
  137.      *
  138.      * @return the data source
  139.      */
  140.     @Override
  141.     public DataSource getDataSource( )
  142.     {
  143.         if ( _bInit )
  144.         {
  145.             return super.getDataSource( );
  146.         }

  147.         /**
  148.          * Empty datasource
  149.          */
  150.         return new EmptyDataSource( );
  151.     }

  152.     /**
  153.      * Empty datasource
  154.      */
  155.     private static class EmptyDataSource implements DataSource
  156.     {
  157.         @Override
  158.         public <T> T unwrap( Class<T> iface ) throws SQLException
  159.         {
  160.             return null;
  161.         }

  162.         @Override
  163.         public boolean isWrapperFor( Class<?> iface ) throws SQLException
  164.         {
  165.             return false;
  166.         }

  167.         @Override
  168.         public void setLoginTimeout( int seconds ) throws SQLException
  169.         {
  170.             // Do nothing
  171.         }

  172.         @Override
  173.         public void setLogWriter( PrintWriter out ) throws SQLException
  174.         {
  175.             // Do nothing
  176.         }

  177.         @Override
  178.         public int getLoginTimeout( ) throws SQLException
  179.         {
  180.             return 0;
  181.         }

  182.         @Override
  183.         public PrintWriter getLogWriter( ) throws SQLException
  184.         {
  185.             return null;
  186.         }

  187.         @Override
  188.         public Connection getConnection( String username, String password ) throws SQLException
  189.         {
  190.             return null;
  191.         }

  192.         @Override
  193.         public Connection getConnection( ) throws SQLException
  194.         {
  195.             return null;
  196.         }

  197.         /**
  198.          * Get the parent logger
  199.          *
  200.          * @return the logger
  201.          * @throws SQLFeatureNotSupportedException
  202.          *             if this method is not supported
  203.          */
  204.         public java.util.logging.Logger getParentLogger( ) throws SQLFeatureNotSupportedException
  205.         {
  206.             throw new SQLFeatureNotSupportedException( );
  207.         }
  208.     }
  209. }