View Javadoc
1   package net.sumaris.core.dao.technical;
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 com.google.common.collect.ImmutableList;
27  import com.google.common.collect.Lists;
28  import com.google.common.collect.Maps;
29  import net.sumaris.core.dao.technical.hibernate.HibernateDaoSupport;
30  import net.sumaris.core.model.referential.Status;
31  import net.sumaris.core.model.referential.StatusEnum;
32  import net.sumaris.core.model.technical.configuration.Software;
33  import net.sumaris.core.model.technical.configuration.SoftwareProperty;
34  import net.sumaris.core.util.Beans;
35  import net.sumaris.core.vo.technical.SoftwareVO;
36  import org.apache.commons.collections4.MapUtils;
37  import org.springframework.beans.factory.annotation.Autowired;
38  import org.springframework.stereotype.Repository;
39  
40  import javax.persistence.EntityManager;
41  import java.sql.Timestamp;
42  import java.util.List;
43  import java.util.Map;
44  import java.util.Objects;
45  
46  @Repository("softwareDao")
47  public class SoftwareDaoImpl extends HibernateDaoSupport implements SoftwareDao{
48  
49      @Autowired
50      private SoftwareRepository repository;
51  
52      public SoftwareVO get(String label) {
53          return toVO(repository.getOneByLabel(label));
54      }
55  
56      public SoftwareVO"../../../../../net/sumaris/core/vo/technical/SoftwareVO.html#SoftwareVO">SoftwareVO save(SoftwareVO source)  {
57  
58          EntityManager entityManager = getEntityManager();
59          Software entity = null;
60          if (source.getId() != null) {
61              entity = get(Software.class, source.getId());
62          }
63          boolean isNew = (entity == null);
64          if (isNew) {
65              entity = new Software();
66          }
67  
68          else {
69              // Check update date
70              checkUpdateDateForUpdate(source, entity);
71  
72              // Lock entityName
73              lockForUpdate(entity);
74          }
75  
76          // VO -> Entity
77          softwareVOToEntity(source, entity, false);
78  
79          // Update update_dt
80          Timestamp newUpdateDate = getDatabaseCurrentTimestamp();
81          entity.setUpdateDate(newUpdateDate);
82  
83          // Save entityName
84          if (isNew) {
85              // Force creation date
86              entity.setCreationDate(newUpdateDate);
87              source.setCreationDate(newUpdateDate);
88  
89              entityManager.persist(entity);
90              source.setId(entity.getId());
91          }
92  
93          source.setUpdateDate(newUpdateDate);
94  
95          // Save properties
96          saveProperties(source.getProperties(), entity, newUpdateDate);
97  
98          // Final merge
99          entityManager.merge(entity);
100 
101         return source;
102     }
103 
104     /* -- protected methods -- */
105 
106     protected void softwareVOToEntity(SoftwareVO source, Software target, boolean copyIfNull) {
107 
108         Beans.copyProperties(source, target);
109 
110         // status
111         if (copyIfNull || source.getStatusId() != null) {
112             if (source.getStatusId() == null) {
113                 target.setStatus(null);
114             }
115             else {
116                 target.setStatus(load(Status.class, source.getStatusId()));
117             }
118         }
119     }
120 
121     protected void saveProperties(Map<String, String> source, Software parent, Timestamp updateDate) {
122         final EntityManager em = getEntityManager();
123         if (MapUtils.isEmpty(source)) {
124             if (parent.getProperties() != null) {
125                 List<SoftwareProperty> toRemove = ImmutableList.copyOf(parent.getProperties());
126                 parent.getProperties().clear();
127                 toRemove.forEach(em::remove);
128             }
129         }
130         else {
131             Map<String, SoftwareProperty> existingProperties = Beans.splitByProperty(
132                     Beans.getList(parent.getProperties()),
133                     SoftwareProperty.Fields.LABEL);
134             final Status enableStatus = em.getReference(Status.class, StatusEnum.ENABLE.getId());
135             if (parent.getProperties() == null) {
136                 parent.setProperties(Lists.newArrayList());
137             }
138             final List<SoftwareProperty> targetProperties = parent.getProperties();
139 
140             // Transform each entry into SoftwareProperty
141             source.entrySet().stream()
142                     .filter(e -> Objects.nonNull(e.getKey())
143                             && Objects.nonNull(e.getValue())
144                     )
145                     .map(e -> {
146                         SoftwareProperty prop = existingProperties.remove(e.getKey());
147                         boolean isNew = (prop == null);
148                         if (isNew) {
149                             prop = new SoftwareProperty();
150                             prop.setLabel(e.getKey());
151                             prop.setSoftware(parent);
152                             prop.setCreationDate(updateDate);
153                         }
154                         prop.setName(e.getValue());
155                         prop.setStatus(enableStatus);
156                         prop.setUpdateDate(updateDate);
157                         if (isNew) {
158                             em.persist(prop);
159                         }
160                         else {
161                             em.merge(prop);
162                         }
163                         return prop;
164                     })
165                     .forEach(targetProperties::add);
166 
167             // Remove old properties
168             if (MapUtils.isNotEmpty(existingProperties)) {
169                 parent.getProperties().removeAll(existingProperties.values());
170                 existingProperties.values().forEach(em::remove);
171             }
172 
173         }
174     }
175 
176     protected SoftwareVO toVO(Software source) {
177         if (source == null) return null;
178 
179         SoftwareVO/SoftwareVO.html#SoftwareVO">SoftwareVO target = new SoftwareVO();
180 
181         Beans.copyProperties(source, target);
182 
183         // Status
184         target.setStatusId(source.getStatus().getId());
185 
186         // properties
187         Map<String, String> properties = Maps.newHashMap();
188         Beans.getStream(source.getProperties())
189                 .filter(prop -> Objects.nonNull(prop)
190                         && Objects.nonNull(prop.getLabel())
191                         && Objects.nonNull(prop.getName())
192                 )
193                 .forEach(prop -> {
194                     if (properties.containsKey(prop.getLabel())) {
195                         logger.warn(String.format("Duplicate software property with label {%s}. Overriding existing value with {%s}", prop.getLabel(), prop.getName()));
196                     }
197                     properties.put(prop.getLabel(), prop.getName());
198                 });
199         target.setProperties(properties);
200 
201 
202         return target;
203     }
204 
205     protected Software toEntity(SoftwareVO source) {
206         Preconditions.checkNotNull(source);
207         Preconditions.checkNotNull(source.getLabel());
208 
209         Software target;
210         if (source.getId() != null) {
211             target = repository.getOneByLabel(source.getLabel());
212         }
213         else {
214             target = new Software();
215         }
216 
217         softwareVOToEntity(source, target, true);
218 
219         return target;
220     }
221 
222 }