View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de 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  
36  import fr.paris.lutece.portal.service.plugin.PluginEvent;
37  import fr.paris.lutece.portal.service.plugin.PluginEventListener;
38  import fr.paris.lutece.portal.service.plugin.PluginService;
39  import fr.paris.lutece.util.sql.TransactionManager;
40  
41  import org.apache.commons.lang.StringUtils;
42  
43  import org.apache.log4j.Logger;
44  
45  import org.springframework.jdbc.datasource.DataSourceTransactionManager;
46  
47  import java.io.PrintWriter;
48  
49  import java.sql.Connection;
50  import java.sql.SQLException;
51  import java.sql.SQLFeatureNotSupportedException;
52  
53  import javax.sql.DataSource;
54  
55  
56  /**
57   * DataSource transaction manager. This transaction manager use Spring
58   * transaction manager, and do not use {@link TransactionManager}. This
59   * transaction manager allow to use transaction in a given plugin, but does not
60   * influence other plugins. To create transactions throw multiple plugins, use
61   * {@link LuteceTransactionManager}
62   */
63  public class DAOUtilTransactionManager extends DataSourceTransactionManager implements PluginEventListener
64  {
65      private static final long serialVersionUID = -654531540978261621L;
66      private Logger _logger = Logger.getLogger( "lutece.debug.sql.tx" );
67      private String _strPluginName;
68      private boolean _bInit;
69  
70      /**
71       * Registers the listener to {@link PluginService}.
72       */
73      public DAOUtilTransactionManager(  )
74      {
75          PluginService.registerPluginEventListener( this );
76      }
77  
78      /**
79       * Gets the plugin name
80       * @return the plugin name
81       */
82      public String getPluginName(  )
83      {
84          return _strPluginName;
85      }
86  
87      /**
88       * Sets the plugin name
89       * @param strPluginName the plugin name
90       */
91      public void setPluginName( String strPluginName )
92      {
93          _strPluginName = strPluginName;
94      }
95  
96      /**
97       * {@inheritDoc}
98       */
99      @Override
100     public void processPluginEvent( PluginEvent event )
101     {
102         if ( getPluginName(  ).equals( event.getPlugin(  ).getName(  ) ) )
103         {
104             if ( ( event.getEventType(  ) == PluginEvent.PLUGIN_INSTALLED ) ||
105                     ( event.getEventType(  ) == PluginEvent.PLUGIN_POOL_CHANGED ) )
106             {
107                 if ( StringUtils.isNotBlank( event.getPlugin(  ).getDbPoolName(  ) ) &&
108                         !AppConnectionService.NO_POOL_DEFINED.equals( event.getPlugin(  ).getDbPoolName(  ) ) )
109                 {
110                     try
111                     {
112                         _logger.debug( "DAOUtilTransactionManager changed datasource status..." );
113                         setDataSource( AppConnectionService.getPoolManager(  )
114                                                            .getDataSource( event.getPlugin(  ).getDbPoolName(  ) ) );
115                         _bInit = true;
116                     }
117                     catch ( Exception ex )
118                     {
119                         _bInit = false;
120                         _logger.error( "An error occured getting pool for DAOUtilTransactionManager for plugin " +
121                             event.getPlugin(  ).getName(  ) +
122                             ", please check plugin is activated and pool is correctly set : " + ex.getMessage(  ), ex );
123                     }
124                 }
125                 else
126                 {
127                     _logger.debug( "Pool for plugin " + event.getPlugin(  ).getName(  ) +
128                         " is set to null, clearing transaction manager" );
129                     setDataSource( null );
130                     _bInit = false;
131                 }
132             }
133             else if ( event.getEventType(  ) == PluginEvent.PLUGIN_UNINSTALLED )
134             {
135                 setDataSource( null );
136                 _bInit = false;
137             }
138         }
139     }
140 
141     /**
142      * Returns a "fake" datasource to avoid spring checks failure when pool are
143      * not initialized.
144      * Returns the current datasource otherwise.
145      *
146      * @return the data source
147      */
148     @Override
149     public DataSource getDataSource(  )
150     {
151         if ( _bInit )
152         {
153             return super.getDataSource(  );
154         }
155 
156         /**
157          * Empty datasource
158          */
159         return new EmptyDataSource(  );
160     }
161 
162     /**
163      * Empty datasource
164      */
165     private static class EmptyDataSource implements DataSource
166     {
167         @Override
168         public <T> T unwrap( Class<T> iface ) throws SQLException
169         {
170             return null;
171         }
172 
173         @Override
174         public boolean isWrapperFor( Class<?> iface ) throws SQLException
175         {
176             return false;
177         }
178 
179         @Override
180         public void setLoginTimeout( int seconds ) throws SQLException
181         {
182         }
183 
184         @Override
185         public void setLogWriter( PrintWriter out ) throws SQLException
186         {
187         }
188 
189         @Override
190         public int getLoginTimeout(  ) throws SQLException
191         {
192             return 0;
193         }
194 
195         @Override
196         public PrintWriter getLogWriter(  ) throws SQLException
197         {
198             return null;
199         }
200 
201         @Override
202         public Connection getConnection( String username, String password )
203             throws SQLException
204         {
205             return null;
206         }
207 
208         @Override
209         public Connection getConnection(  ) throws SQLException
210         {
211             return null;
212         }
213 
214         /**
215          * Get the parent logger
216          * @return the logger
217          * @throws SQLFeatureNotSupportedException if this method is not
218          *             supported
219          */
220         public java.util.logging.Logger getParentLogger(  )
221             throws SQLFeatureNotSupportedException
222         {
223             throw new SQLFeatureNotSupportedException(  );
224         }
225     }
226 }