1 package net.sumaris.core.dao.data;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
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
68
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
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
105 Operation parent = get(Operation.class, operationId);
106
107
108 final Map<Integer, VesselPosition> sourcesToRemove = Beans.splitById(Beans.getList(parent.getPositions()));
109
110
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
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
143 checkUpdateDateForUpdate(source, entity);
144
145
146 lockForUpdate(entity);
147 }
148
149
150 vesselPositionVOToEntity(source, entity, true);
151
152
153 Timestamp newUpdateDate = getDatabaseCurrentTimestamp();
154 entity.setUpdateDate(newUpdateDate);
155
156
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
167
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
190 DepartmentVO recorderDepartment = referentialDao.toTypedVO(source.getRecorderDepartment(), DepartmentVO.class).orElse(null);
191 target.setRecorderDepartment(recorderDepartment);
192
193 return target;
194 }
195
196
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
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
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
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 }