diff --git a/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml b/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml index a3735407d0947237063618742e4f47299f3298b0..07486545181a5df376ba83a81d0c62a34596604f 100644 --- a/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml +++ b/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml @@ -112,8 +112,6 @@ <class>org.olat.repository.model.RepositoryEntryLifecycle</class> <class>org.olat.repository.model.RepositoryEntryStatistics</class> <class>org.olat.repository.model.RepositoryEntryLightImpl</class> - <class>org.olat.repository.model.RepositoryEntryMyCourseView</class> - <class>org.olat.repository.model.RepositoryEntryAuthorViewImpl</class> <class>org.olat.repository.model.RepositoryEntryMembership</class> <class>org.olat.instantMessaging.model.InstantMessageImpl</class> <class>org.olat.instantMessaging.model.ImPreferencesImpl</class> diff --git a/src/main/java/org/olat/course/assessment/EfficiencyStatementManager.java b/src/main/java/org/olat/course/assessment/EfficiencyStatementManager.java index 0329bc61641b901fd7e2831adb2dbe544a0ab3cc..5ee424f7d77a717409e3114bde9960a9d9f5f23b 100644 --- a/src/main/java/org/olat/course/assessment/EfficiencyStatementManager.java +++ b/src/main/java/org/olat/course/assessment/EfficiencyStatementManager.java @@ -463,6 +463,20 @@ public class EfficiencyStatementManager extends BasicManager implements UserData } } + public List<UserEfficiencyStatementLight> findEfficiencyStatementsLight(List<Long> keys) { + if(keys == null || keys.isEmpty()) return Collections.emptyList(); + + StringBuilder sb = new StringBuilder(); + sb.append("select statement from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ") + .append(" left join fetch statement.resource resource") + .append(" where statement.key in (:keys)"); + + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), UserEfficiencyStatementLight.class) + .setParameter("keys", keys) + .getResultList(); + } + /** * Find all identities who have an efficiency statement for this course repository entry * @param courseRepoEntryKey diff --git a/src/main/java/org/olat/course/assessment/manager/UserCourseInformationsManager.java b/src/main/java/org/olat/course/assessment/manager/UserCourseInformationsManager.java index 5b51b3fc5fd6200c88bb9c551738c3f17b50ad99..303dc5a50a1647f371f0f3bcd0496d3c524d7d69 100644 --- a/src/main/java/org/olat/course/assessment/manager/UserCourseInformationsManager.java +++ b/src/main/java/org/olat/course/assessment/manager/UserCourseInformationsManager.java @@ -38,6 +38,8 @@ public interface UserCourseInformationsManager { public List<UserCourseInformations> getUserCourseInformations(Identity identity, List<OLATResource> resources); + public List<UserCourseInformations> getUserCourseInformations(List<Long> keys); + public void updateUserCourseInformations(Long courseResId, Identity identity, boolean strict); diff --git a/src/main/java/org/olat/course/assessment/manager/UserCourseInformationsManagerImpl.java b/src/main/java/org/olat/course/assessment/manager/UserCourseInformationsManagerImpl.java index 9cdddc67f29496fa1aad4b8e6f09ec010746d103..3555b285ed81bdfeb06f234b88cff0cde85db570 100644 --- a/src/main/java/org/olat/course/assessment/manager/UserCourseInformationsManagerImpl.java +++ b/src/main/java/org/olat/course/assessment/manager/UserCourseInformationsManagerImpl.java @@ -112,6 +112,24 @@ public class UserCourseInformationsManagerImpl extends BasicManager implements U } } + @Override + public List<UserCourseInformations> getUserCourseInformations(List<Long> keys) { + if(keys == null || keys.isEmpty()) { + return Collections.emptyList(); + } + + StringBuilder sb = new StringBuilder(); + sb.append("select infos from ").append(UserCourseInfosImpl.class.getName()).append(" as infos ") + .append(" inner join fetch infos.resource as resource") + .append(" inner join infos.identity as identity") + .append(" where infos.key in (:keys)"); + + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), UserCourseInformations.class) + .setParameter("keys", keys) + .getResultList(); + } + /** * Update (or create if not exists) the course informations for a user * @param userCourseEnv diff --git a/src/main/java/org/olat/repository/RepositoryEntryAuthorView.java b/src/main/java/org/olat/repository/RepositoryEntryAuthorView.java index a7fe36a1c0cd5b616574f8e1bfc83b7d1559818b..7eebcc6638f5baff178171abaa65d1d1f50f5401 100644 --- a/src/main/java/org/olat/repository/RepositoryEntryAuthorView.java +++ b/src/main/java/org/olat/repository/RepositoryEntryAuthorView.java @@ -60,9 +60,7 @@ public interface RepositoryEntryAuthorView extends OLATResourceable, RepositoryE public Date getLastUsage(); /** - * @return True if some offers are currently available + * @return True if some offers are set */ - public boolean isValidOfferAvailable(); - public boolean isOfferAvailable(); } diff --git a/src/main/java/org/olat/repository/RepositoryEntryMyView.java b/src/main/java/org/olat/repository/RepositoryEntryMyView.java index d8590dc4c70c9f7aa5ca38bf06f2fe2d11b8b82d..9145d01a467aa1245ee76782708be2c318038f70 100644 --- a/src/main/java/org/olat/repository/RepositoryEntryMyView.java +++ b/src/main/java/org/olat/repository/RepositoryEntryMyView.java @@ -81,7 +81,7 @@ public interface RepositoryEntryMyView extends OLATResourceable { /** * @return The average rating of this entry, or null if the entry was never rated */ - public Float getAverageRating(); + public Double getAverageRating(); public long getNumOfRatings(); @@ -91,8 +91,4 @@ public interface RepositoryEntryMyView extends OLATResourceable { * @return True if some offers are currently available */ public boolean isValidOfferAvailable(); - - public boolean isOfferAvailable(); - - } diff --git a/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorViewQueries.java b/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorQueries.java similarity index 80% rename from src/main/java/org/olat/repository/manager/RepositoryEntryAuthorViewQueries.java rename to src/main/java/org/olat/repository/manager/RepositoryEntryAuthorQueries.java index 83d3496563c237c278757e7cc1420b084c51a651..a85d3d057f7cd3b353b9c96b2baccdcde1639b30 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorViewQueries.java +++ b/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorQueries.java @@ -19,6 +19,7 @@ */ package org.olat.repository.manager; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -29,6 +30,7 @@ import org.olat.basesecurity.IdentityImpl; import org.olat.basesecurity.IdentityRef; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.PersistenceHelper; +import org.olat.core.commons.services.mark.impl.MarkImpl; import org.olat.core.id.Identity; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -36,8 +38,10 @@ import org.olat.core.util.StringHelper; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryAuthorView; import org.olat.repository.RepositoryEntryRef; +import org.olat.repository.model.RepositoryEntryAuthorImpl; import org.olat.repository.model.SearchAuthorRepositoryEntryViewParams; import org.olat.repository.model.SearchAuthorRepositoryEntryViewParams.OrderBy; +import org.olat.resource.accesscontrol.model.OfferImpl; import org.olat.user.UserImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -53,9 +57,9 @@ import org.springframework.stereotype.Service; * */ @Service -public class RepositoryEntryAuthorViewQueries { +public class RepositoryEntryAuthorQueries { - private static final OLog log = Tracing.createLoggerFor(RepositoryEntryAuthorViewQueries.class); + private static final OLog log = Tracing.createLoggerFor(RepositoryEntryAuthorQueries.class); @Autowired private DB dbInstance; @@ -91,12 +95,22 @@ public class RepositoryEntryAuthorViewQueries { return Collections.emptyList(); } - TypedQuery<RepositoryEntryAuthorView> query = createViewQuery(params, RepositoryEntryAuthorView.class); + TypedQuery<Object[]> query = createViewQuery(params, Object[].class); query.setFirstResult(firstResult); if(maxResults > 0) { query.setMaxResults(maxResults); } - return query.getResultList(); + List<Object[]> objects = query.getResultList(); + List<RepositoryEntryAuthorView> views = new ArrayList<>(objects.size()); + for(Object[] object:objects) { + RepositoryEntry re = (RepositoryEntry)object[0]; + Number numOfMarks = (Number)object[1]; + boolean hasMarks = numOfMarks == null ? false : numOfMarks.longValue() > 0; + Number numOffers = (Number)object[2]; + long offers = numOffers == null ? 0l : numOffers.longValue(); + views.add(new RepositoryEntryAuthorImpl(re, hasMarks, offers)); + } + return views; } protected <T> TypedQuery<T> createViewQuery(SearchAuthorRepositoryEntryViewParams params, @@ -108,27 +122,36 @@ public class RepositoryEntryAuthorViewQueries { boolean count = Number.class.equals(type); StringBuilder sb = new StringBuilder(); if(count) { - sb.append("select count(v.key) from repositoryentryauthor as v ") + sb.append("select count(v.key) ") + .append(" from repositoryentry as v, ").append(IdentityImpl.class.getName()).append(" as ident ") .append(" inner join v.olatResource as res") .append(" left join v.lifecycle as lifecycle"); } else { - sb.append("select v from repositoryentryauthor as v ") + sb.append("select v, ") + .append(" (select count(mark.key) from ").append(MarkImpl.class.getName()).append(" as mark ") + .append(" where mark.creator=ident and mark.resId=v.key and mark.resName='RepositoryEntry'") + .append(" ) as marks,") + .append(" (select count(offer.key) from ").append(OfferImpl.class.getName()).append(" as offer ") + .append(" where offer.resource=res and offer.valid=true") + .append(" ) as offers") + .append(" from repositoryentry as v, ").append(IdentityImpl.class.getName()).append(" as ident ") .append(" inner join fetch v.olatResource as res") - .append(" left join fetch v.lifecycle as lifecycle"); + .append(" inner join fetch v.statistics as stats") + .append(" left join fetch v.lifecycle as lifecycle "); } - sb.append(" where v.identityKey=:identityKey "); + sb.append(" where ident.key=:identityKey "); //only my entries as author if(params.isOwnedResourcesOnly()) { sb.append(" and exists (select rel from repoentrytogroup as rel, bgroup as baseGroup, bgroupmember as membership") - .append(" where rel.entry=v and rel.group=baseGroup and membership.group=baseGroup and membership.identity.key=v.identityKey") + .append(" where rel.entry=v and rel.group=baseGroup and membership.group=baseGroup and membership.identity.key=ident.key") .append(" and membership.role='").append(GroupRoles.owner.name()).append("'") .append(" )"); } else { sb.append(" and (v.access>=").append(RepositoryEntry.ACC_OWNERS_AUTHORS) .append(" or (v.access=").append(RepositoryEntry.ACC_OWNERS) .append(" and exists (select rel from repoentrytogroup as rel, bgroup as baseGroup, bgroupmember as membership") - .append(" where rel.entry=v and rel.group=baseGroup and membership.group=baseGroup and membership.identity.key=v.identityKey") + .append(" where rel.entry=v and rel.group=baseGroup and membership.group=baseGroup and membership.identity.key=ident.key") .append(" and membership.role='").append(GroupRoles.owner.name()).append("'") .append(" )") .append(" ))"); @@ -141,8 +164,10 @@ public class RepositoryEntryAuthorViewQueries { if (params.isResourceTypesDefined()) { sb.append(" and res.resName in (:resourcetypes)"); } - if(params.getMarked() != null) { - sb.append(" and v.markKey ").append(params.getMarked().booleanValue() ? " is not null " : " is null "); + if(params.getMarked() != null && params.getMarked().booleanValue()) { + sb.append(" and exists (select mark2.key from ").append(MarkImpl.class.getName()).append(" as mark2 ") + .append(" where mark2.creator=ident and mark2.resId=v.key and mark2.resName='RepositoryEntry'") + .append(" )"); } String author = params.getAuthor(); @@ -238,9 +263,9 @@ public class RepositoryEntryAuthorViewQueries { break; case favorit: if(asc) { - sb.append(" order by v.markKey nulls last, lower(v.displayname) asc"); + sb.append(" order by marks asc, lower(v.displayname) asc"); } else { - sb.append(" order by v.markKey nulls first, lower(v.displayname) desc"); + sb.append(" order by marks desc, lower(v.displayname) desc"); } break; case type: @@ -261,9 +286,9 @@ public class RepositoryEntryAuthorViewQueries { break; case ac: if(asc) { - sb.append(" order by v.offersAvailable nulls last, lower(v.displayname) asc"); + sb.append(" order by offers asc, lower(v.displayname) asc"); } else { - sb.append(" order by v.offersAvailable nulls first, lower(v.displayname) desc"); + sb.append(" order by offers desc, lower(v.displayname) desc"); } break; case creationDate: @@ -271,7 +296,7 @@ public class RepositoryEntryAuthorViewQueries { appendAsc(sb, asc).append(", lower(v.displayname) asc"); break; case lastUsage: - sb.append(" order by v.lastUsage "); + sb.append(" order by v.stats.lastUsage "); appendAsc(sb, asc).append(", lower(v.displayname) asc"); break; case lifecycleLabel: diff --git a/src/main/java/org/olat/repository/manager/RepositoryEntryMyCourseViewQueries.java b/src/main/java/org/olat/repository/manager/RepositoryEntryMyCourseQueries.java similarity index 51% rename from src/main/java/org/olat/repository/manager/RepositoryEntryMyCourseViewQueries.java rename to src/main/java/org/olat/repository/manager/RepositoryEntryMyCourseQueries.java index 375847f801998ab5013550470e3fe7de15e68f60..bb294a900e86a50c615cfa5ae70d50a4b13b32b0 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryEntryMyCourseViewQueries.java +++ b/src/main/java/org/olat/repository/manager/RepositoryEntryMyCourseQueries.java @@ -19,26 +19,39 @@ */ package org.olat.repository.manager; +import java.util.ArrayList; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.persistence.TypedQuery; import org.olat.basesecurity.GroupRoles; +import org.olat.basesecurity.IdentityImpl; import org.olat.basesecurity.IdentityRef; import org.olat.catalog.CatalogEntryImpl; import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.mark.impl.MarkImpl; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.course.assessment.EfficiencyStatementManager; +import org.olat.course.assessment.UserCourseInformations; +import org.olat.course.assessment.manager.UserCourseInformationsManager; +import org.olat.course.assessment.model.UserEfficiencyStatementImpl; +import org.olat.course.assessment.model.UserEfficiencyStatementLight; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryMyView; import org.olat.repository.RepositoryEntryRef; +import org.olat.repository.model.RepositoryEntryMyCourseImpl; import org.olat.repository.model.SearchMyRepositoryEntryViewParams; import org.olat.repository.model.SearchMyRepositoryEntryViewParams.Filter; import org.olat.repository.model.SearchMyRepositoryEntryViewParams.OrderBy; +import org.olat.resource.OLATResource; +import org.olat.resource.accesscontrol.model.OfferImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -53,12 +66,16 @@ import org.springframework.stereotype.Service; * */ @Service -public class RepositoryEntryMyCourseViewQueries { +public class RepositoryEntryMyCourseQueries { - private static final OLog log = Tracing.createLoggerFor(RepositoryEntryMyCourseViewQueries.class); + private static final OLog log = Tracing.createLoggerFor(RepositoryEntryMyCourseQueries.class); @Autowired private DB dbInstance; + @Autowired + private EfficiencyStatementManager efficiencyStatementManager; + @Autowired + private UserCourseInformationsManager userCourseInformationsManager; public RepositoryEntryMyView loadView(IdentityRef identity, RepositoryEntryRef ref) { StringBuilder sb = new StringBuilder(); @@ -91,12 +108,58 @@ public class RepositoryEntryMyCourseViewQueries { return Collections.emptyList(); } - TypedQuery<RepositoryEntryMyView> query = creatMyViewQuery(params, RepositoryEntryMyView.class); + TypedQuery<Object[]> query = creatMyViewQuery(params, Object[].class); query.setFirstResult(firstResult); if(maxResults > 0) { query.setMaxResults(maxResults); } - List<RepositoryEntryMyView> views = query.getResultList(); + + List<Long> infosKeys = new ArrayList<>(); + List<Long> effKeys = new ArrayList<>(); + List<Object[]> objects = query.getResultList(); + List<RepositoryEntryMyView> views = new ArrayList<>(objects.size()); + Map<OLATResource,RepositoryEntryMyCourseImpl> viewsMap = new HashMap<>(); + for(Object[] object:objects) { + RepositoryEntry re = (RepositoryEntry)object[0]; + Number numOfMarks = (Number)object[1]; + boolean hasMarks = numOfMarks == null ? false : numOfMarks.longValue() > 0; + Number numOffers = (Number)object[2]; + long offers = numOffers == null ? 0l : numOffers.longValue(); + Integer myRating = (Integer)object[3]; + + RepositoryEntryMyCourseImpl view = new RepositoryEntryMyCourseImpl(re, hasMarks, offers, myRating); + views.add(view); + viewsMap.put(re.getOlatResource(), view); + + Long infosKey = (Long)object[4]; + if(infosKey != null) { + infosKeys.add(infosKey); + } + Long effKey = (Long)object[5]; + if(effKey != null) { + effKeys.add(effKey); + } + } + + if(effKeys.size() > 0) { + List<UserEfficiencyStatementLight> efficiencyStatements = + efficiencyStatementManager.findEfficiencyStatementsLight(effKeys); + for(UserEfficiencyStatementLight efficiencyStatement:efficiencyStatements) { + if(viewsMap.containsKey(efficiencyStatement.getResource())) { + viewsMap.get(efficiencyStatement.getResource()).setEfficiencyStatement(efficiencyStatement); + } + } + } + + if(infosKeys.size() > 0) { + List<UserCourseInformations> courseInfos = userCourseInformationsManager.getUserCourseInformations(infosKeys); + for(UserCourseInformations courseInfo:courseInfos) { + if(viewsMap.containsKey(courseInfo.getResource())) { + viewsMap.get(courseInfo.getResource()).setCourseInfos(courseInfo); + } + } + } + return views; } @@ -109,17 +172,43 @@ public class RepositoryEntryMyCourseViewQueries { boolean count = Number.class.equals(type); StringBuilder sb = new StringBuilder(); + if(count) { - sb.append("select count(v.key) from repositoryentrymy as v ") + sb.append("select count(v.key) ") + .append(" from repositoryentry as v, ").append(IdentityImpl.class.getName()).append(" as ident ") .append(" inner join v.olatResource as res") - .append(" left join v.lifecycle as lifecycle"); + .append(" inner join v.statistics as stats") + .append(" left join v.lifecycle as lifecycle "); } else { - sb.append("select v from repositoryentrymy as v ") + sb.append("select v, ") + .append(" (select count(mark.key) from ").append(MarkImpl.class.getName()).append(" as mark ") + .append(" where mark.creator=ident and mark.resId=v.key and mark.resName='RepositoryEntry'") + .append(" ) as marks,") + .append(" (select count(offer.key) from ").append(OfferImpl.class.getName()).append(" as offer ") + .append(" where offer.resource=res and offer.valid=true") + //TODO validity + .append(" ) as offers, ") + .append(" (select rating.rating from userrating as rating") + .append(" where rating.resId=v.key and rating.creator=ident and rating.resName='RepositoryEntry'") + .append(" ) as myrating") + // user course informations + .append(" ,(select infos.key from usercourseinfos as infos") + .append(" where infos.resource=res and infos.identity=ident") + .append(" ) as infosKey") + //efficiency statements + .append(" ,(select eff.key from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as eff") + .append(" where eff.resource=res and eff.identity=ident") + .append(" ) as effKey"); + appendOrderByInSelect(params, sb); + sb.append(" from repositoryentry as v, ").append(IdentityImpl.class.getName()).append(" as ident ") .append(" inner join fetch v.olatResource as res") - .append(" left join fetch v.lifecycle as lifecycle"); + .append(" inner join fetch v.statistics as stats") + .append(" left join fetch v.lifecycle as lifecycle "); } + //user course informations + //efficiency statements - sb.append(" where v.identityKey=:identityKey and "); + sb.append(" where ident.key=:identityKey and "); appendMyViewAccessSubSelect(sb, roles, params.getFilters(), params.isMembershipMandatory()); if(params.getRepoEntryKeys() != null && params.getRepoEntryKeys().size() > 0) { sb.append(" and v.key in (:repoEntryKeys) "); @@ -127,7 +216,7 @@ public class RepositoryEntryMyCourseViewQueries { if(params.getFilters() != null) { for(Filter filter:params.getFilters()) { - appendMyViewFilters(filter, sb); + appendFiltersInWhereClause(filter, sb); } } @@ -139,12 +228,14 @@ public class RepositoryEntryMyCourseViewQueries { if (params.isResourceTypesDefined()) { sb.append(" and res.resName in (:resourcetypes)"); } - if(params.getMarked() != null) { - sb.append(" and v.markKey ").append(params.getMarked().booleanValue() ? " is not null " : " is null "); + if(params.getMarked() != null && params.getMarked().booleanValue()) { + sb.append(" and exists (select mark2.key from ").append(MarkImpl.class.getName()).append(" as mark2 ") + .append(" where mark2.creator=ident and mark2.resId=v.key and mark2.resName='RepositoryEntry'") + .append(" )"); } if(!count) { - appendMyViewOrderBy(params.getOrderBy(), params.isOrderByAsc(), sb); + appendOrderBy(params.getOrderBy(), params.isOrderByAsc(), sb); } TypedQuery<T> dbQuery = dbInstance.getCurrentEntityManager() @@ -200,7 +291,7 @@ public class RepositoryEntryMyCourseViewQueries { sb.append(" or (") .append(" v.access=").append(RepositoryEntry.ACC_OWNERS).append(" and v.membersOnly=true") .append(" and exists (select rel from repoentrytogroup as rel, bgroup as baseGroup, bgroupmember as membership") - .append(" where rel.entry=v and rel.group=baseGroup and membership.group=baseGroup and membership.identity.key=v.identityKey") + .append(" where rel.entry=v and rel.group=baseGroup and membership.group=baseGroup and membership.identity.key=ident.key") .append(" and membership.role in ('").append(GroupRoles.owner.name()).append("','").append(GroupRoles.coach.name()).append("','").append(GroupRoles.participant.name()).append("')") .append(" )") .append(" )") @@ -212,38 +303,69 @@ public class RepositoryEntryMyCourseViewQueries { //make sure that in all case the role is mandatory sb.append(" or (v.access=").append(RepositoryEntry.ACC_OWNERS).append(" and v.membersOnly=true))") .append(" and exists (select rel from repoentrytogroup as rel, bgroup as baseGroup, bgroupmember as membership") - .append(" where rel.entry=v and rel.group=baseGroup and membership.group=baseGroup and membership.identity.key=v.identityKey") + .append(" where rel.entry=v and rel.group=baseGroup and membership.group=baseGroup and membership.identity.key=ident.key") .append(" and membership.role in (").append(inRoles).append(")") .append(" )"); } } } - private void appendMyViewFilters(Filter filter, StringBuilder sb) { + private void appendFiltersInWhereClause(Filter filter, StringBuilder sb) { switch(filter) { case currentCourses: - sb.append(" and ").append(" lifecycle.validFrom<=:now and lifecycle.validTo>=:now"); + sb.append(" and lifecycle.validFrom<=:now and lifecycle.validTo>=:now"); break; case upcomingCourses: - sb.append(" and ").append(" lifecycle.validFrom>=:now"); + sb.append(" and lifecycle.validFrom>=:now"); break; case oldCourses: - sb.append(" and ").append(" lifecycle.validTo<=:now"); + sb.append(" and lifecycle.validTo<=:now"); break; case passed: - sb.append(" and ").append(" v.passed=true"); + sb.append(" and exists (select eff2.key from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as eff2") + .append(" where eff2.resource=res and eff2.identity=ident and eff2.passed=true") + .append(" )"); break; case notPassed: - sb.append(" and ").append(" v.passed=false"); + sb.append(" and exists (select eff3.key from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as eff3") + .append(" where eff3.resource=res and eff3.identity=ident and eff3.passed=false") + .append(" )"); break; case withoutPassedInfos: - sb.append(" and ").append(" v.passed is null"); + sb.append(" and exists (select eff4.key from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as eff4") + .append(" where eff4.resource=res and eff4.identity=ident and eff4.passed is null") + .append(" )"); break; default: //do nothing } } - private void appendMyViewOrderBy(OrderBy orderBy, boolean asc, StringBuilder sb) { + + private void appendOrderByInSelect(SearchMyRepositoryEntryViewParams params, StringBuilder sb) { + OrderBy orderBy = params.getOrderBy(); + if(orderBy != null) { + switch(orderBy) { + case lastVisited: + sb.append(" ,(select infos2.recentLaunch from usercourseinfos as infos2") + .append(" where infos2.resource=res and infos2.identity=ident") + .append(" ) as recentLaunch"); + break; + case passed: + sb.append(" ,(select eff3.passed from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as eff3") + .append(" where eff3.resource=res and eff3.identity=ident") + .append(" ) as passed"); + break; + case score: + sb.append(" ,(select eff4.score from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as eff4") + .append(" where eff4.resource=res and eff4.identity=ident") + .append(" ) as score"); + break; + default: //do nothing + } + } + } + + private void appendOrderBy(OrderBy orderBy, boolean asc, StringBuilder sb) { if(orderBy != null) { switch(orderBy) { case automatic: @@ -252,21 +374,21 @@ public class RepositoryEntryMyCourseViewQueries { break; case favorit: if(asc) { - sb.append(" order by v.markKey nulls last, lower(v.displayname) asc"); + sb.append(" order by marks asc, lower(v.displayname) asc"); } else { - sb.append(" order by v.markKey nulls first, lower(v.displayname) desc"); + sb.append(" order by marks desc, lower(v.displayname) desc"); } break; case lastVisited: - sb.append(" order by v.recentLaunch "); + sb.append(" order by recentLaunch "); appendAsc(sb, asc).append(" nulls last, lower(v.displayname) asc"); break; case passed: - sb.append(" order by v.passed "); + sb.append(" order by passed "); appendAsc(sb, asc).append(" nulls last, lower(v.displayname) asc"); break; case score: - sb.append(" order by v.score "); + sb.append(" order by score "); appendAsc(sb, asc).append(" nulls last, lower(v.displayname) asc"); break; case title: @@ -290,7 +412,7 @@ public class RepositoryEntryMyCourseViewQueries { appendAsc(sb, asc).append(", lower(v.displayname) asc"); break; case rating: - sb.append(" order by v.averageRating "); + sb.append(" order by v.statistics.rating "); appendAsc(sb, asc).append(" nulls last, lower(v.displayname) asc"); break; default: @@ -309,4 +431,76 @@ public class RepositoryEntryMyCourseViewQueries { } return sb; } + + /* + protected <T> TypedQuery<T> creatMyViewQuery(SearchMyRepositoryEntryViewParams params, + Class<T> type) { + + Roles roles = params.getRoles(); + Identity identity = params.getIdentity(); + List<String> resourceTypes = params.getResourceTypes(); + + boolean count = Number.class.equals(type); + StringBuilder sb = new StringBuilder(); + + String entity = "repositoryentrymy"; + if(params.getMarked() != null && params.getMarked().booleanValue()) { + entity = "repositoryentrymy"; + } + + if(count) { + sb.append("select count(v.key) from ").append(entity).append(" as v ") + .append(" inner join v.olatResource as res") + .append(" left join v.lifecycle as lifecycle"); + } else { + sb.append("select v from ").append(entity).append(" as v ") + .append(" inner join fetch v.olatResource as res") + .append(" left join fetch v.lifecycle as lifecycle"); + } + + sb.append(" where v.identityKey=:identityKey and "); + appendMyViewAccessSubSelect(sb, roles, params.getFilters(), params.isMembershipMandatory()); + if(params.getRepoEntryKeys() != null && params.getRepoEntryKeys().size() > 0) { + sb.append(" and v.key in (:repoEntryKeys) "); + } + + if(params.getFilters() != null) { + for(Filter filter:params.getFilters()) { + appendMyViewFilters(filter, sb); + } + } + + if(params.getParentEntry() != null) { + sb.append(" and exists (select cei.parent.key from ").append(CatalogEntryImpl.class.getName()).append(" as cei ") + .append(" where cei.parent.key=:parentCeiKey and cei.repositoryEntry.key=v.key") + .append(" )"); + } + if (params.isResourceTypesDefined()) { + sb.append(" and res.resName in (:resourcetypes)"); + } + if(params.getMarked() != null) { + sb.append(" and v.markKey ").append(params.getMarked().booleanValue() ? " is not null " : " is null "); + } + + if(!count) { + appendMyViewOrderBy(params.getOrderBy(), params.isOrderByAsc(), sb); + } + + TypedQuery<T> dbQuery = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), type); + if(params.getParentEntry() != null) { + dbQuery.setParameter("parentCeiKey", params.getParentEntry().getKey()); + } + if(params.getRepoEntryKeys() != null && params.getRepoEntryKeys().size() > 0) { + dbQuery.setParameter("repoEntryKeys", params.getRepoEntryKeys()); + } + if (params.isResourceTypesDefined()) { + dbQuery.setParameter("resourcetypes", resourceTypes); + } + if(params.isLifecycleFilterDefined()) { + dbQuery.setParameter("now", new Date()); + } + dbQuery.setParameter("identityKey", identity.getKey()); + return dbQuery; + }*/ } \ No newline at end of file diff --git a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java index a4ffaa8bc6e3812d3e6ce2f07c1259764ddf988c..1a2118d677039500770c6bd54907579f2403df05 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java +++ b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java @@ -82,9 +82,9 @@ public class RepositoryServiceImpl implements RepositoryService { @Autowired private RepositoryEntryStatisticsDAO repositoryEntryStatisticsDao; @Autowired - private RepositoryEntryMyCourseViewQueries myCourseViewQueries; + private RepositoryEntryMyCourseQueries myCourseViewQueries; @Autowired - private RepositoryEntryAuthorViewQueries authorViewQueries; + private RepositoryEntryAuthorQueries authorViewQueries; @Autowired private OLATResourceManager resourceManager; diff --git a/src/main/java/org/olat/repository/model/RepositoryEntryAuthorViewImpl.java b/src/main/java/org/olat/repository/model/RepositoryEntryAuthorImpl.java similarity index 50% rename from src/main/java/org/olat/repository/model/RepositoryEntryAuthorViewImpl.java rename to src/main/java/org/olat/repository/model/RepositoryEntryAuthorImpl.java index 8d2ab0e543a197d80aff4ab7cb2cb39ceb3f78d3..f0cf62b1caea12987ae20b85b19d8b224ff65c64 100644 --- a/src/main/java/org/olat/repository/model/RepositoryEntryAuthorViewImpl.java +++ b/src/main/java/org/olat/repository/model/RepositoryEntryAuthorImpl.java @@ -21,94 +21,69 @@ package org.olat.repository.model; import java.util.Date; -import javax.persistence.Cacheable; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import org.hibernate.annotations.GenericGenerator; import org.olat.core.util.resource.OresHelper; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryAuthorView; import org.olat.resource.OLATResource; -import org.olat.resource.OLATResourceImpl; /** * - * Initial date: 28.04.2014<br> + * Initial date: 04.06.2014<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -@Cacheable(false) -@Entity(name="repositoryentryauthor") -@Table(name="o_repositoryentry_author_v") -public class RepositoryEntryAuthorViewImpl implements RepositoryEntryAuthorView { - - @Id - @GeneratedValue(generator = "system-uuid") - @GenericGenerator(name = "system-uuid", strategy = "hilo") - @Column(name="re_id", nullable=false, unique=true, insertable=false, updatable=false) +public class RepositoryEntryAuthorImpl implements RepositoryEntryAuthorView { + private Long key; - @Temporal(TemporalType.TIMESTAMP) - @Column(name="re_creationdate", nullable=false, insertable=false, updatable=false) private Date creationDate; - @Temporal(TemporalType.TIMESTAMP) - @Column(name="re_lastmodified", nullable=false, insertable=false, updatable=false) - private Date lastModified; - @Column(name="re_displayname", nullable=false, insertable=false, updatable=false) private String displayname; - @Column(name="re_description", nullable=false, insertable=false, updatable=false) private String description; - @Column(name="re_author", nullable=false, insertable=false, updatable=false) private String author; - @Column(name="re_authors", nullable=false, insertable=false, updatable=false) private String authors; - @Column(name="re_softkey", nullable=false, insertable=false, updatable=false) private String softkey; - @Column(name="re_external_id", nullable=false, insertable=false, updatable=false) private String externalId; - @Column(name="re_external_ref", nullable=false, insertable=false, updatable=false) private String externalRef; - @Column(name="re_membersonly", nullable=false, insertable=false, updatable=false) private boolean membersOnly; - @Column(name="re_accesscode", nullable=false, insertable=false, updatable=false) private int access; - @Column(name="re_statuscode", nullable=false, insertable=false, updatable=false) private int statusCode; - @Temporal(TemporalType.TIMESTAMP) - @Column(name="re_lastusage", nullable=false, insertable=false, updatable=false) private Date lastUsage; - @ManyToOne(targetEntity=OLATResourceImpl.class,fetch=FetchType.LAZY,optional=false) - @JoinColumn(name="fk_olatresource", nullable=false, insertable=false, updatable=false) private OLATResource olatResource; - - @ManyToOne(targetEntity=RepositoryEntryLifecycle.class,fetch=FetchType.LAZY,optional=true) - @JoinColumn(name="fk_lifecycle", nullable=true, insertable=false, updatable=false) private RepositoryEntryLifecycle lifecycle; - @Column(name="mark_id", nullable=true, insertable=false, updatable=false) - private Long markKey; + private boolean marked; - @Column(name="num_of_valid_offers", nullable=true, insertable=false, updatable=false) - private long offersAvailable; - @Column(name="num_of_offers", nullable=true, insertable=false, updatable=false) private long offers; - @Column(name="member_id", nullable=true, insertable=false, updatable=false) - private Long identityKey; + public RepositoryEntryAuthorImpl(RepositoryEntry re, boolean marked, long offers) { + key = re.getKey(); + creationDate = re.getCreationDate(); + + displayname = re.getDisplayname(); + description = re.getDescription(); + author = re.getInitialAuthor(); + authors = re.getAuthors(); + + softkey = re.getSoftkey(); + externalId = re.getExternalId(); + externalRef = re.getExternalRef(); + + membersOnly = re.isMembersOnly(); + access = re.getAccess(); + statusCode = re.getStatusCode(); + + lastUsage = re.getStatistics().getLastUsage(); + + olatResource = re.getOlatResource(); + lifecycle = re.getLifecycle(); + this.marked = marked; + this.offers = offers; + } @Override public Long getKey() { @@ -196,7 +171,7 @@ public class RepositoryEntryAuthorViewImpl implements RepositoryEntryAuthorView @Override public boolean isMarked() { - return markKey != null; + return marked; } @Override @@ -204,16 +179,8 @@ public class RepositoryEntryAuthorViewImpl implements RepositoryEntryAuthorView return lastUsage; } - @Override - public boolean isValidOfferAvailable() { - return offersAvailable > 0; - } - @Override public boolean isOfferAvailable() { return offers > 0; } - - - -} +} \ No newline at end of file diff --git a/src/main/java/org/olat/repository/model/RepositoryEntryMyCourseView.java b/src/main/java/org/olat/repository/model/RepositoryEntryMyCourseImpl.java similarity index 59% rename from src/main/java/org/olat/repository/model/RepositoryEntryMyCourseView.java rename to src/main/java/org/olat/repository/model/RepositoryEntryMyCourseImpl.java index fc4bd59b37ea7ef84e342e610f00b8c33309736d..4ca48d52bca9462805d69b985e44134f0f988124 100644 --- a/src/main/java/org/olat/repository/model/RepositoryEntryMyCourseView.java +++ b/src/main/java/org/olat/repository/model/RepositoryEntryMyCourseImpl.java @@ -21,25 +21,13 @@ package org.olat.repository.model; import java.util.Date; -import javax.persistence.Cacheable; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import org.hibernate.annotations.GenericGenerator; import org.olat.core.id.CreateInfo; import org.olat.core.id.ModifiedInfo; -import org.olat.core.id.Persistable; +import org.olat.course.assessment.UserCourseInformations; +import org.olat.course.assessment.model.UserEfficiencyStatementLight; +import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryMyView; import org.olat.resource.OLATResource; -import org.olat.resource.OLATResourceImpl; /** * This view is based on a CROSS JOIN, the identityKey must be set @@ -50,80 +38,82 @@ import org.olat.resource.OLATResourceImpl; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -@Cacheable(false) -@Entity(name="repositoryentrymy") -@Table(name="o_repositoryentry_my_v") -public class RepositoryEntryMyCourseView implements RepositoryEntryMyView, Persistable, CreateInfo, ModifiedInfo { +public class RepositoryEntryMyCourseImpl implements RepositoryEntryMyView, CreateInfo, ModifiedInfo { - private static final long serialVersionUID = -8484159601386853047L; - - @Id - @GeneratedValue(generator = "system-uuid") - @GenericGenerator(name = "system-uuid", strategy = "hilo") - @Column(name="re_id", nullable=false, unique=true, insertable=false, updatable=false) private Long key; - - @Temporal(TemporalType.TIMESTAMP) - @Column(name="re_creationdate", nullable=false, insertable=false, updatable=false) private Date creationDate; - @Temporal(TemporalType.TIMESTAMP) - @Column(name="re_lastmodified", nullable=false, insertable=false, updatable=false) private Date lastModified; - - @Column(name="re_displayname", nullable=false, insertable=false, updatable=false) private String displayname; - @Column(name="re_description", nullable=false, insertable=false, updatable=false) private String description; - @Column(name="re_authors", nullable=false, insertable=false, updatable=false) private String authors; - @Column(name="re_membersonly", nullable=false, insertable=false, updatable=false) private boolean membersOnly; - @Column(name="re_accesscode", nullable=false, insertable=false, updatable=false) private int access; - @ManyToOne(targetEntity=OLATResourceImpl.class,fetch=FetchType.LAZY,optional=false) - @JoinColumn(name="fk_olatresource", nullable=false, insertable=false, updatable=false) private OLATResource olatResource; - - @ManyToOne(targetEntity=RepositoryEntryLifecycle.class,fetch=FetchType.LAZY,optional=true) - @JoinColumn(name="fk_lifecycle", nullable=true, insertable=false, updatable=false) private RepositoryEntryLifecycle lifecycle; - @Column(name="eff_score", nullable=true, insertable=false, updatable=false) private Float score; - @Column(name="eff_passed", nullable=true, insertable=false, updatable=false) private Boolean passed; - @Column(name="mark_id", nullable=true, insertable=false, updatable=false) - private Long markKey; + private boolean marked; - @Column(name="rat_rating", nullable=true, insertable=false, updatable=false) private Integer myRating; - @Column(name="stats_rating", nullable=true, insertable=false, updatable=false) - private Float averageRating; - @Column(name="stats_num_of_ratings", nullable=true, insertable=false, updatable=false) + + private Double averageRating; private long numOfRatings; - @Column(name="stats_num_of_comments", nullable=true, insertable=false, updatable=false) private long numOfComments; - @Column(name="ci_initiallaunchdate", nullable=true, insertable=false, updatable=false) private Date initialLaunch; - @Column(name="ci_recentlaunchdate", nullable=true, insertable=false, updatable=false) private Date recentLaunch; - @Column(name="ci_visit", nullable=true, insertable=false, updatable=false) private Integer visit; - @Column(name="ci_timespend", nullable=true, insertable=false, updatable=false) private Long timeSpend; - @Column(name="num_of_valid_offers", nullable=true, insertable=false, updatable=false) private long offersAvailable; - @Column(name="num_of_offers", nullable=true, insertable=false, updatable=false) - private long offers; - @Column(name="member_id", nullable=true, insertable=false, updatable=false) - private Long identityKey; + public RepositoryEntryMyCourseImpl(RepositoryEntry re, + boolean marked, long offersAvailable, Integer myRating) { + key = re.getKey(); + creationDate = re.getCreationDate(); + lastModified = re.getLastModified(); + displayname = re.getDisplayname(); + description = re.getDescription(); + authors = re.getAuthors(); + membersOnly = re.isMembersOnly(); + access = re.getAccess(); + + olatResource = re.getOlatResource(); + lifecycle = re.getLifecycle(); + this.marked = marked; + this.myRating = myRating; + + RepositoryEntryStatistics stats = re.getStatistics(); + if(stats != null) { + averageRating = stats.getRating(); + numOfRatings = stats.getNumOfRatings(); + numOfComments = stats.getNumOfComments(); + } + + this.offersAvailable = offersAvailable; + } + + public void setEfficiencyStatement(UserEfficiencyStatementLight efficiencyStatment) { + if(efficiencyStatment != null) { + score = efficiencyStatment.getScore(); + passed = efficiencyStatment.getPassed(); + } + } + + public void setCourseInfos(UserCourseInformations courseInfos) { + if(courseInfos != null) { + initialLaunch = courseInfos.getInitialLaunch(); + recentLaunch = courseInfos.getRecentLaunch(); + visit = courseInfos.getVisit(); + timeSpend = courseInfos.getTimeSpend(); + } + } + @Override public Long getKey() { return key; @@ -244,7 +234,7 @@ public class RepositoryEntryMyCourseView implements RepositoryEntryMyView, Persi @Override public boolean isMarked() { - return markKey != null; + return marked; } @Override @@ -291,11 +281,11 @@ public class RepositoryEntryMyCourseView implements RepositoryEntryMyView, Persi this.myRating = myRating; } - public Float getAverageRating() { + public Double getAverageRating() { return averageRating; } - public void setAverageRating(Float averageRating) { + public void setAverageRating(Double averageRating) { this.averageRating = averageRating; } @@ -319,11 +309,6 @@ public class RepositoryEntryMyCourseView implements RepositoryEntryMyView, Persi public boolean isValidOfferAvailable() { return offersAvailable > 0; } - - @Override - public boolean isOfferAvailable() { - return offers > 0; - } @Override @@ -331,8 +316,8 @@ public class RepositoryEntryMyCourseView implements RepositoryEntryMyView, Persi if(this == obj) { return true; } - if(obj instanceof RepositoryEntryMyCourseView) { - RepositoryEntryMyCourseView relc = (RepositoryEntryMyCourseView)obj; + if(obj instanceof RepositoryEntryMyCourseImpl) { + RepositoryEntryMyCourseImpl relc = (RepositoryEntryMyCourseImpl)obj; return getKey() != null && getKey().equals(relc.getKey()); } return false; @@ -347,9 +332,4 @@ public class RepositoryEntryMyCourseView implements RepositoryEntryMyView, Persi public String toString() { return super.toString(); } - - @Override - public boolean equalsByPersistableKey(Persistable persistable) { - return equals(persistable); - } } \ No newline at end of file diff --git a/src/main/java/org/olat/repository/model/SearchMyRepositoryEntryViewParams.java b/src/main/java/org/olat/repository/model/SearchMyRepositoryEntryViewParams.java index 9ba67ffdecfeecc5cc38c9ffcafb6fa23b88a826..d435a6045d56951b286acc50d6ea523fc82202e8 100644 --- a/src/main/java/org/olat/repository/model/SearchMyRepositoryEntryViewParams.java +++ b/src/main/java/org/olat/repository/model/SearchMyRepositoryEntryViewParams.java @@ -100,6 +100,12 @@ public class SearchMyRepositoryEntryViewParams { this.filters = filters; } + public boolean isPassedFiltered() { + return filters != null && (filters.contains(Filter.notPassed) + || filters.contains(Filter.passed) + || filters.contains(Filter.withoutPassedInfos)); + } + public boolean isLifecycleFilterDefined() { return filters != null && (filters.contains(Filter.upcomingCourses) || filters.contains(Filter.currentCourses) diff --git a/src/main/java/org/olat/repository/ui/author/AuthoringEntryDataSource.java b/src/main/java/org/olat/repository/ui/author/AuthoringEntryDataSource.java index 22093d29f05df055cc9dd39b38f3efd66bd4eba1..db24ae9be16ef11437d1c63b923fbd0b2ff5a19b 100644 --- a/src/main/java/org/olat/repository/ui/author/AuthoringEntryDataSource.java +++ b/src/main/java/org/olat/repository/ui/author/AuthoringEntryDataSource.java @@ -143,7 +143,7 @@ public class AuthoringEntryDataSource implements FlexiTableDataSourceDelegate<Au Set<String> newNames = new HashSet<String>(); List<OLATResource> resourcesWithAC = new ArrayList<>(repoEntries.size()); for(RepositoryEntryAuthorView entry:repoEntries) { - if(entry.isValidOfferAvailable()) { + if(entry.isOfferAvailable()) { resourcesWithAC.add(entry.getOlatResource()); } final String author = entry.getAuthor(); diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java index 4922eb939b9f37fb19cace6d95699aa861a9596f..01a8c005840fe38c4fc91867fa80d09e353908f6 100644 --- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java +++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java @@ -209,7 +209,7 @@ public class RepositoryEntryDetailsController extends FormBasicController { markLink.setIconLeftCSS(marked ? Mark.MARK_CSS_LARGE : Mark.MARK_ADD_CSS_LARGE); Integer myRating = row.getMyRating(); - Float averageRating = row.getAverageRating(); + Double averageRating = row.getAverageRating(); long numOfRatings = row.getNumOfRatings(); float ratingValue = myRating == null ? 0f : myRating.floatValue(); float averageRatingValue = averageRating == null ? 0f : averageRating.floatValue(); diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java index 3f385784eaebf2e0f58866df8835121a6fe0548d..22639376f8634497e357801fe0807ee2c29055a9 100644 --- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java +++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java @@ -413,7 +413,7 @@ public class RepositoryEntryListController extends FormBasicController @Override public void forgeRatings(RepositoryEntryRow row) { Integer myRating = row.getMyRating(); - Float averageRating = row.getAverageRating(); + Double averageRating = row.getAverageRating(); long numOfRatings = row.getNumOfRatings(); float ratingValue = myRating == null ? 0f : myRating.floatValue(); diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryRow.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryRow.java index 2daf6e978afe40e713ff0b249ee28052d4a90eae..79df16a0cd664cf90b4d9b6026bb32634dd02c7f 100644 --- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryRow.java +++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryRow.java @@ -61,7 +61,7 @@ public class RepositoryEntryRow implements RepositoryEntryRef { public Date recentLaunch; private Integer myRating; - private Float averageRating; + private Double averageRating; private long numOfRatings; private long numOfComments; @@ -196,11 +196,11 @@ public class RepositoryEntryRow implements RepositoryEntryRef { this.myRating = myRating; } - public Float getAverageRating() { + public Double getAverageRating() { return averageRating; } - public void setAverageRating(Float averageRating) { + public void setAverageRating(Double averageRating) { this.averageRating = averageRating; } diff --git a/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql b/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql index 291e6a3552d9c8224f77214c5c33c86e84e424d3..5fa27179833ed44110c272a3f2de5f40fecd1d93 100644 --- a/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql +++ b/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql @@ -282,87 +282,6 @@ create or replace view o_as_eff_statement_groups_v as ( left join o_as_user_course_infos as pg_initial_launch on (pg_initial_launch.fk_resource_id = sg_re.fk_olatresource and pg_initial_launch.fk_identity = sg_participant.fk_identity_id) ); --- new views -create or replace view o_repositoryentry_my_v as ( - select - re.repositoryentry_id as re_id, - re.creationdate as re_creationdate, - re.lastmodified as re_lastmodified, - re.displayname as re_displayname, - re.description as re_description, - re.authors as re_authors, - re.accesscode as re_accesscode, - re.membersonly as re_membersonly, - re.statuscode as re_statuscode, - re.fk_lifecycle as fk_lifecycle, - re.fk_olatresource as fk_olatresource, - courseinfos.initiallaunchdate as ci_initiallaunchdate, - courseinfos.recentlaunchdate as ci_recentlaunchdate, - courseinfos.visit as ci_visit, - courseinfos.timespend as ci_timespend, - effstatement.score as eff_score, - effstatement.passed as eff_passed, - mark.mark_id as mark_id, - rating.rating as rat_rating, - stats.r_rating as stats_rating, - stats.r_num_of_ratings as stats_num_of_ratings, - stats.r_num_of_comments as stats_num_of_comments, - ident.id as member_id, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - and (offer.validfrom is null or offer.validfrom <= current_timestamp()) - and (offer.validto is null or offer.validto >= current_timestamp()) - ) as num_of_valid_offers, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - ) as num_of_offers - from o_repositoryentry as re - cross join o_bs_identity as ident - inner join o_repositoryentry_stats as stats on (re.fk_stats=stats.id) - left join o_mark as mark on (mark.creator_id=ident.id and re.repositoryentry_id=mark.resid and mark.resname='RepositoryEntry') - left join o_as_eff_statement as effstatement on (effstatement.fk_identity=ident.id and effstatement.fk_resource_id = re.fk_olatresource) - left join o_userrating as rating on (rating.creator_id=ident.id and re.repositoryentry_id=rating.resid and rating.resname='RepositoryEntry') - left join o_as_user_course_infos as courseinfos on (courseinfos.fk_identity=ident.id and re.fk_olatresource=courseinfos.fk_resource_id) -); - -create or replace view o_repositoryentry_author_v as ( - select - re.repositoryentry_id as re_id, - re.creationdate as re_creationdate, - re.lastmodified as re_lastmodified, - re.displayname as re_displayname, - re.description as re_description, - re.softkey as re_softkey, - re.external_id as re_external_id, - re.external_ref as re_external_ref, - re.initialauthor as re_author, - re.authors as re_authors, - re.accesscode as re_accesscode, - re.membersonly as re_membersonly, - re.statuscode as re_statuscode, - re.fk_lifecycle as fk_lifecycle, - re.fk_olatresource as fk_olatresource, - stats.r_lastusage as re_lastusage, - mark.mark_id as mark_id, - ident.id as member_id, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - and (offer.validfrom is null or offer.validfrom <= current_timestamp) - and (offer.validto is null or offer.validto >= current_timestamp) - ) as num_of_valid_offers, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - ) as num_of_offers - from o_repositoryentry as re - cross join o_bs_identity as ident - inner join o_repositoryentry_stats as stats on (re.fk_stats=stats.id) - left join o_mark as mark on (mark.creator_id=ident.id and re.repositoryentry_id=mark.resid and mark.resname='RepositoryEntry') -); - -- drop views drop view o_gp_visible_participant_v; drop view o_gp_contact_participant_v; diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index 5aba5651f2cc892b98ac3de282216c75a36c0240..df380e4277a184b07b73a80f7eeed0cb5e858ac7 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -1454,86 +1454,6 @@ create or replace view o_re_membership_v as ( inner join o_re_to_group relgroup on (relgroup.fk_entry_id=re.repositoryentry_id) inner join o_bs_group_member as bmember on (bmember.fk_group_id=relgroup.fk_group_id) ); - -create view o_repositoryentry_my_v as ( - select - re.repositoryentry_id as re_id, - re.creationdate as re_creationdate, - re.lastmodified as re_lastmodified, - re.displayname as re_displayname, - re.description as re_description, - re.authors as re_authors, - re.accesscode as re_accesscode, - re.membersonly as re_membersonly, - re.statuscode as re_statuscode, - re.fk_lifecycle as fk_lifecycle, - re.fk_olatresource as fk_olatresource, - courseinfos.initiallaunchdate as ci_initiallaunchdate, - courseinfos.recentlaunchdate as ci_recentlaunchdate, - courseinfos.visit as ci_visit, - courseinfos.timespend as ci_timespend, - effstatement.score as eff_score, - effstatement.passed as eff_passed, - mark.mark_id as mark_id, - rating.rating as rat_rating, - stats.r_rating as stats_rating, - stats.r_num_of_ratings as stats_num_of_ratings, - stats.r_num_of_comments as stats_num_of_comments, - ident.id as member_id, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - and (offer.validfrom is null or offer.validfrom <= current_timestamp()) - and (offer.validto is null or offer.validto >= current_timestamp()) - ) as num_of_valid_offers, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - ) as num_of_offers - from o_repositoryentry as re - cross join o_bs_identity as ident - inner join o_repositoryentry_stats as stats on (re.fk_stats=stats.id) - left join o_mark as mark on (mark.creator_id=ident.id and re.repositoryentry_id=mark.resid and mark.resname='RepositoryEntry') - left join o_as_eff_statement as effstatement on (effstatement.fk_identity=ident.id and effstatement.fk_resource_id = re.fk_olatresource) - left join o_userrating as rating on (rating.creator_id=ident.id and re.repositoryentry_id=rating.resid and rating.resname='RepositoryEntry') - left join o_as_user_course_infos as courseinfos on (courseinfos.fk_identity=ident.id and re.fk_olatresource=courseinfos.fk_resource_id) -); - -create view o_repositoryentry_author_v as ( - select - re.repositoryentry_id as re_id, - re.creationdate as re_creationdate, - re.lastmodified as re_lastmodified, - re.displayname as re_displayname, - re.description as re_description, - re.softkey as re_softkey, - re.external_id as re_external_id, - re.external_ref as re_external_ref, - re.initialauthor as re_author, - re.authors as re_authors, - re.accesscode as re_accesscode, - re.membersonly as re_membersonly, - re.statuscode as re_statuscode, - re.fk_lifecycle as fk_lifecycle, - re.fk_olatresource as fk_olatresource, - stats.r_lastusage as re_lastusage, - mark.mark_id as mark_id, - ident.id as member_id, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - and (offer.validfrom is null or offer.validfrom <= current_timestamp) - and (offer.validto is null or offer.validto >= current_timestamp) - ) as num_of_valid_offers, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - ) as num_of_offers - from o_repositoryentry as re - cross join o_bs_identity as ident - inner join o_repositoryentry_stats as stats on (re.fk_stats=stats.id) - left join o_mark as mark on (mark.creator_id=ident.id and re.repositoryentry_id=mark.resid and mark.resname='RepositoryEntry') -); -- contacts create view o_gp_contactkey_v as ( diff --git a/src/main/resources/database/postgresql/alter_9_4_0_to_10_0_0.sql b/src/main/resources/database/postgresql/alter_9_4_0_to_10_0_0.sql index 05984aad72de606835ae3908db8ccef32b6b1307..33995bf0817db45074b106d9629fd8fa32681a29 100644 --- a/src/main/resources/database/postgresql/alter_9_4_0_to_10_0_0.sql +++ b/src/main/resources/database/postgresql/alter_9_4_0_to_10_0_0.sql @@ -289,87 +289,6 @@ create view o_as_eff_statement_groups_v as ( left join o_as_user_course_infos as pg_initial_launch on (pg_initial_launch.fk_resource_id = sg_re.fk_olatresource and pg_initial_launch.fk_identity = sg_participant.fk_identity_id) ); --- new views -create view o_repositoryentry_my_v as ( - select - re.repositoryentry_id as re_id, - re.creationdate as re_creationdate, - re.lastmodified as re_lastmodified, - re.displayname as re_displayname, - re.description as re_description, - re.authors as re_authors, - re.accesscode as re_accesscode, - re.membersonly as re_membersonly, - re.statuscode as re_statuscode, - re.fk_lifecycle as fk_lifecycle, - re.fk_olatresource as fk_olatresource, - courseinfos.initiallaunchdate as ci_initiallaunchdate, - courseinfos.recentlaunchdate as ci_recentlaunchdate, - courseinfos.visit as ci_visit, - courseinfos.timespend as ci_timespend, - effstatement.score as eff_score, - effstatement.passed as eff_passed, - mark.mark_id as mark_id, - rating.rating as rat_rating, - stats.r_rating as stats_rating, - stats.r_num_of_ratings as stats_num_of_ratings, - stats.r_num_of_comments as stats_num_of_comments, - ident.id as member_id, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - and (offer.validfrom is null or offer.validfrom <= current_timestamp) - and (offer.validto is null or offer.validto >= current_timestamp) - ) as num_of_valid_offers, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - ) as num_of_offers - from o_repositoryentry as re - cross join o_bs_identity as ident - inner join o_repositoryentry_stats as stats on (re.fk_stats=stats.id) - left join o_mark as mark on (mark.creator_id=ident.id and re.repositoryentry_id=mark.resid and mark.resname='RepositoryEntry') - left join o_as_eff_statement as effstatement on (effstatement.fk_identity=ident.id and effstatement.fk_resource_id = re.fk_olatresource) - left join o_userrating as rating on (rating.creator_id=ident.id and re.repositoryentry_id=rating.resid and rating.resname='RepositoryEntry') - left join o_as_user_course_infos as courseinfos on (courseinfos.fk_identity=ident.id and re.fk_olatresource=courseinfos.fk_resource_id) -); - -create view o_repositoryentry_author_v as ( - select - re.repositoryentry_id as re_id, - re.creationdate as re_creationdate, - re.lastmodified as re_lastmodified, - re.displayname as re_displayname, - re.description as re_description, - re.softkey as re_softkey, - re.external_id as re_external_id, - re.external_ref as re_external_ref, - re.initialauthor as re_author, - re.authors as re_authors, - re.accesscode as re_accesscode, - re.membersonly as re_membersonly, - re.statuscode as re_statuscode, - re.fk_lifecycle as fk_lifecycle, - re.fk_olatresource as fk_olatresource, - stats.r_lastusage as re_lastusage, - mark.mark_id as mark_id, - ident.id as member_id, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - and (offer.validfrom is null or offer.validfrom <= current_timestamp) - and (offer.validto is null or offer.validto >= current_timestamp) - ) as num_of_valid_offers, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - ) as num_of_offers - from o_repositoryentry as re - cross join o_bs_identity as ident - inner join o_repositoryentry_stats as stats on (re.fk_stats=stats.id) - left join o_mark as mark on (mark.creator_id=ident.id and re.repositoryentry_id=mark.resid and mark.resname='RepositoryEntry') -); - -- drop views drop view o_gp_visible_participant_v; drop view o_gp_contact_participant_v; diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql index b8eb74888aa765f7dee882c556d3d987c2989d50..fcedbafeb6ecb8719574e4060d09477d5714fe15 100644 --- a/src/main/resources/database/postgresql/setupDatabase.sql +++ b/src/main/resources/database/postgresql/setupDatabase.sql @@ -1455,50 +1455,6 @@ create or replace view o_re_membership_v as ( inner join o_re_to_group relgroup on (relgroup.fk_entry_id=re.repositoryentry_id) inner join o_bs_group_member as bmember on (bmember.fk_group_id=relgroup.fk_group_id) ); - -create view o_repositoryentry_my_v as ( - select - re.repositoryentry_id as re_id, - re.creationdate as re_creationdate, - re.lastmodified as re_lastmodified, - re.displayname as re_displayname, - re.description as re_description, - re.authors as re_authors, - re.accesscode as re_accesscode, - re.membersonly as re_membersonly, - re.statuscode as re_statuscode, - re.fk_lifecycle as fk_lifecycle, - re.fk_olatresource as fk_olatresource, - courseinfos.initiallaunchdate as ci_initiallaunchdate, - courseinfos.recentlaunchdate as ci_recentlaunchdate, - courseinfos.visit as ci_visit, - courseinfos.timespend as ci_timespend, - effstatement.score as eff_score, - effstatement.passed as eff_passed, - mark.mark_id as mark_id, - rating.rating as rat_rating, - stats.r_rating as stats_rating, - stats.r_num_of_ratings as stats_num_of_ratings, - stats.r_num_of_comments as stats_num_of_comments, - ident.id as member_id, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - and (offer.validfrom is null or offer.validfrom <= current_timestamp) - and (offer.validto is null or offer.validto >= current_timestamp) - ) as num_of_valid_offers, - (select count(offer.offer_id) from o_ac_offer as offer - where offer.fk_resource_id = re.fk_olatresource - and offer.is_valid=true - ) as num_of_offers - from o_repositoryentry as re - cross join o_bs_identity as ident - inner join o_repositoryentry_stats as stats on (re.fk_stats=stats.id) - left join o_mark as mark on (mark.creator_id=ident.id and re.repositoryentry_id=mark.resid and mark.resname='RepositoryEntry') - left join o_as_eff_statement as effstatement on (effstatement.fk_identity=ident.id and effstatement.fk_resource_id = re.fk_olatresource) - left join o_userrating as rating on (rating.creator_id=ident.id and re.repositoryentry_id=rating.resid and rating.resname='RepositoryEntry') - left join o_as_user_course_infos as courseinfos on (courseinfos.fk_identity=ident.id and re.fk_olatresource=courseinfos.fk_resource_id) -); -- contacts create view o_gp_contactkey_v as ( diff --git a/src/test/java/org/olat/repository/manager/RepositoryEntryAuthorQueriesTest.java b/src/test/java/org/olat/repository/manager/RepositoryEntryAuthorQueriesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7ce0d8898d8ace9fda0ead9adf64099f3af0c659 --- /dev/null +++ b/src/test/java/org/olat/repository/manager/RepositoryEntryAuthorQueriesTest.java @@ -0,0 +1,65 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.repository.manager; + +import java.util.List; + +import org.jcodec.common.Assert; +import org.junit.Test; +import org.olat.basesecurity.BaseSecurity; +import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; +import org.olat.core.id.Roles; +import org.olat.repository.RepositoryEntryAuthorView; +import org.olat.repository.model.SearchAuthorRepositoryEntryViewParams; +import org.olat.test.JunitTestHelper; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 04.06.2014<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RepositoryEntryAuthorQueriesTest extends OlatTestCase { + + @Autowired + private DB dbInstance; + @Autowired + private BaseSecurity securityManager; + @Autowired + private RepositoryEntryAuthorQueries repositoryEntryAuthorViewQueries; + + + @Test + public void searchViews() { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("view-"); + dbInstance.commit(); + Roles roles = securityManager.getRoles(id); + + SearchAuthorRepositoryEntryViewParams params + = new SearchAuthorRepositoryEntryViewParams(id, roles); + params.setMarked(Boolean.TRUE); + + List<RepositoryEntryAuthorView> views = repositoryEntryAuthorViewQueries.searchViews(params, 0, 10); + Assert.assertNotNull(views); + } +} diff --git a/src/test/java/org/olat/repository/manager/RepositoryEntryMyCourseQueriesTest.java b/src/test/java/org/olat/repository/manager/RepositoryEntryMyCourseQueriesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..7601316f256ff93a26d9f8f1766de7df89a7cc44 --- /dev/null +++ b/src/test/java/org/olat/repository/manager/RepositoryEntryMyCourseQueriesTest.java @@ -0,0 +1,65 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.repository.manager; + +import java.util.List; + +import org.jcodec.common.Assert; +import org.junit.Test; +import org.olat.basesecurity.BaseSecurity; +import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; +import org.olat.core.id.Roles; +import org.olat.repository.RepositoryEntryMyView; +import org.olat.repository.model.SearchMyRepositoryEntryViewParams; +import org.olat.test.JunitTestHelper; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 04.06.2014<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RepositoryEntryMyCourseQueriesTest extends OlatTestCase { + + @Autowired + private DB dbInstance; + @Autowired + private BaseSecurity securityManager; + @Autowired + private RepositoryEntryMyCourseQueries repositoryEntryMyCourseViewQueries; + + @Test + public void searchViews() { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("view-"); + dbInstance.commit(); + Roles roles = securityManager.getRoles(id); + + SearchMyRepositoryEntryViewParams params + = new SearchMyRepositoryEntryViewParams(id, roles); + params.setMarked(Boolean.TRUE); + + List<RepositoryEntryMyView> views = repositoryEntryMyCourseViewQueries.searchViews(params, 0, 10); + Assert.assertNotNull(views); + + } +} diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index 23ce7a2a9262462109ba8695aea0d2e758107d12..068bcea40c214548d3ccf654adbae862a9b4f450 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -107,6 +107,8 @@ import org.junit.runners.Suite; org.olat.repository.manager.RepositoryEntryRelationDAOTest.class,//ok org.olat.repository.manager.RepositoryServiceImplTest.class,//ok org.olat.repository.manager.RepositoryEntryStatisticsDAOTest.class,//ok + org.olat.repository.manager.RepositoryEntryAuthorQueriesTest.class,//ok + org.olat.repository.manager.RepositoryEntryMyCourseQueriesTest.class,//ok org.olat.repository.RepositoryManagerTest.class,//ok org.olat.repository.RepositoryManagerQueryTest.class,//ok org.olat.instantMessaging.InstantMessageDAOTest.class,//ok