View Javadoc
1   package fr.ifremer.quadrige3.core.dao.administration.user;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: Quadrige3 Client Core
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 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.base.Joiner;
27  import com.google.common.collect.Lists;
28  import com.google.common.collect.Maps;
29  import fr.ifremer.quadrige3.core.dao.referential.StatusCode;
30  import fr.ifremer.quadrige3.core.dao.technical.Assert;
31  import fr.ifremer.quadrige3.core.dao.technical.jdbc.OptionalDataSourceJdbcDaoSupport;
32  import fr.ifremer.quadrige3.core.exception.QuadrigeTechnicalException;
33  import fr.ifremer.quadrige3.core.vo.administration.program.ProgramVO;
34  import fr.ifremer.quadrige3.core.vo.administration.user.LightQuserVO;
35  import fr.ifremer.quadrige3.core.vo.administration.user.PrivilegeVO;
36  import fr.ifremer.quadrige3.core.vo.administration.user.QuserVO;
37  import org.apache.commons.io.IOUtils;
38  import org.apache.commons.lang3.StringUtils;
39  import org.springframework.beans.factory.InitializingBean;
40  import org.springframework.beans.factory.annotation.Autowired;
41  import org.springframework.context.annotation.Lazy;
42  import org.springframework.stereotype.Repository;
43  
44  import javax.annotation.Resource;
45  import javax.sql.DataSource;
46  import java.io.IOException;
47  import java.io.InputStream;
48  import java.math.BigDecimal;
49  import java.sql.ResultSet;
50  import java.sql.SQLException;
51  import java.util.List;
52  import java.util.Map;
53  import java.util.Properties;
54  
55  /**
56   * <p>
57   * QuserJdbcDaoImpl class.
58   * </p>
59   * 
60   * @see fr.ifremer.quadrige3.core.dao.administration.user.Quser
61   */
62  @Repository("quserJdbcDao")
63  @Lazy
64  public class QuserJdbcDaoImpl
65  		extends OptionalDataSourceJdbcDaoSupport
66  		implements QuserJdbcDao, InitializingBean {
67  
68  	private final static String QUERIES_FILE_PATH = "queries.jdbc.xml";
69  
70  	@Resource(name = "queriesJdbcProperties")
71  	private Properties queriesJdbcProperties;
72  
73  	protected Properties connectionProperties;
74  
75  	/**
76  	 * Constructor used by Spring
77  	 * 
78  	 * @param dataSource
79  	 *            a {@link javax.sql.DataSource} object.
80  	 */
81  	@Autowired
82  	public QuserJdbcDaoImpl(DataSource dataSource) {
83  		super(dataSource);
84  	}
85  
86  	/**
87  	 * Constructor without Spring (e.g. for synchro)
88  	 */
89  	public QuserJdbcDaoImpl() {
90  		this((Properties) null/* use default connection properties */);
91  	}
92  
93  	/**
94  	 * Constructor without Spring (e.g. for synchro)
95  	 * 
96  	 * @param connectionProperties
97  	 *            a {@link java.util.Properties} object.
98  	 */
99  	public QuserJdbcDaoImpl(Properties connectionProperties) {
100 		super();
101 		this.connectionProperties = connectionProperties;
102 
103 		// Load properties
104 		Properties properties = new Properties();
105 		InputStream is = null;
106 		try {
107 			is = getClass().getClassLoader().getResourceAsStream(QUERIES_FILE_PATH);
108 			properties.loadFromXML(is);
109 
110 			this.queriesJdbcProperties = properties;
111 		} catch (IOException e) {
112 			throw new QuadrigeTechnicalException(
113 					String.format("Unable to read file [%s] from classpath", QUERIES_FILE_PATH),
114 					e);
115 		} finally {
116 			IOUtils.closeQuietly(is);
117 		}
118 
119 		// Check all queries
120 		checkAllQueriesExists();
121 	}
122 
123 	/** {@inheritDoc} */
124 	@Override
125 	public void afterPropertiesSet() {
126 		// Check queries exists on queries file
127 		checkAllQueriesExists();
128 	}
129 
130 	/** {@inheritDoc} */
131 	@Override
132 	public Integer getUserIdByUsername(String username) {
133 		return getUserIdByUsername(connectionProperties, username);
134 	}
135 
136 	/** {@inheritDoc} */
137 	@Override
138 	public Integer getUserIdByUsername(Properties connectionProperties, String username) {
139 		// Find the user, by id
140 		String sql = queriesJdbcProperties.getProperty("quserIdByLoginAndStatus");
141 
142 		Map<String, Object> paramMap = Maps.newHashMap();
143 		paramMap.put("username", username);
144 		paramMap.put("statusCd", StatusCode.ENABLE.getValue());
145 
146 		return query(connectionProperties, sql, paramMap, rs -> {
147             Object value = rs.getObject(1);
148             if (value == null) {
149                 return null;
150             }
151 
152             // Oracle DBMS return a BigDecimal from NUMBER(10) columns
153             if (value instanceof BigDecimal) {
154                 return ((BigDecimal) value).intValue();
155             }
156 
157             // for all other java types: convert into Integer
158             return Integer.parseInt(value.toString());
159         });
160 	}
161 
162 	/** {@inheritDoc} */
163 	@Override
164 	public LightQuserVO getLightUserById(int personId) {
165 		return getLightUserById(connectionProperties, personId);
166 	}
167 
168 	/** {@inheritDoc} */
169 	@Override
170 	public LightQuserVO getLightUserById(Properties connectionProperties, int quserId) {
171 		// Find the user, by id
172 		String sql = queriesJdbcProperties.getProperty("lightQuserById");
173 
174 		Map<String, Object> paramMap = Maps.newHashMap();
175 		paramMap.put("quserId", quserId);
176 
177 		return query(connectionProperties, sql, paramMap, this::toLightQuserVO);
178 	}
179 
180 	/** {@inheritDoc} */
181 	@Override
182 	public List<LightQuserVO> getUsersByIds(List<Integer> ids) {
183 		return getUsersByIds(connectionProperties, ids);
184 	}
185 
186 	/** {@inheritDoc} */
187 	@Override
188 	public List<LightQuserVO> getUsersByIds(Properties connectionProperties, List<Integer> ids) {
189 		// Find users, by ids
190 		String sql = queriesJdbcProperties.getProperty("lightQusersByIds");
191 		sql = sql.replace(":ids", Joiner.on(",").skipNulls().join(ids));
192 
193 		Map<String, Object> paramMap = Maps.newHashMap();
194 
195 		return query(connectionProperties, sql, paramMap, (rs, rowNum) -> toLightQuserVO(rs));
196 	}
197 
198 	/** {@inheritDoc} */
199 	@Override
200 	public QuserVO getUserById(int userId) {
201 		return getUserById(connectionProperties, userId);
202 	}
203 
204 	/** {@inheritDoc} */
205 	@Override
206 	public QuserVO getUserById(Properties connectionProperties, int quserId) {
207 		// Find the user, by id
208 		String sql = queriesJdbcProperties.getProperty("quserById");
209 
210 		Map<String, Object> paramMap = Maps.newHashMap();
211 		paramMap.put("quserId", quserId);
212 
213 		return query(connectionProperties, sql, paramMap, this::toQuserVO);
214 	}
215 
216 	/** {@inheritDoc} */
217 	@Override
218 	public List<PrivilegeVO> getPrivilegesByUserId(int userId) {
219 		return getPrivilegesByUserId(connectionProperties, userId);
220 	}
221 
222 	/** {@inheritDoc} */
223 	@Override
224 	public List<PrivilegeVO> getPrivilegesByUserId(Properties connectionProperties, int userId) {
225 		// Find the user, by id
226 		String sql = queriesJdbcProperties.getProperty("privilegesByQuserId");
227 
228 		Map<String, Object> paramMap = Maps.newHashMap();
229 		paramMap.put("quserId", userId);
230 
231 		final List<PrivilegeVO> result = Lists.newArrayList();
232 
233 		// Execute the query, and fill the result list
234 		query(connectionProperties, sql, paramMap, source -> {
235             PrivilegeVO target = toPrivilegeVO(source);
236             result.add(target);
237         });
238 
239 		return result;
240 	}
241 
242 	/* -- Internal methods -- */
243 
244 	/**
245 	 * <p>
246 	 * toLightQuserVO.
247 	 * </p>
248 	 * 
249 	 * @param source
250 	 *            a {@link java.sql.ResultSet} object.
251 	 * @return a {@link fr.ifremer.quadrige3.core.vo.administration.user.LightQuserVO} object.
252 	 * @throws java.sql.SQLException
253 	 *             if any.
254 	 */
255 	protected LightQuserVO toLightQuserVO(ResultSet source) throws SQLException {
256 		int row = 0;
257 		return new LightQuserVO(
258 				safeGetInteger(source, ++row),
259 				source.getString(++row),
260 				source.getString(++row));
261 	}
262 
263 	/**
264 	 * <p>
265 	 * toQuserVO.
266 	 * </p>
267 	 * 
268 	 * @param source
269 	 *            a {@link java.sql.ResultSet} object.
270 	 * @return a {@link fr.ifremer.quadrige3.core.vo.administration.user.QuserVO} object.
271 	 * @throws java.sql.SQLException
272 	 *             if any.
273 	 */
274 	protected QuserVO toQuserVO(ResultSet source) throws SQLException {
275 		QuserVO target = new QuserVO();
276 
277 		int row = 0;
278 		target.setQuserId(safeGetInteger(source, ++row));
279 		target.setQuserLastNm(source.getString(++row));
280 		target.setQuserFirstNm(source.getString(++row));
281 		target.setQuserAddress(source.getString(++row));
282 		target.setQuserCreationDt(source.getDate(++row));
283 		target.setUpdateDt(source.getTimestamp(++row));
284 		target.setStatusCd(source.getString(++row));
285 		target.setDepId(safeGetInteger(source, ++row));
286 		target.setQuserIntranetLg(source.getString(++row));
287 		target.setQuserExtranetLg(source.getString(++row));
288 		target.setQuserEMail(source.getString(++row));
289 		target.setQuserPhone(source.getString(++row));
290 		target.setQuserOrgan(source.getString(++row));
291 		target.setQuserAdminCenter(source.getString(++row));
292 		target.setQuserSite(source.getString(++row));
293 		target.setQuserLdapPresent(source.getString(++row));
294 
295 		return target;
296 	}
297 
298 	/**
299 	 * <p>
300 	 * toProgramVO.
301 	 * </p>
302 	 * 
303 	 * @param source
304 	 *            a {@link java.sql.ResultSet} object.
305 	 * @return a {@link fr.ifremer.quadrige3.core.vo.administration.program.ProgramVO} object.
306 	 * @throws java.sql.SQLException
307 	 *             if any.
308 	 */
309 	protected ProgramVO toProgramVO(ResultSet source) throws SQLException {
310 		ProgramVO target = new ProgramVO();
311 
312 		int row = 0;
313 		target.setProgCd(source.getString(++row));
314 		target.setProgNm(source.getString(++row));
315 
316 		return target;
317 	}
318 
319 	/**
320 	 * <p>
321 	 * toPrivilegeVO.
322 	 * </p>
323 	 * 
324 	 * @param source
325 	 *            a {@link java.sql.ResultSet} object.
326 	 * @return a {@link fr.ifremer.quadrige3.core.vo.administration.user.PrivilegeVO} object.
327 	 * @throws java.sql.SQLException
328 	 *             if any.
329 	 */
330 	protected PrivilegeVO toPrivilegeVO(ResultSet source) throws SQLException {
331 		PrivilegeVO target = new PrivilegeVO();
332 
333 		int row = 0;
334 		target.setPrivilegeCd(source.getString(++row));
335 		target.setPrivilegeNm(source.getString(++row));
336 		target.setPrivilegeDc(source.getString(++row));
337 		target.setStatusCd(source.getString(++row));
338 		target.setUpdateDt(source.getTimestamp(++row));
339 
340 		return target;
341 	}
342 
343 	/**
344 	 * Check queries exists on queries file
345 	 */
346 	protected void checkAllQueriesExists() {
347 		Assert.notNull(queriesJdbcProperties);
348 
349 		checkQueryExists("quserIdByLoginAndStatus");
350 		checkQueryExists("lightQuserById");
351 		checkQueryExists("quserById");
352 		checkQueryExists("privilegesByQuserId");
353 	}
354 
355 	/**
356 	 * Check if a query exists on the queries properties file
357 	 * 
358 	 * @param queryName
359 	 *            a {@link java.lang.String} object.
360 	 */
361 	protected void checkQueryExists(String queryName) {
362 		if (StringUtils.isBlank(queriesJdbcProperties.getProperty(queryName))) {
363 			throw new QuadrigeTechnicalException(String.format("Property with name [%s] not exists on JDBC queries file", queryName));
364 		}
365 	}
366 }