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.plugins.crm.business.user;
35  
36  import fr.paris.lutece.plugins.crm.service.user.CRMUserAttributesService;
37  import fr.paris.lutece.portal.service.util.AppLogService;
38  import fr.paris.lutece.util.sql.DAOUtil;
39  
40  import org.apache.commons.beanutils.BeanUtils;
41  import org.apache.commons.lang3.StringUtils;
42  
43  import java.io.Serializable;
44  
45  import java.lang.reflect.InvocationTargetException;
46  
47  import java.util.HashMap;
48  import java.util.Map;
49  import java.util.Map.Entry;
50  
51  import javax.servlet.http.HttpServletRequest;
52  
53  /**
54   *
55   * CRMUserAttributeFilter
56   *
57   */
58  public class CRMUserFilter implements Serializable
59  {
60      public static final int MUST_BE_UPDATED_TRUE = 1;
61      public static final int MUST_BE_UPDATED_FALSE = 0;
62      private static final long serialVersionUID = -4489731073268811381L;
63      private static final String SQL_WHERE = " WHERE ";
64      private static final String SQL_AND = " AND ";
65      private static final String SQL_OR = " OR ";
66      private static final String SQL_PERCENT = "%";
67      // SQL FILTERS
68      private static final String SQL_FILTER_ID_CRM_USER = " cu.id_crm_user = ? ";
69      private static final String SQL_FILTER_USER_GUID = " cu.user_guid LIKE ? ";
70      private static final String SQL_FILTER_STATUS_ACTIVE = " cu.status = ? ";
71      private static final String SQL_FILTER_MUST_BE_UPDATED = " cu.must_be_updated = ? ";
72      private int _nIdCRMUser;
73      private String _strUserGuid;
74      private Map<String, String> _userInfos;
75      private int _nStatus = -1;
76      private int _nMustBeUpdated = -1;
77      private boolean _bIsWideSearch;
78  
79      /**
80       * Init.
81       *
82       * @param request
83       *            the request
84       */
85      public void init( HttpServletRequest request )
86      {
87          try
88          {
89              BeanUtils.populate( this, request.getParameterMap( ) );
90          }
91          catch( IllegalAccessException e )
92          {
93              AppLogService.error( "Unable to fetch data from request", e );
94          }
95          catch( InvocationTargetException e )
96          {
97              AppLogService.error( "Unable to fetch data from request", e );
98          }
99  
100         // LinkedHashMap to keep the FIFO behavior
101         _userInfos = new HashMap<String, String>( );
102 
103         for ( String strAttributeKey : CRMUserAttributesService.getService( ).getUserAttributeKeys( ) )
104         {
105             String strParamValue = request.getParameter( strAttributeKey );
106 
107             if ( StringUtils.isNotBlank( strParamValue ) )
108             {
109                 _userInfos.put( strAttributeKey, strParamValue );
110             }
111         }
112     }
113 
114     /**
115      * Set the id crm user
116      * 
117      * @param nIdCRMUser
118      *            the id crm user
119      */
120     public void setIdCRMUser( int nIdCRMUser )
121     {
122         _nIdCRMUser = nIdCRMUser;
123     }
124 
125     /**
126      * Get the id crm user
127      * 
128      * @return the id crm user
129      */
130     public int getIdCRMUser( )
131     {
132         return _nIdCRMUser;
133     }
134 
135     /**
136      * Contains id crm user.
137      *
138      * @return true, if successful
139      */
140     public boolean containsIdCRMUser( )
141     {
142         return _nIdCRMUser > 0;
143     }
144 
145     /**
146      * Set the user guid
147      * 
148      * @param strUserGuid
149      *            the user guid
150      */
151     public void setUserGuid( String strUserGuid )
152     {
153         _strUserGuid = strUserGuid;
154     }
155 
156     /**
157      * Get the user guid
158      * 
159      * @return the user guid
160      */
161     public String getUserGuid( )
162     {
163         return _strUserGuid;
164     }
165 
166     /**
167      * Contains user guid.
168      *
169      * @return true, if successful
170      */
171     public boolean containsUserGuid( )
172     {
173         return StringUtils.isNotBlank( _strUserGuid );
174     }
175 
176     /**
177      * Set the user attributes
178      * 
179      * @param userInfos
180      *            the user attributes
181      */
182     public void setUserAttributes( Map<String, String> userInfos )
183     {
184         _userInfos = userInfos;
185     }
186 
187     /**
188      * Get the user attributes
189      * 
190      * @return the user attributes
191      */
192     public Map<String, String> getUserAttributes( )
193     {
194         return _userInfos;
195     }
196 
197     /**
198      * Contains user attributes.
199      *
200      * @return true, if successful
201      */
202     public boolean containsUserAttributes( )
203     {
204         return ( _userInfos != null ) && !_userInfos.isEmpty( );
205     }
206 
207     /**
208      * Get the user attribute value
209      * 
210      * @param strUserAttributeKey
211      *            the key
212      * @return the user attribute value
213      */
214     public String getUserAttributeValue( String strUserAttributeKey )
215     {
216         String strUserInfoValue = StringUtils.EMPTY;
217 
218         if ( _userInfos != null )
219         {
220             strUserInfoValue = _userInfos.get( strUserAttributeKey );
221         }
222 
223         return StringUtils.isNotBlank( strUserInfoValue ) ? strUserInfoValue : StringUtils.EMPTY;
224     }
225 
226     /**
227      * Set true if the search is wide, false otherwise
228      * 
229      * @param isWideSearch
230      *            true if the search is wide, false otherwise
231      */
232     public void setWideSearch( boolean isWideSearch )
233     {
234         _bIsWideSearch = isWideSearch;
235     }
236 
237     /**
238      * Return true if the search is wide, false otherwise
239      * 
240      * @return true if the search is wide, false otherwise
241      */
242     public boolean isWideSearch( )
243     {
244         return _bIsWideSearch;
245     }
246 
247     /**
248      * @return the nStatus
249      */
250     public int getStatus( )
251     {
252         return _nStatus;
253     }
254 
255     /**
256      * @param nStatus
257      *            the nStatus to set
258      */
259     public void setStatus( int nStatus )
260     {
261         _nStatus = nStatus;
262     }
263 
264     /**
265      * Contains status.
266      */
267     public boolean containsStatus( )
268     {
269         return _nStatus > -1;
270     }
271 
272     /**
273      * 
274      * @return
275      */
276     public int getMustBeUpdated( )
277     {
278         return _nMustBeUpdated;
279     }
280 
281     /**
282      * 
283      * @param _nMustBeUpdated
284      */
285     public void setMustBeUpdated( int nMustBeUpdated )
286     {
287         this._nMustBeUpdated = nMustBeUpdated;
288     }
289 
290     /**
291      * Contains id crm user.
292      *
293      * @return true, if successful
294      */
295     public boolean containsMustBeUpdated( )
296     {
297         return _nMustBeUpdated > 0;
298     }
299 
300     /**
301      * Builds the sql query.
302      *
303      * @param strSQL
304      *            the str sql
305      * @return the string
306      */
307     public String buildSQLQuery( String strSQL )
308     {
309         StringBuilder sbSQL = new StringBuilder( strSQL );
310         int nIndex = 1;
311         nIndex = buildSQLQueryForAttribute( sbSQL, nIndex );
312         nIndex = buildFilter( sbSQL, containsIdCRMUser( ), SQL_FILTER_ID_CRM_USER, nIndex );
313         nIndex = buildFilter( sbSQL, containsUserGuid( ), SQL_FILTER_USER_GUID, nIndex );
314         nIndex = buildFilter( sbSQL, containsStatus( ), SQL_FILTER_STATUS_ACTIVE, nIndex );
315         buildFilter( sbSQL, containsStatus( ), SQL_FILTER_MUST_BE_UPDATED, nIndex );
316 
317         return sbSQL.toString( );
318     }
319 
320     /**
321      * Builds the sql query for attribute.
322      *
323      * @param sbSQL
324      *            the sb sql
325      * @param nIndex
326      *            the n index
327      * @return the int
328      */
329     public int buildSQLQueryForAttribute( StringBuilder sbSQL, int nIndex )
330     {
331         int nIndexTmp = nIndex;
332 
333         if ( containsUserAttributes( ) )
334         {
335             for ( int nI = 0; nI < _userInfos.size( ); nI++ )
336             {
337                 sbSQL.append( " INNER JOIN crm_user_attribute AS cua" + nI );
338                 sbSQL.append( " ON cu.id_crm_user = cua" + nI + ".id_crm_user" );
339             }
340 
341             for ( int nI = 0; nI < _userInfos.size( ); nI++ )
342             {
343                 // 2 interrogations marks, so nIndexTmp should add 2
344                 nIndexTmp = addSQLWhereOr( isWideSearch( ), sbSQL, nIndexTmp ) + 1;
345                 sbSQL.append( " cua" + nI + ".user_attribute_key = ? AND cua" + nI + ".user_attribute_value LIKE ? " );
346             }
347         }
348 
349         return nIndexTmp;
350     }
351 
352     /**
353      * Sets the filter values.
354      *
355      * @param daoUtil
356      *            the new filter values
357      */
358     public void setFilterValues( DAOUtil daoUtil )
359     {
360         int nIndex = 1;
361 
362         if ( containsUserAttributes( ) )
363         {
364             for ( Entry<String, String> param : _userInfos.entrySet( ) )
365             {
366                 daoUtil.setString( nIndex++, param.getKey( ) );
367                 daoUtil.setString( nIndex++, SQL_PERCENT + param.getValue( ) + SQL_PERCENT );
368             }
369         }
370 
371         if ( containsIdCRMUser( ) )
372         {
373             daoUtil.setInt( nIndex++, getIdCRMUser( ) );
374         }
375 
376         if ( containsUserGuid( ) )
377         {
378             daoUtil.setString( nIndex++, SQL_PERCENT + getUserGuid( ) + SQL_PERCENT );
379         }
380 
381         if ( containsStatus( ) )
382         {
383             daoUtil.setInt( nIndex++, getStatus( ) );
384         }
385 
386         if ( containsMustBeUpdated( ) )
387         {
388             daoUtil.setInt( nIndex++, getMustBeUpdated( ) );
389         }
390 
391     }
392 
393     /**
394      * Builds the filter.
395      *
396      * @param sbSQL
397      *            the sb sql
398      * @param bAddFilter
399      *            the b add filter
400      * @param strSQL
401      *            the str sql
402      * @param nIndex
403      *            the n index
404      * @return the int
405      */
406     private int buildFilter( StringBuilder sbSQL, boolean bAddFilter, String strSQL, int nIndex )
407     {
408         int nIndexTmp = nIndex;
409 
410         if ( bAddFilter )
411         {
412             nIndexTmp = addSQLWhereOr( isWideSearch( ), sbSQL, nIndex );
413             sbSQL.append( strSQL );
414         }
415 
416         return nIndexTmp;
417     }
418 
419     /**
420      * Add a <b>WHERE</b> or a <b>OR</b> depending of the index. <br/>
421      * <ul>
422      * <li>if <code>nIndex</code> == 1, then we add a <b>WHERE</b></li>
423      * <li>if <code>nIndex</code> != 1, then we add a <b>OR</b> or a <b>AND</b> depending of the wide search characteristic</li>
424      * </ul>
425      * 
426      * @param bIsWideSearch
427      *            true if it is a wide search, false otherwise
428      * @param sbSQL
429      *            the SQL query
430      * @param nIndex
431      *            the index
432      * @return the new index
433      */
434     private int addSQLWhereOr( boolean bIsWideSearch, StringBuilder sbSQL, int nIndex )
435     {
436         if ( nIndex == 1 )
437         {
438             sbSQL.append( SQL_WHERE );
439         }
440         else
441         {
442             sbSQL.append( bIsWideSearch ? SQL_OR : SQL_AND );
443         }
444 
445         return nIndex + 1;
446     }
447 
448 }