/** * <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.course.assessment.manager; import static org.olat.core.commons.persistence.PersistenceHelper.appendAnd; import static org.olat.core.commons.persistence.PersistenceHelper.appendFuzzyLike; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashSet; import java.util.List; import javax.persistence.TemporalType; import javax.persistence.TypedQuery; import org.olat.basesecurity.GroupRoles; import org.olat.basesecurity.IdentityRef; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.PersistenceHelper; import org.olat.core.util.StringHelper; import org.olat.course.assessment.AssessmentMode; import org.olat.course.assessment.AssessmentMode.Status; import org.olat.course.assessment.model.AssessmentModeImpl; import org.olat.course.assessment.model.SearchAssessmentModeParams; import org.olat.course.nodes.CourseNode; import org.olat.group.BusinessGroupRef; import org.olat.group.area.BGtoAreaRelationImpl; import org.olat.repository.RepositoryEntryRef; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * * Initial date: 20.04.2015<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ @Service public class AssessmentModeDAO { @Autowired private DB dbInstance; public AssessmentMode getAssessmentModeById(Long key) { List<AssessmentMode> modes = dbInstance.getCurrentEntityManager() .createNamedQuery("assessmentModeById", AssessmentMode.class) .setParameter("modeKey", key) .getResultList(); return modes == null || modes.isEmpty() ? null : modes.get(0); } public List<AssessmentMode> findAssessmentMode(SearchAssessmentModeParams params) { StringBuilder sb = new StringBuilder(); sb.append("select mode from courseassessmentmode mode") .append(" inner join fetch mode.repositoryEntry v") .append(" inner join fetch v.olatResource res"); boolean where = false; Date date = params.getDate(); if(date != null) { where = appendAnd(sb, where); sb.append(":date between mode.beginWithLeadTime and mode.endWithFollowupTime"); } String name = params.getName(); if(StringHelper.containsNonWhitespace(name)) { name = PersistenceHelper.makeFuzzyQueryString(name); where = appendAnd(sb, where); sb.append("("); appendFuzzyLike(sb, "v.displayname", "name", dbInstance.getDbVendor()); sb.append(" or "); appendFuzzyLike(sb, "mode.name", "name", dbInstance.getDbVendor()); sb.append(")"); } Long id = null; String refs = null; String fuzzyRefs = null; if(StringHelper.containsNonWhitespace(params.getIdAndRefs())) { refs = params.getIdAndRefs(); fuzzyRefs = PersistenceHelper.makeFuzzyQueryString(refs); where = appendAnd(sb, where); sb.append(" (v.externalId=:ref or "); PersistenceHelper.appendFuzzyLike(sb, "v.externalRef", "fuzzyRefs", dbInstance.getDbVendor()); sb.append(" or v.softkey=:ref"); if(StringHelper.isLong(refs)) { try { id = Long.parseLong(refs); sb.append(" or v.key=:vKey or res.resId=:vKey"); } catch (NumberFormatException e) { // } } sb.append(")"); } sb.append(" order by mode.beginWithLeadTime desc "); TypedQuery<AssessmentMode> query = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), AssessmentMode.class); if(StringHelper.containsNonWhitespace(params.getName())) { query.setParameter("name", name); } if(id != null) { query.setParameter("vKey", id); } if(refs != null) { query.setParameter("ref", refs); } if(fuzzyRefs != null) { query.setParameter("fuzzyRefs", fuzzyRefs); } if(date != null) { query.setParameter("date", date, TemporalType.TIMESTAMP); } return query.getResultList(); } public List<AssessmentMode> getAssessmentModeFor(RepositoryEntryRef entry) { return dbInstance.getCurrentEntityManager() .createNamedQuery("assessmentModeByRepoEntry", AssessmentMode.class) .setParameter("entryKey", entry.getKey()) .getResultList(); } public List<AssessmentMode> getAssessmentModes(Date now) { Calendar cal = Calendar.getInstance(); cal.set(Calendar.MILLISECOND, 0); cal.set(Calendar.SECOND, 0); StringBuilder sb = new StringBuilder(); sb.append("select mode from courseassessmentmode mode where ") .append(" (mode.beginWithLeadTime<=:now and mode.endWithFollowupTime>=:now and mode.manualBeginEnd=false)") .append(" or mode.statusString in ('").append(Status.leadtime.name()).append("','") .append(Status.assessment.name()).append("','").append(Status.followup.name()).append("')"); return dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), AssessmentMode.class) .setParameter("now", now) .getResultList(); } public boolean isInAssessmentMode(RepositoryEntryRef entry, Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.set(Calendar.MILLISECOND, 0); cal.set(Calendar.SECOND, 0); StringBuilder sb = new StringBuilder(); sb.append("select count(mode) from courseassessmentmode mode where ") .append(" mode.repositoryEntry.key=:repoKey and (") .append(" (mode.beginWithLeadTime<=:now and mode.endWithFollowupTime>=:now and mode.manualBeginEnd=false)") .append(" or mode.statusString in ('").append(Status.leadtime.name()).append("','") .append(Status.assessment.name()).append("','").append(Status.followup.name()).append("'))"); List<Number> count = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), Number.class) .setParameter("now", date) .setParameter("repoKey", entry.getKey()) .getResultList(); return count != null && count.size() > 0 && count.get(0).intValue() > 0; } protected List<AssessmentMode> loadAssessmentModeFor(IdentityRef identity, List<AssessmentMode> currentModes) { StringBuilder sb = new StringBuilder(1500); sb.append("select mode from courseassessmentmode mode ") .append(" inner join fetch mode.repositoryEntry entry") .append(" left join mode.groups as modeToGroup") .append(" left join mode.areas as modeToArea") .append(" where mode.key in (:modeKeys)") .append(" and ((mode.targetAudienceString in ('").append(AssessmentMode.Target.courseAndGroups.name()).append("','").append(AssessmentMode.Target.groups.name()).append("')") .append(" and (exists (select businessGroup from businessgroup as businessGroup, bgroupmember as membership") .append(" where modeToGroup.businessGroup.key=businessGroup.key and membership.group.key=businessGroup.baseGroup.key and membership.identity.key=:identityKey") .append(" and (membership.role='").append(GroupRoles.participant.name()).append("' or ") .append(" (mode.applySettingsForCoach=true and membership.role='").append(GroupRoles.coach.name()).append("'))") .append(" ) or exists (select areaToGroup from ").append(BGtoAreaRelationImpl.class.getName()).append(" as areaToGroup,businessgroup as businessGroupArea, bgroupmember as membership") .append(" where modeToArea.area=areaToGroup.groupArea and areaToGroup.businessGroup=businessGroupArea and membership.group=businessGroupArea.baseGroup and membership.identity.key=:identityKey") .append(" and (membership.role='").append(GroupRoles.participant.name()).append("' or ") .append(" (mode.applySettingsForCoach=true and membership.role='").append(GroupRoles.coach.name()).append("'))") .append(" ))) or (mode.targetAudienceString in ('").append(AssessmentMode.Target.courseAndGroups.name()).append("','").append(AssessmentMode.Target.course.name()).append("')") .append(" and exists (select rel from repoentrytogroup as rel, bgroupmember as membership ") .append(" where mode.repositoryEntry.key=rel.entry.key and membership.group.key=rel.group.key and rel.defaultGroup=true and membership.identity.key=:identityKey") .append(" and (membership.role='").append(GroupRoles.participant.name()).append("' or ") .append(" (mode.applySettingsForCoach=true and membership.role='").append(GroupRoles.coach.name()).append("'))") .append(" ))") .append(" )"); List<Long> modeKeys = new ArrayList<>(currentModes.size()); for(AssessmentMode mode:currentModes) { modeKeys.add(mode.getKey()); } List<AssessmentMode> modeList = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), AssessmentMode.class) .setParameter("identityKey", identity.getKey()) .setParameter("modeKeys", modeKeys) .getResultList(); //quicker than distinct return new ArrayList<AssessmentMode>(new HashSet<AssessmentMode>(modeList)); } public boolean isNodeInUse(RepositoryEntryRef entry, CourseNode node) { if(entry == null || node == null) return false; StringBuilder sb = new StringBuilder(); sb.append("select count(mode) from courseassessmentmode mode where ") .append(" mode.repositoryEntry.key=:repoKey ") .append(" and (mode.startElement=:startIdent or mode.elementList like :nodeIdent)") .append(" and (mode.beginWithLeadTime>=:now") .append(" or mode.statusString in ('").append(Status.none.name()).append("','").append(Status.leadtime.name()).append("','").append(Status.assessment.name()).append("','").append(Status.followup.name()).append("'))"); Calendar cal = Calendar.getInstance(); cal.set(Calendar.MILLISECOND, 0); cal.set(Calendar.SECOND, 0); List<Number> count = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), Number.class) .setParameter("repoKey", entry.getKey()) .setParameter("startIdent", node.getIdent()) .setParameter("nodeIdent", "%" + node.getIdent() + "%") .setParameter("now", cal.getTime(), TemporalType.TIMESTAMP) .getResultList(); return count != null && count.size() > 0 && count.get(0).intValue() > 0; } public void delete(AssessmentMode assessmentMode) { AssessmentModeImpl refMode = dbInstance.getCurrentEntityManager() .getReference(AssessmentModeImpl.class, assessmentMode.getKey()); dbInstance.getCurrentEntityManager().remove(refMode); } /** * Delete all assessment modes of a course. * * @param entry The course */ public void delete(RepositoryEntryRef entry) { for(AssessmentMode mode: getAssessmentModeFor(entry)) { delete(mode); } } public void deleteAssessmentModesToGroup(BusinessGroupRef businessGroup) { String q = "delete from courseassessmentmodetogroup as modegrrel where modegrrel.businessGroup.key=:groupKey"; dbInstance.getCurrentEntityManager().createQuery(q) .setParameter("groupKey", businessGroup.getKey()) .executeUpdate(); } /** * Delete the relations between assessment mode and group for the specified business group and course. * @param businessGroup * @param entry */ public void delete(BusinessGroupRef businessGroup, RepositoryEntryRef entry) { String q = "delete from courseassessmentmodetogroup as modegrrel where modegrrel.businessGroup.key=:groupKey and modegrrel.assessmentMode.key in (select amode.key from courseassessmentmode amode where amode.repositoryEntry.key=:repoKey)"; dbInstance.getCurrentEntityManager().createQuery(q) .setParameter("groupKey", businessGroup.getKey()) .setParameter("repoKey", entry.getKey()) .executeUpdate(); } }