Removed MDC from four modules
[sdc.git] / openecomp-be / lib / openecomp-sdc-versioning-lib / openecomp-sdc-versioning-core / src / main / java / org / openecomp / sdc / versioning / impl / VersioningManagerImpl.java
1 /*
2  * Copyright © 2016-2017 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.versioning.impl;
18
19 import org.openecomp.sdc.common.errors.CoreException;
20 import org.openecomp.sdc.common.errors.ErrorCode;
21 import org.openecomp.sdc.logging.api.Logger;
22 import org.openecomp.sdc.logging.api.LoggerFactory;
23 import org.openecomp.sdc.versioning.ItemManager;
24 import org.openecomp.sdc.versioning.VersionCalculator;
25 import org.openecomp.sdc.versioning.VersioningManager;
26 import org.openecomp.sdc.versioning.dao.VersionDao;
27 import org.openecomp.sdc.versioning.dao.VersionInfoDao;
28 import org.openecomp.sdc.versioning.dao.VersionInfoDeletedDao;
29 import org.openecomp.sdc.versioning.dao.VersionableEntityDaoFactory;
30 import org.openecomp.sdc.versioning.dao.types.Revision;
31 import org.openecomp.sdc.versioning.dao.types.SynchronizationState;
32 import org.openecomp.sdc.versioning.dao.types.UserCandidateVersion;
33 import org.openecomp.sdc.versioning.dao.types.Version;
34 import org.openecomp.sdc.versioning.dao.types.VersionInfoDeletedEntity;
35 import org.openecomp.sdc.versioning.dao.types.VersionInfoEntity;
36 import org.openecomp.sdc.versioning.dao.types.VersionStatus;
37 import org.openecomp.sdc.versioning.errors.CheckinOnEntityLockedByOtherErrorBuilder;
38 import org.openecomp.sdc.versioning.errors.CheckinOnUnlockedEntityErrorBuilder;
39 import org.openecomp.sdc.versioning.errors.CheckoutOnLockedEntityErrorBuilder;
40 import org.openecomp.sdc.versioning.errors.DeleteOnLockedEntityErrorBuilder;
41 import org.openecomp.sdc.versioning.errors.EditOnEntityLockedByOtherErrorBuilder;
42 import org.openecomp.sdc.versioning.errors.EditOnUnlockedEntityErrorBuilder;
43 import org.openecomp.sdc.versioning.errors.EntityAlreadyExistErrorBuilder;
44 import org.openecomp.sdc.versioning.errors.EntityAlreadyFinalizedErrorBuilder;
45 import org.openecomp.sdc.versioning.errors.EntityNotExistErrorBuilder;
46 import org.openecomp.sdc.versioning.errors.SubmitLockedEntityNotAllowedErrorBuilder;
47 import org.openecomp.sdc.versioning.errors.UndoCheckoutOnEntityLockedByOtherErrorBuilder;
48 import org.openecomp.sdc.versioning.errors.UndoCheckoutOnUnlockedEntityErrorBuilder;
49 import org.openecomp.sdc.versioning.types.VersionCreationMethod;
50 import org.openecomp.sdc.versioning.types.VersionInfo;
51 import org.openecomp.sdc.versioning.types.VersionableEntityAction;
52 import org.openecomp.sdc.versioning.types.VersionableEntityMetadata;
53
54 import java.util.Collection;
55 import java.util.HashMap;
56 import java.util.HashSet;
57 import java.util.List;
58 import java.util.Map;
59 import java.util.Set;
60 import java.util.stream.Collectors;
61
62 public class VersioningManagerImpl implements VersioningManager {
63   private static final Logger LOGGER = LoggerFactory.getLogger(VersioningManagerImpl.class);
64   private static final Version INITIAL_ACTIVE_VERSION = new Version(0, 0);
65   private static final Map<String, Set<VersionableEntityMetadata>> VERSIONABLE_ENTITIES =
66       new HashMap<>();
67
68   private final VersionInfoDao versionInfoDao;
69   private final VersionInfoDeletedDao versionInfoDeletedDao;
70   private VersionDao versionDao;
71   private VersionCalculator versionCalculator;
72   private ItemManager itemManager;
73
74   public VersioningManagerImpl(VersionInfoDao versionInfoDao,
75                                VersionInfoDeletedDao versionInfoDeletedDao,
76                                VersionDao versionDao,
77                                VersionCalculator versionCalculator,
78                                ItemManager itemManager) {
79     this.versionInfoDao = versionInfoDao;
80     this.versionInfoDeletedDao = versionInfoDeletedDao;
81     this.versionDao = versionDao;
82     this.versionCalculator = versionCalculator;
83     this.itemManager = itemManager;
84   }
85
86   private static VersionInfo getVersionInfo(VersionInfoEntity versionInfoEntity, String user,
87                                             VersionableEntityAction action) {
88     return getVersionInfo(versionInfoEntity.getEntityId(),
89         versionInfoEntity.getEntityType(),
90         versionInfoEntity.getActiveVersion(),
91         versionInfoEntity.getCandidate(),
92         versionInfoEntity.getStatus(),
93         versionInfoEntity.getLatestFinalVersion(),
94         versionInfoEntity.getViewableVersions(),
95         action,
96         user);
97   }
98
99   private static VersionInfo getVersionInfo(VersionInfoDeletedEntity versionInfoEntity, String user,
100                                             VersionableEntityAction action) {
101     return getVersionInfo(versionInfoEntity.getEntityId(),
102         versionInfoEntity.getEntityType(),
103         versionInfoEntity.getActiveVersion(),
104         versionInfoEntity.getCandidate(),
105         versionInfoEntity.getStatus(),
106         versionInfoEntity.getLatestFinalVersion(),
107         versionInfoEntity.getViewableVersions(),
108         action,
109         user);
110   }
111
112   private static VersionInfo getVersionInfo(String entityId, String entityType, Version activeVer,
113                                             UserCandidateVersion candidate, VersionStatus status,
114                                             Version latestFinalVersion,
115                                             Set<Version> viewableVersions,
116                                             VersionableEntityAction action, String user) {
117     Version activeVersion;
118
119     if (action == VersionableEntityAction.Write) {
120       if (candidate != null) {
121         if (user.equals(candidate.getUser())) {
122           activeVersion = candidate.getVersion();
123         } else {
124           throw new CoreException(
125               new EditOnEntityLockedByOtherErrorBuilder(entityType, entityId, candidate.getUser())
126                   .build());
127         }
128       } else {
129         throw new CoreException(new EditOnUnlockedEntityErrorBuilder(entityType, entityId).build());
130       }
131     } else {
132       if (candidate != null && user.equals(candidate.getUser())) {
133         activeVersion = candidate.getVersion();
134       } else {
135         activeVersion = activeVer;
136       }
137     }
138
139     VersionInfo versionInfo = new VersionInfo();
140     versionInfo.setStatus(status);
141     activeVersion.setStatus(status);
142     if (latestFinalVersion != null) {
143       latestFinalVersion.setStatus(status);
144     }
145     if (viewableVersions != null) {
146       viewableVersions.forEach(version -> version.setStatus(status));
147     }
148     versionInfo.setActiveVersion(activeVersion);
149     versionInfo.setLatestFinalVersion(latestFinalVersion);
150     versionInfo.setViewableVersions(toSortedList(viewableVersions));
151     versionInfo.setFinalVersions(getFinalVersions(viewableVersions));
152     if (candidate != null) {
153       candidate.getVersion().setStatus(status);
154       versionInfo.setLockingUser(candidate.getUser());
155       if (user.equals(candidate.getUser())) {
156         versionInfo.getViewableVersions().add(candidate.getVersion());
157       }
158     }
159     return versionInfo;
160   }
161
162   private static List<Version> toSortedList(
163       Set<Version> versions) { // changing the Set to List in DB will require migration...
164     return versions.stream().sorted((o1, o2) -> o1.getMajor() > o2.getMajor() ? 1
165         : o1.getMajor() == o2.getMajor() ? (Integer.compare(o1.getMinor(), o2.getMinor())) : -1)
166             .collect(Collectors.toList());
167   }
168
169   private static List<Version> getFinalVersions(Set<Version> versions) {
170     return versions.stream().filter(Version::isFinal).collect(Collectors.toList());
171   }
172
173   @Override
174   public void register(String entityType, VersionableEntityMetadata entityMetadata) {
175     Set<VersionableEntityMetadata> entitiesMetadata =
176         VERSIONABLE_ENTITIES.computeIfAbsent(entityType, k -> new HashSet<>());
177     entitiesMetadata.add(entityMetadata);
178   }
179
180   @Override
181   public Version create(String entityType, String entityId, String user) {
182     VersionInfoEntity
183         versionInfoEntity = versionInfoDao.get(new VersionInfoEntity(entityType, entityId));
184     if (versionInfoEntity != null) {
185       throw new CoreException(new EntityAlreadyExistErrorBuilder(entityType, entityId).build());
186     }
187
188     versionInfoEntity = new VersionInfoEntity(entityType, entityId);
189     versionInfoEntity.setActiveVersion(INITIAL_ACTIVE_VERSION);
190     markAsCheckedOut(versionInfoEntity, user);
191     versionInfoDao.create(versionInfoEntity);
192
193     return versionInfoEntity.getCandidate().getVersion();
194   }
195
196   @Override
197   public void delete(String entityType, String entityId, String user) {
198     VersionInfoEntity versionInfoEntity =
199         versionInfoDao.get(new VersionInfoEntity(entityType, entityId));
200     if (versionInfoEntity == null) {
201       throw new CoreException(new EntityNotExistErrorBuilder(entityType, entityId).build());
202     }
203
204     if (versionInfoEntity.getStatus() == VersionStatus.Locked) {
205       throw new CoreException(new DeleteOnLockedEntityErrorBuilder(entityType, entityId,
206               versionInfoEntity.getCandidate().getUser()).build());
207     }
208
209     doDelete(versionInfoEntity);
210   }
211
212   @Override
213   public void undoDelete(String entityType, String entityId, String user) {
214     VersionInfoDeletedEntity versionInfoDeletedEntity =
215         versionInfoDeletedDao.get(new VersionInfoDeletedEntity(entityType, entityId));
216     if (versionInfoDeletedEntity == null) {
217       throw new CoreException(new EntityNotExistErrorBuilder(entityType, entityId).build());
218     }
219
220     doUndoDelete(versionInfoDeletedEntity);
221   }
222
223   @Override
224   public Version checkout(String entityType, String entityId, String user) {
225     VersionInfoEntity versionInfoEntity =
226         versionInfoDao.get(new VersionInfoEntity(entityType, entityId));
227     if (versionInfoEntity == null) {
228       throw new CoreException(new EntityNotExistErrorBuilder(entityType, entityId).build());
229     }
230
231     Version checkoutVersion = null;
232     switch (versionInfoEntity.getStatus()) {
233       case Locked:
234         throw new CoreException(new CheckoutOnLockedEntityErrorBuilder(entityType, entityId,
235             versionInfoEntity.getCandidate().getUser()).build());
236       case Certified:
237       case Draft:
238         checkoutVersion = doCheckout(versionInfoEntity, user);
239         break;
240       default:
241         //do nothing
242         break;
243     }
244
245     return checkoutVersion;
246   }
247
248   @Override
249   public Version undoCheckout(String entityType, String entityId, String user) {
250     VersionInfoEntity versionInfoEntity =
251         versionInfoDao.get(new VersionInfoEntity(entityType, entityId));
252     if (versionInfoEntity == null) {
253       throw new CoreException(new EntityNotExistErrorBuilder(entityType, entityId).build());
254     }
255
256     Version activeVersion = null;
257     switch (versionInfoEntity.getStatus()) {
258       case Locked:
259         if (!user.equals(versionInfoEntity.getCandidate().getUser())) {
260           throw new CoreException(
261               new UndoCheckoutOnEntityLockedByOtherErrorBuilder(entityType, entityId,
262                   versionInfoEntity.getCandidate().getUser()).build());
263         }
264         activeVersion = undoCheckout(versionInfoEntity);
265         break;
266       case Certified:
267       case Draft:
268         throw new CoreException(
269             new UndoCheckoutOnUnlockedEntityErrorBuilder(entityType, entityId).build());
270       default:
271         //do nothing
272         break;
273     }
274
275     return activeVersion;
276   }
277
278   private Version undoCheckout(VersionInfoEntity versionInfoEntity) {
279     deleteVersionFromEntity(versionInfoEntity.getEntityType(), versionInfoEntity.getEntityId(),
280         versionInfoEntity.getCandidate().getVersion(), versionInfoEntity.getActiveVersion());
281
282     versionInfoEntity
283         .setStatus(versionInfoEntity.getActiveVersion().isFinal() ? VersionStatus.Certified
284             : VersionStatus.Draft);
285     versionInfoEntity.setCandidate(null);
286     versionInfoDao.update(versionInfoEntity);
287     return versionInfoEntity.getActiveVersion();
288   }
289
290   @Override
291   public Version checkin(String entityType, String entityId, String user,
292                          String checkinDescription) {
293     VersionInfoEntity versionInfoEntity =
294         versionInfoDao.get(new VersionInfoEntity(entityType, entityId));
295     if (versionInfoEntity == null) {
296       throw new CoreException(new EntityNotExistErrorBuilder(entityType, entityId).build());
297     }
298
299     Version checkedInVersion = null;
300     switch (versionInfoEntity.getStatus()) {
301       case Draft:
302       case Certified:
303         throw new CoreException(
304             new CheckinOnUnlockedEntityErrorBuilder(entityType, entityId).build());
305       case Locked:
306         if (!user.equals(versionInfoEntity.getCandidate().getUser())) {
307           throw new CoreException(new CheckinOnEntityLockedByOtherErrorBuilder(entityType, entityId,
308               versionInfoEntity.getCandidate().getUser()).build());
309         }
310         checkedInVersion = doCheckin(versionInfoEntity);
311         break;
312       default:
313         //do nothing
314         break;
315     }
316
317     return checkedInVersion;
318   }
319
320   @Override
321   public Version submit(String entityType, String entityId, String user, String submitDescription) {
322     VersionInfoEntity versionInfoEntity =
323         versionInfoDao.get(new VersionInfoEntity(entityType, entityId));
324     if (versionInfoEntity == null) {
325       throw new CoreException(new EntityNotExistErrorBuilder(entityType, entityId).build());
326     }
327
328     Version submitVersion = null;
329     switch (versionInfoEntity.getStatus()) {
330       case Certified:
331         throw new CoreException(
332             new EntityAlreadyFinalizedErrorBuilder(entityType, entityId).build());
333       case Locked:
334         throw new CoreException(new SubmitLockedEntityNotAllowedErrorBuilder(entityType, entityId,
335             versionInfoEntity.getCandidate().getUser()).build());
336       case Draft:
337         submitVersion = doSubmit(versionInfoEntity);
338         break;
339       default:
340         //do nothing
341         break;
342     }
343
344     return submitVersion;
345   }
346
347   @Override
348   public VersionInfo getEntityVersionInfo(String entityType, String entityId, String user,
349                                           VersionableEntityAction action) {
350     VersionInfoEntity versionInfoEntity =
351         versionInfoDao.get(new VersionInfoEntity(entityType, entityId));
352     if (versionInfoEntity == null) {
353       throw new CoreException(new EntityNotExistErrorBuilder(entityType, entityId).build());
354     }
355     return getVersionInfo(versionInfoEntity, user, action);
356   }
357
358   @Override
359   public Map<String, VersionInfo> listEntitiesVersionInfo(String entityType, String user,
360                                                           VersionableEntityAction action) {
361     Collection<VersionInfoEntity> versionInfoEntities =
362         versionInfoDao.list(new VersionInfoEntity(entityType, null));
363     Map<String, VersionInfo> activeVersions = new HashMap<>();
364     for (VersionInfoEntity versionInfoEntity : versionInfoEntities) {
365       activeVersions
366           .put(versionInfoEntity.getEntityId(), getVersionInfo(versionInfoEntity, user, action));
367     }
368     return activeVersions;
369   }
370
371   @Override
372   public Map<String, VersionInfo> listDeletedEntitiesVersionInfo(String entityType, String user,
373                                                                  VersionableEntityAction action) {
374     Collection<VersionInfoDeletedEntity> versionInfoDeletedEntities =
375         versionInfoDeletedDao.list(new VersionInfoDeletedEntity(entityType, null));
376     Map<String, VersionInfo> activeVersions = new HashMap<>();
377
378
379     for (VersionInfoDeletedEntity versionInfoDeletedEntity : versionInfoDeletedEntities) {
380       activeVersions.put(versionInfoDeletedEntity.getEntityId(),
381           getVersionInfo(versionInfoDeletedEntity, user, action));
382     }
383     return activeVersions;
384   }
385
386   @Override
387   public List<Version> list(String itemId) {
388
389     List<Version> versions = versionDao.list(itemId);
390     Set<String> versionsNames = versions.stream().map(Version::getName).collect(Collectors.toSet());
391     versions.forEach(version -> {
392       version.setAdditionalInfo(new HashMap<>());
393       versionCalculator.injectAdditionalInfo(version, versionsNames);
394     });
395     return versions;
396   }
397
398   @Override
399   public Version get(String itemId, Version version) {
400     return versionDao.get(itemId, version)
401         .map(retrievedVersion -> getUpdateRetrievedVersion(itemId, retrievedVersion))
402         .orElseGet(() -> getSyncedVersion(itemId, version));
403   }
404
405   private Version getUpdateRetrievedVersion(String itemId, Version version) {
406     if (version.getStatus() == VersionStatus.Certified &&
407         (version.getState().getSynchronizationState() == SynchronizationState.OutOfSync ||
408             version.getState().isDirty())) {
409       forceSync(itemId, version);
410       LOGGER.info("Item Id {}, version Id {}: Force sync is done", itemId, version.getId());
411       version = versionDao.get(itemId, version)
412           .orElseThrow(() -> new IllegalStateException(
413               "Get version after a successful force sync must return the version"));
414     }
415     return version;
416   }
417
418   private Version getSyncedVersion(String itemId, Version version) {
419     sync(itemId, version);
420     LOGGER.info("Item Id {}, version Id {}: First time sync is done", itemId, version.getId());
421     return versionDao.get(itemId, version)
422         .orElseThrow(() -> new IllegalStateException(
423             "Get version after a successful sync must return the version"));
424   }
425
426   @Override
427   public Version create(String itemId, Version version, VersionCreationMethod creationMethod) {
428     String baseVersionName = null;
429     if (version.getBaseId() == null) {
430       version.setDescription("Initial version");
431     } else {
432       baseVersionName = get(itemId, new Version(version.getBaseId())).getName();
433     }
434     String versionName = versionCalculator.calculate(baseVersionName, creationMethod);
435     validateVersionName(itemId, versionName);
436     version.setName(versionName);
437
438     versionDao.create(itemId, version);
439     itemManager.updateVersionStatus(itemId, VersionStatus.Draft, null);
440
441     publish(itemId, version, String.format("Create version: %s", version.getName()));
442     return version;
443   }
444
445   private void validateVersionName(String itemId, String versionName) {
446     if (versionDao.list(itemId).stream()
447         .anyMatch(version -> versionName.equals(version.getName()))) {
448       String errorDescription = String
449           .format("Item %s: create version failed, a version with the name %s already exist",
450               itemId, versionName);
451       throw new CoreException(new ErrorCode.ErrorCodeBuilder()
452           .withMessage(errorDescription)
453           .build());
454     }
455   }
456
457   @Override
458   public void submit(String itemId, Version version, String submitDescription) {
459     version = get(itemId, version);
460
461     validateSubmit(itemId, version);
462
463     version.setStatus(VersionStatus.Certified);
464     versionDao.update(itemId, version);
465
466     publish(itemId, version, submitDescription);
467
468     itemManager.updateVersionStatus(itemId, VersionStatus.Certified, VersionStatus.Draft);
469   }
470
471   private void validateSubmit(String itemId, Version version) {
472     if (version.getStatus() == VersionStatus.Certified) {
473       String errorDescription = String
474           .format("Item %s: submit version failed, version %s is already Certified", itemId,
475               version.getId());
476       throw new CoreException(new ErrorCode.ErrorCodeBuilder()
477           .withMessage(errorDescription)
478           .build());
479     }
480   }
481
482   @Override
483   public void publish(String itemId, Version version, String message) {
484     versionDao.publish(itemId, version, message);
485   }
486
487
488   @Override
489   public void sync(String itemId, Version version) {
490     versionDao.sync(itemId, version);
491   }
492
493   @Override
494   public void forceSync(String itemId, Version version) {
495     versionDao.forceSync(itemId, version);
496   }
497
498   @Override
499   public void revert(String itemId, Version version, String revisionId) {
500     versionDao.revert(itemId, version, revisionId);
501   }
502
503   @Override
504   public List<Revision> listRevisions(String itemId, Version version) {
505     return versionDao.listRevisions(itemId, version);
506   }
507
508   private void markAsCheckedOut(VersionInfoEntity versionInfoEntity, String checkingOutUser) {
509     versionInfoEntity.setStatus(VersionStatus.Locked);
510     versionInfoEntity.setCandidate(new UserCandidateVersion(checkingOutUser,
511         versionInfoEntity.getActiveVersion().calculateNextCandidate()));
512   }
513
514   private Version doCheckout(VersionInfoEntity versionInfoEntity, String user) {
515     markAsCheckedOut(versionInfoEntity, user);
516     versionInfoDao.update(versionInfoEntity);
517
518     initVersionOnEntity(versionInfoEntity.getEntityType(), versionInfoEntity.getEntityId(),
519         versionInfoEntity.getActiveVersion(), versionInfoEntity.getCandidate().getVersion());
520
521     return versionInfoEntity.getCandidate().getVersion();
522   }
523
524   private void doDelete(VersionInfoEntity versionInfoEntity) {
525     VersionInfoDeletedEntity versionInfoDeletedEntity = new VersionInfoDeletedEntity();
526     versionInfoDeletedEntity.setStatus(versionInfoEntity.getStatus());
527     versionInfoDeletedEntity.setViewableVersions(versionInfoEntity.getViewableVersions());
528     versionInfoDeletedEntity.setActiveVersion(versionInfoEntity.getActiveVersion());
529     versionInfoDeletedEntity.setCandidate(versionInfoEntity.getCandidate());
530     versionInfoDeletedEntity.setEntityId(versionInfoEntity.getEntityId());
531     versionInfoDeletedEntity.setEntityType(versionInfoEntity.getEntityType());
532     versionInfoDeletedEntity.setLatestFinalVersion(versionInfoEntity.getLatestFinalVersion());
533     versionInfoDeletedDao.create(versionInfoDeletedEntity);
534     versionInfoDao.delete(versionInfoEntity);
535   }
536
537   private void doUndoDelete(VersionInfoDeletedEntity versionInfoDeletedEntity) {
538     VersionInfoEntity versionInfoEntity = new VersionInfoEntity();
539     versionInfoEntity.setStatus(versionInfoDeletedEntity.getStatus());
540     versionInfoEntity.setViewableVersions(versionInfoDeletedEntity.getViewableVersions());
541     versionInfoEntity.setActiveVersion(versionInfoDeletedEntity.getActiveVersion());
542     versionInfoEntity.setCandidate(versionInfoDeletedEntity.getCandidate());
543     versionInfoEntity.setEntityId(versionInfoDeletedEntity.getEntityId());
544     versionInfoEntity.setEntityType(versionInfoDeletedEntity.getEntityType());
545     versionInfoEntity.setLatestFinalVersion(versionInfoDeletedEntity.getLatestFinalVersion());
546     versionInfoDao.create(versionInfoEntity);
547     versionInfoDeletedDao.delete(versionInfoDeletedEntity);
548   }
549
550   private Version doCheckin(VersionInfoEntity versionInfoEntity) {
551     UserCandidateVersion userCandidateVersion = versionInfoEntity.getCandidate();
552     versionInfoEntity.setCandidate(null);
553     versionInfoEntity.setActiveVersion(userCandidateVersion.getVersion());
554     versionInfoEntity.getViewableVersions().add(versionInfoEntity.getActiveVersion());
555     versionInfoEntity.setStatus(VersionStatus.Draft);
556
557     closeVersionOnEntity(versionInfoEntity.getEntityType(), versionInfoEntity.getEntityId(),
558         versionInfoEntity.getActiveVersion());
559
560     versionInfoDao.update(versionInfoEntity);
561
562     return versionInfoEntity.getActiveVersion();
563   }
564
565   private Version doSubmit(VersionInfoEntity versionInfoEntity) {
566     Version finalVersion = versionInfoEntity.getActiveVersion().calculateNextFinal();
567     initVersionOnEntity(versionInfoEntity.getEntityType(), versionInfoEntity.getEntityId(),
568         versionInfoEntity.getActiveVersion(), finalVersion);
569     closeVersionOnEntity(versionInfoEntity.getEntityType(), versionInfoEntity.getEntityId(),
570         finalVersion);
571
572     Set<Version> viewableVersions = new HashSet<>();
573     for (Version version : versionInfoEntity.getViewableVersions()) {
574       if (version.isFinal()) {
575         viewableVersions.add(version);
576       }
577     }
578     viewableVersions.add(finalVersion);
579     versionInfoEntity.setViewableVersions(viewableVersions);
580     versionInfoEntity.setActiveVersion(finalVersion);
581     versionInfoEntity.setLatestFinalVersion(finalVersion);
582     versionInfoEntity.setStatus(VersionStatus.Certified);
583     versionInfoDao.update(versionInfoEntity);
584
585     return finalVersion;
586   }
587
588   private void initVersionOnEntity(String entityType, String entityId, Version baseVersion,
589                                    Version newVersion) {
590     Set<VersionableEntityMetadata> entityMetadatas = VERSIONABLE_ENTITIES.get(entityType);
591     if (entityMetadatas != null) {
592       for (VersionableEntityMetadata entityMetadata : entityMetadatas) {
593         VersionableEntityDaoFactory.getInstance().createInterface(entityMetadata.getStoreType())
594             .initVersion(entityMetadata, entityId, baseVersion, newVersion);
595       }
596     }
597   }
598
599   private void deleteVersionFromEntity(String entityType, String entityId,
600                                        Version versionToDelete, Version backToVersion) {
601     Set<VersionableEntityMetadata> entityMetadatas = VERSIONABLE_ENTITIES.get(entityType);
602     if (entityMetadatas != null) {
603       for (VersionableEntityMetadata entityMetadata : entityMetadatas) {
604         VersionableEntityDaoFactory.getInstance().createInterface(entityMetadata.getStoreType())
605             .deleteVersion(entityMetadata, entityId, versionToDelete, backToVersion);
606       }
607     }
608   }
609
610   private void closeVersionOnEntity(String entityType, String entityId, Version versionToClose) {
611     Set<VersionableEntityMetadata> entityMetadatas = VERSIONABLE_ENTITIES.get(entityType);
612     if (entityMetadatas != null) {
613       for (VersionableEntityMetadata entityMetadata : entityMetadatas) {
614         VersionableEntityDaoFactory.getInstance().createInterface(entityMetadata.getStoreType())
615             .closeVersion(entityMetadata, entityId, versionToClose);
616       }
617     }
618   }
619 }