View Javadoc
1   package net.sumaris.core.dao.data;
2   
3   /*-
4    * #%L
5    * SUMARiS:: Core
6    * %%
7    * Copyright (C) 2018 SUMARiS Consortium
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/gpl-3.0.html>.
22   * #L%
23   */
24  
25  import com.google.common.base.Preconditions;
26  import net.sumaris.core.dao.referential.ReferentialDao;
27  import net.sumaris.core.dao.technical.SortDirection;
28  import net.sumaris.core.model.administration.user.Department;
29  import net.sumaris.core.model.data.Operation;
30  import net.sumaris.core.model.data.VesselPosition;
31  import net.sumaris.core.model.referential.QualityFlag;
32  import net.sumaris.core.util.Beans;
33  import net.sumaris.core.vo.administration.user.DepartmentVO;
34  import net.sumaris.core.vo.data.VesselPositionVO;
35  import org.apache.commons.collections4.MapUtils;
36  import org.apache.commons.lang3.StringUtils;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  import org.springframework.beans.factory.annotation.Autowired;
40  import org.springframework.stereotype.Repository;
41  
42  import javax.persistence.EntityManager;
43  import javax.persistence.TypedQuery;
44  import javax.persistence.criteria.*;
45  import java.sql.Timestamp;
46  import java.util.List;
47  import java.util.Map;
48  import java.util.Objects;
49  import java.util.stream.Collectors;
50  
51  @Repository("vesselPositionDao")
52  public class VesselPositionDaoImpl extends BaseDataDaoImpl implements VesselPositionDao {
53  
54      /** Logger. */
55      private static final Logger log =
56              LoggerFactory.getLogger(VesselPositionDaoImpl.class);
57  
58      @Autowired
59      private ReferentialDao referentialDao;
60  
61      @Override
62      @SuppressWarnings("unchecked")
63      public List<VesselPositionVO> getAllByOperationId(int operationId, int offset, int size, String sortAttribute, SortDirection sortDirection) {
64          Preconditions.checkArgument(offset >= 0);
65          Preconditions.checkArgument(size > 0);
66  
67          // Fetch locations
68          //getEntityManager().enableFetchProfile("with-location");
69  
70          CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
71          CriteriaQuery<VesselPosition> query = builder.createQuery(VesselPosition.class);
72          Root<VesselPosition> root = query.from(VesselPosition.class);
73  
74          ParameterExpression<Integer> operationIdParam = builder.parameter(Integer.class);
75  
76          query.select(root)
77              .where(builder.equal(root.get(VesselPosition.Fields.OPERATION).get(Operation.Fields.ID), operationIdParam));
78  
79          // Add sorting
80          if (StringUtils.isNotBlank(sortAttribute)) {
81              Expression<?> sortExpression = root.get(sortAttribute);
82              query.orderBy(SortDirection.DESC.equals(sortDirection) ?
83                      builder.desc(sortExpression) :
84                      builder.asc(sortExpression)
85              );
86          }
87  
88          TypedQuery<VesselPosition> q = getEntityManager().createQuery(query)
89                  .setParameter(operationIdParam, operationId)
90                  .setFirstResult(offset)
91                  .setMaxResults(size);
92          return toVesselPositionVOs(q.getResultList());
93      }
94  
95      @Override
96      public VesselPositionVO get(int id) {
97          VesselPosition entity = getEntityManager().find(VesselPosition.class, id);
98          return toMeasurementVO(entity);
99      }
100 
101     @Override
102     public List<VesselPositionVO> saveByOperationId(int operationId, List<VesselPositionVO> sources) {
103 
104         // Load parent entity
105         Operation parent = get(Operation.class, operationId);
106 
107         // Remember existing entities
108         final Map<Integer, VesselPosition> sourcesToRemove = Beans.splitById(Beans.getList(parent.getPositions()));
109 
110         // Save each gears
111         List<VesselPositionVO> result = sources.stream().map(gear -> {
112             gear.setOperationId(operationId);
113             if (gear.getId() != null) {
114                 sourcesToRemove.remove(gear.getId());
115             }
116             return save(gear);
117         }).collect(Collectors.toList());
118 
119         // Remove unused entities
120         if (MapUtils.isNotEmpty(sourcesToRemove)) {
121             sourcesToRemove.values().forEach(this::delete);
122         }
123 
124         return result;
125     }
126 
127     @Override
128     public VesselPositionVO/../../../net/sumaris/core/vo/data/VesselPositionVO.html#VesselPositionVO">VesselPositionVO save(VesselPositionVO source) {
129         Preconditions.checkNotNull(source);
130 
131         EntityManager entityManager = getEntityManager();
132         VesselPosition entity = null;
133         if (source.getId() != null) {
134             entity = entityManager.find(VesselPosition.class, source.getId());
135         }
136         boolean isNew = (entity == null);
137         if (isNew) {
138             entity = new VesselPosition();
139         }
140 
141         if (!isNew) {
142             // Check update date
143             checkUpdateDateForUpdate(source, entity);
144 
145             // Lock entityName
146             lockForUpdate(entity);
147         }
148 
149         // VO -> Entity
150         vesselPositionVOToEntity(source, entity, true);
151 
152         // Update update_dt
153         Timestamp newUpdateDate = getDatabaseCurrentTimestamp();
154         entity.setUpdateDate(newUpdateDate);
155 
156         // Save entityName
157         if (isNew) {
158             entityManager.persist(entity);
159             source.setId(entity.getId());
160         } else {
161             entityManager.merge(entity);
162         }
163 
164         source.setUpdateDate(newUpdateDate);
165 
166         //session.flush();
167         //session.clear();
168 
169         return source;
170     }
171 
172     @Override
173     public void delete(int id) {
174 
175         log.debug(String.format("Deleting vesselPosition {id=%s}...", id));
176         delete(VesselPosition.class, id);
177     }
178 
179     @Override
180     public VesselPositionVO toMeasurementVO(VesselPosition source) {
181         if (source == null) return null;
182 
183         VesselPositionVOtionVO.html#VesselPositionVO">VesselPositionVO target = new VesselPositionVO();
184 
185         Beans.copyProperties(source, target);
186 
187         target.setQualityFlagId(source.getQualityFlag().getId());
188 
189         // Recorder department
190         DepartmentVO recorderDepartment = referentialDao.toTypedVO(source.getRecorderDepartment(), DepartmentVO.class).orElse(null);
191         target.setRecorderDepartment(recorderDepartment);
192 
193         return target;
194     }
195 
196     /* -- protected methods -- */
197 
198     protected List<VesselPositionVO> toVesselPositionVOs(List<VesselPosition> source) {
199         return source.stream()
200                 .map(this::toMeasurementVO)
201                 .filter(Objects::nonNull)
202                 .collect(Collectors.toList());
203     }
204 
205     protected void vesselPositionVOToEntity(VesselPositionVO source, VesselPosition target, boolean copyIfNull) {
206 
207         Beans.copyProperties(source, target);
208 
209         // Operation
210         Integer operationId = source.getOperationId() != null ? source.getOperationId() : (source.getOperation() != null ? source.getOperation().getId() : null);
211         if (copyIfNull || (operationId != null)) {
212             if (operationId == null) {
213                 target.setOperation(null);
214             }
215             else {
216                 target.setOperation(load(Operation.class, operationId));
217             }
218         }
219 
220         // Recorder department
221         if (copyIfNull || source.getRecorderDepartment() != null) {
222             if (source.getRecorderDepartment() == null || source.getRecorderDepartment().getId() == null) {
223                 target.setRecorderDepartment(null);
224             }
225             else {
226                 target.setRecorderDepartment(load(Department.class, source.getRecorderDepartment().getId()));
227             }
228         }
229 
230         // Quality flag
231         if (copyIfNull || source.getQualityFlagId() != null) {
232             if (source.getQualityFlagId() == null) {
233                 target.setQualityFlag(load(QualityFlag.class, config.getDefaultQualityFlagId()));
234             }
235             else {
236                 target.setQualityFlag(load(QualityFlag.class, source.getQualityFlagId()));
237             }
238         }
239 
240     }
241 }