|
25 | 25 | import config.MetamodelProvider; |
26 | 26 | import dao.ElementDao; |
27 | 27 | import jpa.manager.JPAManager; |
| 28 | +import org.omg.sysml.data.ProjectUsage; |
28 | 29 | import org.omg.sysml.internal.CommitDataVersionIndex; |
29 | 30 | import org.omg.sysml.internal.CommitNamedElementIndex; |
30 | 31 | import org.omg.sysml.internal.WorkingDataVersion; |
@@ -207,6 +208,34 @@ public Optional<Element> findByCommitAndQualifiedName(Commit commit, String qual |
207 | 208 | }); |
208 | 209 | } |
209 | 210 |
|
| 211 | + @Override |
| 212 | + public Optional<ProjectUsage> findProjectUsageByCommitAndId(Commit commit, UUID elementId) { |
| 213 | + return jpaManager.transact(em -> { |
| 214 | + // TODO Commit is detached at this point. This ternary mitigates by requerying for the Commit in this transaction. A better solution would be moving transaction handling up to service layer (supported by general wisdom) and optionally migrating to using Play's @Transactional/JPAApi. Pros would include removal of repetitive transaction handling at the DAO layer and ability to interface with multiple DAOs in the same transaction (consistent view). Cons include increased temptation to keep transaction open for longer than needed, e.g. during JSON serialization due to the convenience of @Transactional (deprecated in >= 2.8.x), and the service, a higher level of abstraction, becoming aware of transactions. An alternative would be DAO-to-DAO calls (generally discouraged) and delegating to non-transactional versions of methods. |
| 215 | + Commit c = em.contains(commit) ? commit : em.find(CommitImpl.class, commit.getId()); |
| 216 | + CommitDataVersionIndex commitIndex = dataDao.getCommitIndex(c, em); |
| 217 | + |
| 218 | + CriteriaBuilder builder = em.getCriteriaBuilder(); |
| 219 | + CriteriaQuery<WorkingDataVersionImpl> query = builder.createQuery(WorkingDataVersionImpl.class); |
| 220 | + Root<CommitDataVersionIndexImpl> commitIndexRoot = query.from(CommitDataVersionIndexImpl.class); |
| 221 | + SetJoin<CommitDataVersionIndexImpl, WorkingDataVersionImpl> workingDataVersionJoin = commitIndexRoot.join(CommitDataVersionIndexImpl_.workingDataVersion); |
| 222 | + Join<WorkingDataVersionImpl, DataVersionImpl> dataVersionJoin = workingDataVersionJoin.join(WorkingDataVersionImpl_.dataVersion); |
| 223 | + Join<DataVersionImpl, DataIdentityImpl> dataIdentityJoin = dataVersionJoin.join(DataVersionImpl_.identity); |
| 224 | + Expression<Boolean> where = builder.and( |
| 225 | + builder.equal(commitIndexRoot.get(CommitDataVersionIndexImpl_.id), commitIndex.getId()), |
| 226 | + builder.equal(dataIdentityJoin.get(DataIdentityImpl_.id), elementId) |
| 227 | + ); |
| 228 | + query.select(workingDataVersionJoin).where(where); |
| 229 | + try { |
| 230 | + return Optional.of(em.createQuery(query).getSingleResult()) |
| 231 | + .map(WorkingDataVersion::getSource) |
| 232 | + .map(projectUsage -> JpaDataDao.resolve(projectUsage, ProjectUsage.class)); |
| 233 | + } catch (NoResultException e) { |
| 234 | + return Optional.empty(); |
| 235 | + } |
| 236 | + }); |
| 237 | + } |
| 238 | + |
210 | 239 | protected CommitNamedElementIndex getCommitNamedElementIndex(Commit commit, EntityManager em) { |
211 | 240 | CriteriaBuilder builder = em.getCriteriaBuilder(); |
212 | 241 | CriteriaQuery<CommitNamedElementIndexImpl> query = builder.createQuery(CommitNamedElementIndexImpl.class); |
|
0 commit comments