View Javadoc
1   /*
2    * Copyright (c) 2002-2020, 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.plugins.stock.business.provider;
35  
36  import fr.paris.lutece.plugins.stock.commons.ResultList;
37  import fr.paris.lutece.plugins.stock.commons.dao.AbstractStockDAO;
38  import fr.paris.lutece.plugins.stock.commons.dao.PaginationProperties;
39  import fr.paris.lutece.plugins.stock.service.StockPlugin;
40  import fr.paris.lutece.plugins.stock.utils.jpa.StockJPAUtils;
41  
42  import java.util.ArrayList;
43  import java.util.List;
44  
45  import javax.persistence.EntityManager;
46  import javax.persistence.TypedQuery;
47  import javax.persistence.criteria.CriteriaBuilder;
48  import javax.persistence.criteria.CriteriaQuery;
49  import javax.persistence.criteria.JoinType;
50  import javax.persistence.criteria.Order;
51  import javax.persistence.criteria.Predicate;
52  import javax.persistence.criteria.Root;
53  
54  import org.apache.commons.lang3.StringUtils;
55  
56  /**
57   * This class provides Data Access methods for {@link Provider} objects
58   */
59  public final class ProviderDAO extends AbstractStockDAO<Integer, Provider> implements IProviderDAO
60  {
61      /**
62       * {@inheritDoc}
63       */
64      @Override
65      public String getPluginName( )
66      {
67          return StockPlugin.PLUGIN_NAME;
68      }
69  
70      /**
71       * Find all providers with product fetched.
72       * 
73       * @param paginationProperties
74       *            the pagination properties
75       * @return list of providers
76       */
77      public List<Provider> findAllWithProducts( PaginationProperties paginationProperties )
78      {
79          EntityManager em = getEM( );
80          CriteriaBuilder cb = em.getCriteriaBuilder( );
81  
82          CriteriaQuery<Provider> cq = cb.createQuery( Provider.class );
83  
84          Root<Provider> root = cq.from( Provider.class );
85          root.fetch( Provider_.products, JoinType.LEFT );
86          cq.distinct( true );
87  
88          TypedQuery<Provider> query = em.createQuery( cq );
89  
90          return query.getResultList( );
91      }
92  
93      /**
94       * Find provider by id with product fetched
95       * 
96       * @param nId
97       *            the id
98       * @return the provider found
99       */
100     public Provider findByIdWithProducts( int nId )
101     {
102         EntityManager em = getEM( );
103         CriteriaBuilder cb = em.getCriteriaBuilder( );
104 
105         CriteriaQuery<Provider> cq = cb.createQuery( Provider.class );
106 
107         Root<Provider> root = cq.from( Provider.class );
108         root.fetch( Provider_.products, JoinType.LEFT );
109         cq.where( cb.equal( root.get( Provider_.id ), nId ) );
110         cq.distinct( true );
111 
112         TypedQuery<Provider> query = em.createQuery( cq );
113 
114         return query.getSingleResult( );
115     }
116 
117     /**
118      * Find providers by filter.
119      * 
120      * @param filter
121      *            the filter
122      * @param paginationProperties
123      *            the pagination properties
124      * @return list of providers
125      */
126     public ResultList<Provider> findByFilter( ProviderFilter filter, PaginationProperties paginationProperties )
127     {
128         EntityManager em = getEM( );
129         CriteriaBuilder cb = em.getCriteriaBuilder( );
130 
131         CriteriaQuery<Provider> cq = cb.createQuery( Provider.class );
132 
133         Root<Provider> root = cq.from( Provider.class );
134         buildCriteriaQuery( filter, root, cq, cb );
135         buildSortQuery( filter, root, cq, cb );
136         cq.distinct( true );
137 
138         return createPagedQuery( cq, paginationProperties ).getResultList( );
139     }
140 
141     /**
142      * Build the criteria query used when providers are searched by filter
143      * 
144      * @param filter
145      *            the filter
146      * @param root
147      *            the provider root
148      * @param query
149      *            the criteria query
150      * @param builder
151      *            the criteria builder
152      */
153     private void buildCriteriaQuery( ProviderFilter filter, Root<Provider> root, CriteriaQuery<Provider> query, CriteriaBuilder builder )
154     {
155         // predicates list
156         List<Predicate> listPredicates = new ArrayList<>( );
157 
158         if ( StringUtils.isNotBlank( filter.getName( ) ) )
159         {
160             listPredicates.add( builder.like( root.get( Provider_.name ), StockJPAUtils.buildCriteriaLikeString( filter.getName( ) ) ) );
161         }
162 
163         if ( StringUtils.isNotBlank( filter.getAddress( ) ) )
164         {
165             listPredicates.add( builder.like( root.get( Provider_.address ), StockJPAUtils.buildCriteriaLikeString( filter.getAddress( ) ) ) );
166         }
167 
168         if ( StringUtils.isNotBlank( filter.getContactName( ) ) )
169         {
170             listPredicates.add( builder.like( root.get( Provider_.contactName ), StockJPAUtils.buildCriteriaLikeString( filter.getContactName( ) ) ) );
171         }
172 
173         if ( StringUtils.isNotBlank( filter.getMail( ) ) )
174         {
175             listPredicates.add( builder.like( root.get( Provider_.mail ), StockJPAUtils.buildCriteriaLikeString( filter.getMail( ) ) ) );
176         }
177 
178         if ( StringUtils.isNotBlank( filter.getPhoneNumber( ) ) )
179         {
180             listPredicates.add( builder.like( root.get( Provider_.phoneNumber ), StockJPAUtils.buildCriteriaLikeString( filter.getPhoneNumber( ) ) ) );
181         }
182 
183         if ( filter.isProducts( ) )
184         {
185             root.fetch( Provider_.products, JoinType.LEFT );
186         }
187 
188         if ( !listPredicates.isEmpty( ) )
189         {
190             // add existing predicates to Where clause
191             query.where( listPredicates.toArray( new Predicate [ listPredicates.size( )] ) );
192         }
193     }
194 
195     /**
196      * Add the order by parameter to the query
197      * 
198      * @param filter
199      *            the filter
200      * @param root
201      *            the provider root
202      * @param query
203      *            the criteria query
204      * @param builder
205      *            the criteria builder
206      */
207     private void buildSortQuery( ProviderFilter filter, Root<Provider> root, CriteriaQuery<Provider> query, CriteriaBuilder builder )
208     {
209         if ( filter.getOrders( ) != null && !filter.getOrders( ).isEmpty( ) )
210         {
211             List<Order> orderList = new ArrayList<>( );
212 
213             if ( filter.isOrderAsc( ) )
214             {
215                 // get asc order
216                 for ( String order : filter.getOrders( ) )
217                 {
218                     orderList.add( builder.asc( root.get( order ) ) );
219                 }
220             }
221             else
222             {
223                 // get desc order
224                 for ( String order : filter.getOrders( ) )
225                 {
226                     orderList.add( builder.desc( root.get( order ) ) );
227                 }
228             }
229 
230             query.orderBy( orderList );
231         }
232     }
233 }