View Javadoc
1   package fr.ifremer.dali.dao.administration.user;
2   
3   /*
4    * #%L
5    * Dali :: Core
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2013 - 2014 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  import com.google.common.collect.ImmutableList;
27  import com.google.common.collect.ImmutableListMultimap;
28  import com.google.common.collect.Multimap;
29  import fr.ifremer.dali.config.DaliConfiguration;
30  import fr.ifremer.dali.dao.referential.DaliReferentialDao;
31  import fr.ifremer.dali.dao.technical.Daos;
32  import fr.ifremer.dali.dto.DaliBeanFactory;
33  import fr.ifremer.dali.dto.referential.PersonDTO;
34  import fr.ifremer.dali.dto.referential.PrivilegeDTO;
35  import fr.ifremer.quadrige3.core.dao.administration.user.PrivilegeCode;
36  import fr.ifremer.quadrige3.core.dao.administration.user.Quser;
37  import fr.ifremer.quadrige3.core.dao.administration.user.QuserDaoImpl;
38  import fr.ifremer.quadrige3.core.service.technical.CacheService;
39  import org.apache.commons.collections4.CollectionUtils;
40  import org.apache.commons.lang3.StringUtils;
41  import org.hibernate.Query;
42  import org.hibernate.SessionFactory;
43  import org.hibernate.type.IntegerType;
44  import org.hibernate.type.StringType;
45  import org.springframework.beans.factory.annotation.Autowired;
46  import org.springframework.cache.Cache;
47  import org.springframework.context.annotation.Lazy;
48  import org.springframework.dao.DataRetrievalFailureException;
49  import org.springframework.stereotype.Repository;
50  
51  import javax.annotation.Resource;
52  import java.util.*;
53  
54  import static org.nuiton.i18n.I18n.t;
55  
56  /**
57   * <p>DaliQuserDaoImpl class.</p>
58   *
59   */
60  @Repository("daliQuserDao")
61  @Lazy
62  public class DaliQuserDaoImpl extends QuserDaoImpl implements DaliQuserDao {
63  
64      private static final Multimap<String, String> columnNamesByProgramTableNames = ImmutableListMultimap.<String, String>builder()
65              .put("RULE_LIST_RESP_QUSER", "QUSER_ID")
66              .put("PROG_QUSER_PROG_PRIV", "QUSER_ID").build();
67  
68      private static final Multimap<String, String> columnNamesByRulesTableNames = ImmutableListMultimap.<String, String>builder()
69              .put("RULE_LIST_RESP_QUSER", "QUSER_ID").build();
70  
71      private static final Multimap<String, String> columnNamesByDataTableNames = ImmutableListMultimap.<String, String>builder()
72              .put("CAMPAIGN", "QUSER_ID")
73              .put("OCCAS_QUSER", "QUSER_ID")
74              .put("CONTEXT", "QUSER_ID")
75              .put("FILTER", "QUSER_ID")
76              .put("DELETED_ITEM_HISTORY", "REC_QUSER_ID")
77              .put("QUALIFICATION_HISTORY", "QUSER_ID").build();
78  
79      private static final Multimap<String, String> columnNamesBySurveyTableNames = ImmutableListMultimap.<String, String>builder()
80              .put("SURVEY_QUSER", "QUSER_ID").build();
81  
82      @Resource
83      protected DaliConfiguration config;
84  
85      @Resource
86      protected CacheService cacheService;
87  
88      @Resource(name = "daliDepartmentDao")
89      protected DaliDepartmentDao departmentDao;
90  
91      @Resource(name = "daliReferentialDao")
92      protected DaliReferentialDao referentialDao;
93  
94      /**
95       * <p>Constructor for DaliQuserDaoImpl.</p>
96       *
97       * @param sessionFactory a {@link org.hibernate.SessionFactory} object.
98       */
99      @Autowired
100     public DaliQuserDaoImpl(SessionFactory sessionFactory) {
101         super(sessionFactory);
102     }
103 
104     /** {@inheritDoc} */
105     @Override
106     public PersonDTO getUserById(int quserId) {
107         Object[] row = queryUnique("userById",
108                 "quserId", IntegerType.INSTANCE, quserId);
109 
110         if (row == null) {
111             throw new DataRetrievalFailureException(String.format("can't load quser with id = %s", quserId));
112         }
113         return toPersonDTO(Arrays.asList(row).iterator());
114     }
115 
116     /** {@inheritDoc} */
117     @Override
118     public List<PersonDTO> getAllUsers(List<String> statusCodes) {
119         Cache personByIdCache = cacheService.getCache(USER_BY_ID_CACHE);
120 
121         Iterator<Object[]> list = Daos.queryIteratorWithStatus(createQuery("allUsers"), statusCodes);
122 
123         List<PersonDTO> result = new ArrayList<>();
124         while (list.hasNext()) {
125             Object[] source = list.next();
126             PersonDTO target = toPersonDTO(Arrays.asList(source).iterator());
127             result.add(target);
128 
129             // Add to cache by id
130             personByIdCache.put(target.getId(), target);
131         }
132         return result;
133     }
134 
135     /** {@inheritDoc} */
136     @Override
137     public List<PersonDTO> findUsersByCriteria(String lastName, String firstName, boolean strictName, String login, Integer departmentId, String privilegeCode, List<String> statusCodes) {
138         Query q = createQuery("usersByCriteria",
139                 "lastName", StringType.INSTANCE, strictName ? null : lastName,
140                 "firstName", StringType.INSTANCE, strictName ? null : firstName,
141                 "strictLastName", StringType.INSTANCE, strictName ? lastName : null,
142                 "strictFirstName", StringType.INSTANCE, strictName ? firstName : null,
143                 "departmentId", IntegerType.INSTANCE, departmentId,
144                 "privilegeCd", StringType.INSTANCE, privilegeCode,
145                 "login", StringType.INSTANCE, login);
146 
147         Iterator<Object[]> list = Daos.queryIteratorWithStatus(q, statusCodes);
148         List<PersonDTO> result = new ArrayList<>();
149         while (list.hasNext()) {
150             Object[] source = list.next();
151             PersonDTO target = toPersonDTO(Arrays.asList(source).iterator());
152 
153             // append privileges
154             target.addAllPrivilege(getPrivilegesByUserId(target.getId()));
155 
156             result.add(target);
157         }
158         return ImmutableList.copyOf(result);
159     }
160 
161     /** {@inheritDoc} */
162     @Override
163     public PersonDTO getUserByLogin(List<String> statusCodes, String login) {
164         Iterator<Object[]> list = Daos.queryIteratorWithStatus(createQuery("usersByLogin", "login", StringType.INSTANCE, login), statusCodes);
165 
166         // take the first user to eliminate duplicates (should be a local user if exists first)
167         if (list.hasNext()) {
168             Object[] row = list.next();
169             return toPersonDTO(Arrays.asList(row).iterator());
170         }
171         return null;
172     }
173 
174     /** {@inheritDoc} */
175     @Override
176     @SuppressWarnings("unchecked")
177     public List<PersonDTO> getUsersByIds(List<Integer> userIds) {
178         List<PersonDTO> result = new ArrayList<>();
179         if (CollectionUtils.isNotEmpty(userIds)) {
180             Query q = createQuery("usersByIds").setParameterList("quserIds", userIds);
181             Iterator<Object[]> it = q.iterate();
182             while (it.hasNext()) {
183                 result.add(toPersonDTO(Arrays.asList(it.next()).iterator()));
184             }
185         }
186         return result;
187     }
188 
189     /** {@inheritDoc} */
190     @Override
191     public List<PrivilegeDTO> getAllPrivileges() {
192         Iterator<Object[]> list = queryIterator("allPrivileges");
193 
194         List<PrivilegeDTO> result = new ArrayList<>();
195         while (list.hasNext()) {
196             Object[] source = list.next();
197             PrivilegeDTO target = toPrivilegeDTO(Arrays.asList(source).iterator());
198             result.add(target);
199         }
200         return result;
201     }
202 
203     /** {@inheritDoc} */
204     @Override
205     public Collection<PrivilegeDTO> getPrivilegesByUserId(Integer userId) {
206         Iterator<Object[]> list = queryIterator("privilegesByUserId",
207                 "userId", IntegerType.INSTANCE, userId);
208 
209         List<PrivilegeDTO> result = new ArrayList<>();
210         while (list.hasNext()) {
211             Object[] source = list.next();
212             PrivilegeDTO target = toPrivilegeDTO(Arrays.asList(source).iterator());
213             result.add(target);
214         }
215         return result;
216 
217     }
218 
219     /** {@inheritDoc} */
220     @Override
221     public boolean isUserUsedInProgram(int id) {
222 
223         return executeMultipleCount(columnNamesByProgramTableNames, id);
224     }
225 
226     /** {@inheritDoc} */
227     @Override
228     public boolean isUserUsedInRules(int id) {
229         return executeMultipleCount(columnNamesByRulesTableNames, id);
230     }
231 
232     /** {@inheritDoc} */
233     @Override
234     public boolean isUserUsedInData(int id) {
235 
236         return executeMultipleCount(columnNamesByDataTableNames, id)
237                 || executeMultipleCount(columnNamesBySurveyTableNames, id);
238     }
239 
240     /** {@inheritDoc} */
241     @Override
242     public boolean isUserUsedInValidatedData(int id) {
243 
244         // query SURVEY_QUSER first to fasten this method
245         if (!executeMultipleCount(columnNamesBySurveyTableNames, id)) {
246             return false;
247         }
248 
249         // now query with join on survey
250         long count = queryCount("countValidatedSurveyByQuserId", "quserId", IntegerType.INSTANCE, id);
251 
252         return count > 0;
253     }
254 
255     /** {@inheritDoc} */
256     @Override
257     public Object transformEntity(final int transform, final Quser entity) {
258         if (entity != null) {
259             if (transform == DaliQuserDao.TRANSFORM_PERSON_DTO) { // fall-through
260                 return toPersonDTO(entity);
261             }
262             return super.transformEntity(transform, entity);
263         }
264         return null;
265     }
266 
267     /**
268      * {@inheritDoc}
269      *
270      * Transforms a collection of entities using the {@link #transformEntities(int, Collection)} method. This method
271      * does not instantiate a new collection.
272      * <p/>
273      * This method is to be used internally only.
274      * @see #transformEntities(int, Collection)
275      */
276     @Override
277     public void transformEntities(final int transform, final java.util.Collection<?> entities) {
278         if (transform == TRANSFORM_PERSON_DTO) {
279             toPersonDTOCollection(entities);
280         } else {
281             super.transformEntities(transform, entities);
282             // do nothing;
283         }
284     }
285 
286     /* -- Internal Methods -- */
287     /**
288      * <p>toPersonDTO.</p>
289      *
290      * @param source a {@link java.util.Iterator} object.
291      * @return a {@link fr.ifremer.dali.dto.referential.PersonDTO} object.
292      */
293     private PersonDTO toPersonDTO(Iterator<Object> source) {
294         PersonDTO target = DaliBeanFactory.newPersonDTO();
295 
296         // Id
297         target.setId((Integer) source.next());
298 
299         // Registration Code
300         target.setRegCode((String) source.next());
301 
302         // LastName:
303         String lastname = (String) source.next();
304         if (StringUtils.isBlank(lastname) || "-".equals(lastname)) {
305             lastname = "";
306         }
307         target.setName(lastname);
308 
309         // FirstName:
310         String firstname = (String) source.next();
311         if (StringUtils.isBlank(firstname) || "-".equals(firstname)) {
312             firstname = "";
313         }
314         target.setFirstName(firstname);
315 
316         // Department (id)
317         target.setDepartment(departmentDao.getDepartmentById((Integer) source.next()));
318 
319         // logins
320         target.setIntranetLogin((String) source.next());
321         target.setExtranetLogin((String) source.next());
322         target.setHasPassword(StringUtils.isNotBlank((CharSequence) source.next()));
323 
324         // email
325         target.setEmail((String) source.next());
326 
327         // phone
328         target.setPhone((String) source.next());
329 
330         // address
331         target.setAddress((String) source.next());
332 
333         // organism
334         target.setOrganism((String) source.next());
335 
336         // admin center
337         target.setAdminCenter((String) source.next());
338 
339         // site
340         target.setSite((String) source.next());
341 
342         // Status (code)
343         target.setStatus(referentialDao.getStatusByCode((String) source.next()));
344 
345         target.setComment((String) source.next());
346         target.setCreationDate(Daos.convertToDate(source.next()));
347         target.setUpdateDate(Daos.convertToDate(source.next()));
348 
349         return target;
350     }
351 
352     /**
353      * <p>toPersonDTO.</p>
354      *
355      * @param source a {@link fr.ifremer.quadrige3.core.dao.administration.user.Quser} object.
356      * @return a {@link fr.ifremer.dali.dto.referential.PersonDTO} object.
357      */
358     private PersonDTO toPersonDTO(Quser source) {
359         PersonDTO target = DaliBeanFactory.newPersonDTO();
360         target.setId(source.getQuserId());
361         target.setRegCode(source.getQuserCd());
362         target.setName(source.getQuserLastNm());
363         target.setFirstName(source.getQuserFirstNm());
364         target.setDepartment(departmentDao.getDepartmentById(source.getDepartment().getDepId()));
365         target.setIntranetLogin(source.getQuserIntranetLg());
366         target.setExtranetLogin(source.getQuserExtranetLg());
367         target.setEmail(source.getQuserEMail());
368         target.setPhone(source.getQuserPhone());
369         target.setAddress(source.getQuserAddress());
370         target.setOrganism(source.getQuserOrgan());
371         target.setAdminCenter(source.getQuserAdminCenter());
372         target.setSite(source.getQuserSite());
373         referentialDao.getStatusByCode(source.getStatus().getStatusCd());
374         target.setComment(source.getQuserCm());
375         target.setCreationDate(source.getQuserCreationDt());
376         target.setUpdateDate(source.getUpdateDt());
377         return target;
378     }
379 
380     /**
381      * <p>toPersonDTOCollection.</p>
382      *
383      * @param entities a {@link java.util.Collection} object.
384      */
385     @SuppressWarnings("unchecked")
386     private void toPersonDTOCollection(java.util.Collection<?> entities) {
387         if (entities != null) {
388             org.apache.commons.collections4.CollectionUtils.transform(entities, PERSON_DTO_TRANSFORMER);
389         }
390     }
391 
392     private final org.apache.commons.collections4.Transformer PERSON_DTO_TRANSFORMER
393             = input -> {
394                 Object result = null;
395                 if (input instanceof Quser) {
396                     result = toPersonDTO((Quser) input);
397                 }
398                 return result;
399             };
400 
401     private PrivilegeDTO toPrivilegeDTO(Iterator<Object> source) {
402         PrivilegeDTO target = DaliBeanFactory.newPrivilegeDTO();
403 
404         target.setCode((String) source.next());
405         target.setName((String) source.next());
406         target.setDescription((String) source.next());
407 
408         // Override name
409         if (PrivilegeCode.fromValue(target.getCode()) == PrivilegeCode.LOCAL_ADMINISTRATOR) {
410             target.setName(t("quadrige3.security.authority.ROLE_LOCAL_ADMIN"));
411         }
412 
413         return target;
414     }
415 
416 }