/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/edu-services/trunk/cm-service/cm-impl/hibernate-impl/impl/src/java/org/sakaiproject/coursemanagement/impl/CourseManagementServiceHibernateImpl.java $ * $Id: CourseManagementServiceHibernateImpl.java 123501 2013-05-01 22:46:45Z matthew@longsight.com $ *********************************************************************************** * * Copyright (c) 2006, 2007, 2008 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaiproject.coursemanagement.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import org.hibernate.Hibernate; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.criterion.DetachedCriteria; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.coursemanagement.api.AcademicSession; import org.sakaiproject.coursemanagement.api.CanonicalCourse; import org.sakaiproject.coursemanagement.api.CourseManagementService; import org.sakaiproject.coursemanagement.api.CourseOffering; import org.sakaiproject.coursemanagement.api.CourseSet; import org.sakaiproject.coursemanagement.api.Enrollment; import org.sakaiproject.coursemanagement.api.EnrollmentSet; import org.sakaiproject.coursemanagement.api.Membership; import org.sakaiproject.coursemanagement.api.Section; import org.sakaiproject.coursemanagement.api.SectionCategory; import org.sakaiproject.coursemanagement.api.exception.IdNotFoundException; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; /** * Provides access to course and enrollment data stored in sakai's local hibernate tables. * * @author <a href="mailto:jholtzman@berkeley.edu">Josh Holtzman</a> * */ public class CourseManagementServiceHibernateImpl extends HibernateDaoSupport implements CourseManagementService { private static final Log log = LogFactory.getLog(CourseManagementServiceHibernateImpl.class); public void init() { log.info("Initializing " + getClass().getName()); } public void destroy() { log.info("Destroying " + getClass().getName()); } /** * A generic approach to finding objects by their eid. This is "coding by convention", * since it expects the parameterized query to use "eid" as the single named parameter. * * @param eid The eid of the object we're trying to load * @param className The name of the class / interface we're looking for * @return The object, if found * @throws IdNotFoundException */ private Object getObjectByEid(final String eid, final String className) throws IdNotFoundException { HibernateCallback hc = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { StringBuilder hql = new StringBuilder(); hql.append("from ").append(className).append(" as obj where obj.eid=:eid"); Query q = session.createQuery(hql.toString()); q.setParameter("eid", eid); Object result = q.uniqueResult(); if(result == null) { throw new IdNotFoundException(eid, className); } return result; } }; return getHibernateTemplate().execute(hc); } public CourseSet getCourseSet(String eid) throws IdNotFoundException { return (CourseSet)getObjectByEid(eid, CourseSetCmImpl.class.getName()); } public Set<CourseSet> getChildCourseSets(final String parentCourseSetEid) throws IdNotFoundException { // Ensure that the parent exists if(!isCourseSetDefined(parentCourseSetEid)) { throw new IdNotFoundException(parentCourseSetEid, CourseSetCmImpl.class.getName()); } return new HashSet<CourseSet>(getHibernateTemplate().findByNamedQueryAndNamedParam( "findChildCourseSets", "parentEid", parentCourseSetEid)); } public Set<CourseSet> getCourseSets() { return new HashSet<CourseSet>(getHibernateTemplate().findByNamedQuery("findTopLevelCourseSets")); } public Set<Membership> getCourseSetMemberships(String courseSetEid) throws IdNotFoundException { return getMemberships((AbstractMembershipContainerCmImpl)getCourseSet(courseSetEid)); } public CanonicalCourse getCanonicalCourse(String eid) throws IdNotFoundException { return (CanonicalCourse)getObjectByEid(eid, CanonicalCourseCmImpl.class.getName()); } public Set<CanonicalCourse> getEquivalentCanonicalCourses(String canonicalCourseEid) { final CanonicalCourseCmImpl canonicalCourse = (CanonicalCourseCmImpl)getCanonicalCourse(canonicalCourseEid); HibernateCallback hc = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query q = session.getNamedQuery("findEquivalentCanonicalCourses"); q.setParameter("crossListing", canonicalCourse.getCrossListing()); q.setParameter("canonicalCourse", canonicalCourse); return q.list(); } }; return new HashSet<CanonicalCourse>(getHibernateTemplate().executeFind(hc)); } public Set<CanonicalCourse> getCanonicalCourses(final String courseSetEid) throws IdNotFoundException { return ((CourseSetCmImpl)getCourseSet(courseSetEid)).getCanonicalCourses(); } public List <AcademicSession> getAcademicSessions() { return (List <AcademicSession>) getHibernateTemplate().execute(new HibernateCallback() { @Override public List <AcademicSession> doInHibernate(Session session) { Query query = session.getNamedQuery("findAcademicSessions"); query.setCacheable(true); return query.list(); } }); } public List <AcademicSession> getCurrentAcademicSessions() { return (List <AcademicSession>) getHibernateTemplate().execute(new HibernateCallback() { @Override public List <AcademicSession> doInHibernate(Session session) { Query query = session.getNamedQuery("findCurrentAcademicSessions"); query.setCacheable(true); return query.list(); } }); } public AcademicSession getAcademicSession(final String eid) throws IdNotFoundException { return (AcademicSession)getObjectByEid(eid, AcademicSessionCmImpl.class.getName()); } public CourseOffering getCourseOffering(String eid) throws IdNotFoundException { return (CourseOffering)getObjectByEid(eid, CourseOfferingCmImpl.class.getName()); } public Set<CourseOffering> getCourseOfferingsInCourseSet(final String courseSetEid) throws IdNotFoundException { if( ! isCourseSetDefined(courseSetEid)) { throw new IdNotFoundException(courseSetEid, CourseOfferingCmImpl.class.getName()); } return ((CourseSetCmImpl)getCourseSet(courseSetEid)).getCourseOfferings(); } public Set<CourseOffering> getEquivalentCourseOfferings(String courseOfferingEid) throws IdNotFoundException { final CourseOfferingCmImpl courseOffering = (CourseOfferingCmImpl)getCourseOffering(courseOfferingEid); HibernateCallback hc = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query q = session.getNamedQuery("findEquivalentCourseOfferings"); q.setParameter("crossListing", courseOffering.getCrossListing()); q.setParameter("courseOffering", courseOffering); return q.list(); } }; return new HashSet<CourseOffering>(getHibernateTemplate().executeFind(hc)); } public Set<Membership> getCourseOfferingMemberships(String courseOfferingEid) throws IdNotFoundException { return getMemberships((AbstractMembershipContainerCmImpl)getCourseOffering(courseOfferingEid)); } /** * Gets the memberships for a membership container. This query can not be * performed using just the container's eid, since it may conflict with other kinds * of objects with the same eid. * * @param container * @return */ private Set<Membership> getMemberships(final AbstractMembershipContainerCmImpl container) { // This may be a dynamic proxy. In that case, make sure we're using the class // that hibernate understands. final String className = Hibernate.getClass(container).getName(); HibernateCallback hc = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { StringBuilder sb = new StringBuilder("select mbr from MembershipCmImpl as mbr, "); sb.append(className); sb.append(" as container where mbr.memberContainer=container "); sb.append("and container.eid=:eid"); Query q = session.createQuery(sb.toString()); q.setParameter("eid", container.getEid()); return q.list(); } }; return new HashSet<Membership>(getHibernateTemplate().executeFind(hc)); } public Section getSection(String eid) throws IdNotFoundException { return (Section)getObjectByEid(eid, SectionCmImpl.class.getName()); } public Set<Section> getSections(String courseOfferingEid) throws IdNotFoundException { CourseOffering courseOffering = getCourseOffering(courseOfferingEid); return new HashSet<Section>(getHibernateTemplate().findByNamedQueryAndNamedParam( "findTopLevelSectionsInCourseOffering", "courseOffering", courseOffering)); } public Set<Section> getChildSections(final String parentSectionEid) throws IdNotFoundException { if( ! isSectionDefined(parentSectionEid)) { throw new IdNotFoundException(parentSectionEid, SectionCmImpl.class.getName()); } return new HashSet<Section>(getHibernateTemplate().findByNamedQueryAndNamedParam( "findChildSections", "parentEid", parentSectionEid)); } public Set<Membership> getSectionMemberships(String sectionEid) throws IdNotFoundException { return getMemberships((AbstractMembershipContainerCmImpl)getSection(sectionEid)); } public EnrollmentSet getEnrollmentSet(String eid) throws IdNotFoundException { return (EnrollmentSet)getObjectByEid(eid, EnrollmentSetCmImpl.class.getName()); } public Set<EnrollmentSet> getEnrollmentSets(final String courseOfferingEid) throws IdNotFoundException { if(! isCourseOfferingDefined(courseOfferingEid)) { throw new IdNotFoundException(courseOfferingEid, CourseOfferingCmImpl.class.getName()); } return new HashSet<EnrollmentSet>(getHibernateTemplate().findByNamedQueryAndNamedParam( "findEnrollmentSetsByCourseOffering", "courseOfferingEid", courseOfferingEid)); } public Set<Enrollment> getEnrollments(final String enrollmentSetEid) throws IdNotFoundException { if( ! isEnrollmentSetDefined(enrollmentSetEid)) { throw new IdNotFoundException(enrollmentSetEid, EnrollmentSetCmImpl.class.getName()); } return new HashSet<Enrollment>(getHibernateTemplate().findByNamedQueryAndNamedParam( "findEnrollments", "enrollmentSetEid", enrollmentSetEid)); } public boolean isEnrolled(final String userId, final Set<String> enrollmentSetEids) { HibernateCallback hc = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query q = session.getNamedQuery("countEnrollments"); q.setParameter("userId", userId); q.setParameterList("enrollmentSetEids", enrollmentSetEids); return q.iterate().next(); } }; int i = ((Number)getHibernateTemplate().execute(hc)).intValue(); if(log.isDebugEnabled()) log.debug(userId + " is enrolled in " + i + " of these " + enrollmentSetEids.size() + " EnrollmentSets" ); return i > 0; } public boolean isEnrolled(String userId, String enrollmentSetEid) { HashSet<String> enrollmentSetEids = new HashSet<String>(); enrollmentSetEids.add(enrollmentSetEid); return isEnrolled(userId, enrollmentSetEids); } public Enrollment findEnrollment(final String userId, final String enrollmentSetEid) { if( ! isEnrollmentSetDefined(enrollmentSetEid)) { log.warn("Could not find an enrollment set with eid=" + enrollmentSetEid); return null; } HibernateCallback hc = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query q = session.getNamedQuery("findEnrollment"); q.setParameter("userId", userId); q.setParameter("enrollmentSetEid", enrollmentSetEid); return q.uniqueResult(); } }; return (Enrollment)getHibernateTemplate().execute(hc); } public Set<String> getInstructorsOfRecordIds(String enrollmentSetEid) throws IdNotFoundException { EnrollmentSet es = getEnrollmentSet(enrollmentSetEid); return es.getOfficialInstructors(); } public Set<EnrollmentSet> findCurrentlyEnrolledEnrollmentSets(final String userId) { return new HashSet<EnrollmentSet>(getHibernateTemplate().findByNamedQueryAndNamedParam("findCurrentlyEnrolledEnrollmentSets", "userId", userId)); } public Set<EnrollmentSet> findCurrentlyInstructingEnrollmentSets(final String userId) { return new HashSet<EnrollmentSet>(getHibernateTemplate().findByNamedQueryAndNamedParam( "findCurrentlyInstructingEnrollmentSets", "userId", userId)); } public Set<Section> findInstructingSections(final String userId) { return new HashSet<Section>(getHibernateTemplate().findByNamedQueryAndNamedParam( "findInstructingSections", "userId", userId)); } public Set<Section> findEnrolledSections(final String userId) { return new HashSet<Section>(getHibernateTemplate().findByNamedQueryAndNamedParam( "findEnrolledSections", "userId", userId)); } public List<CourseOffering> findActiveCourseOfferingsInCanonicalCourse( String eid) { log.debug("findActiveCourseOfferingsInCanonicalCourse(eid"); /** * select * from CM_MEMBER_CONTAINER_T where start_date <= now() and end_date>=now() and class_discr='org.sakaiproject.coursemanagement.impl.CourseOfferingCmImpl' and canonical_course in (select MEMBER_CONTAINER_ID from CM_MEMBER_CONTAINER_T where enterprise_id= ? and CLASS_DISCR='org.sakaiproject.coursemanagement.impl.CanonicalCourseCmImpl'); */ CanonicalCourse canonicalCourse = null; try { canonicalCourse = this.getCanonicalCourse(eid); } catch (IdNotFoundException e) { //its quite possible someone ask for a course that doesn't exits return new ArrayList<CourseOffering>(); } List<CourseOffering> ret = new ArrayList<CourseOffering>(getHibernateTemplate().findByNamedQueryAndNamedParam("findActiveCourseOfferingsInCanonicalCourse", "canonicalCourse", canonicalCourse)); return ret; } public Set<Section> findInstructingSections(final String userId, final String academicSessionEid) { HibernateCallback hc = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query q = session.getNamedQuery("findInstructingSectionsByAcademicSession"); q.setParameter("userId", userId); q.setParameter("academicSessionEid", academicSessionEid); return q.list(); } }; return new HashSet<Section>(getHibernateTemplate().executeFind(hc)); } public Set<CourseOffering> findCourseOfferings(final String courseSetEid, final String academicSessionEid) throws IdNotFoundException { HibernateCallback hc = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query q = session.getNamedQuery("findCourseOfferingsByCourseSetAndAcademicSession"); q.setParameter("courseSetEid", courseSetEid); q.setParameter("academicSessionEid", academicSessionEid); return q.list(); } }; return new HashSet<CourseOffering>(getHibernateTemplate().executeFind(hc)); } public boolean isEmpty(final String courseSetEid) { HibernateCallback hc = new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query q = session.getNamedQuery("findNonEmptyCourseSet"); q.setParameter("eid", courseSetEid); return Boolean.valueOf( ! q.iterate().hasNext()); } }; return ((Boolean)getHibernateTemplate().execute(hc)).booleanValue(); } public List<CourseSet> findCourseSets(final String category) { return getHibernateTemplate().findByNamedQueryAndNamedParam( "findCourseSetByCategory", "category", category); } public Map<String, String> findCourseOfferingRoles(final String userEid) { // Keep track of CourseOfferings that we've already queried Set<String> queriedCourseOfferingEids = new HashSet<String>(); List results = getHibernateTemplate().findByNamedQueryAndNamedParam( "findCourseOfferingRoles", "userEid", userEid); Map<String, String> courseOfferingRoleMap = new HashMap<String, String>(); for(Iterator iter = results.iterator(); iter.hasNext();) { Object[] oa = (Object[])iter.next(); courseOfferingRoleMap.put((String)oa[0], (String)oa[1]); queriedCourseOfferingEids.add((String)oa[0]); } return courseOfferingRoleMap; } public Map<String, String> findCourseSetRoles(final String userEid) { List results = getHibernateTemplate().findByNamedQueryAndNamedParam( "findCourseSetRoles", "userEid", userEid); Map<String, String> courseSetRoleMap = new HashMap<String, String>(); for(Iterator iter = results.iterator(); iter.hasNext();) { Object[] oa = (Object[])iter.next(); courseSetRoleMap.put((String)oa[0], (String)oa[1]); } return courseSetRoleMap; } public Map<String, String> findSectionRoles(final String userEid) { List results = getHibernateTemplate().findByNamedQueryAndNamedParam( "findSectionRoles", "userEid", userEid); Map<String, String> sectionRoleMap = new HashMap<String, String>(); for(Iterator iter = results.iterator(); iter.hasNext();) { Object[] oa = (Object[])iter.next(); sectionRoleMap.put((String)oa[0], (String)oa[1]); } return sectionRoleMap; } public Set<CourseOffering> getCourseOfferingsInCanonicalCourse(final String canonicalCourseEid) throws IdNotFoundException { if(!isCanonicalCourseDefined(canonicalCourseEid)) { throw new IdNotFoundException(canonicalCourseEid, CanonicalCourseCmImpl.class.getName()); } return new HashSet<CourseOffering>(getHibernateTemplate().findByNamedQueryAndNamedParam("findCourseOfferingsByCanonicalCourse", "canonicalCourseEid", canonicalCourseEid)); } public boolean isAcademicSessionDefined(String eid) { return ((Number)getHibernateTemplate().findByNamedQueryAndNamedParam("isAcademicSessionDefined", "eid", eid).get(0)).intValue() == 1; } public boolean isCanonicalCourseDefined(String eid) { return ((Number)getHibernateTemplate().findByNamedQueryAndNamedParam("isCanonicalCourseDefined", "eid", eid).get(0)).intValue() == 1; } public boolean isCourseOfferingDefined(String eid) { return ((Number)getHibernateTemplate().findByNamedQueryAndNamedParam("isCourseOfferingDefined", "eid", eid).get(0)).intValue() == 1; } public boolean isCourseSetDefined(String eid) { return ((Number)getHibernateTemplate().findByNamedQueryAndNamedParam("isCourseSetDefined", "eid", eid).get(0)).intValue() == 1; } public boolean isEnrollmentSetDefined(String eid) { return ((Number)getHibernateTemplate().findByNamedQueryAndNamedParam("isEnrollmentSetDefined", "eid", eid).get(0)).intValue() == 1; } public boolean isSectionDefined(String eid) { return ((Number)getHibernateTemplate().findByNamedQueryAndNamedParam("isSectionDefined", "eid", eid).get(0)).intValue() == 1; } public List<String> getSectionCategories() { return getHibernateTemplate().findByNamedQuery("findSectionCategories"); } public String getSectionCategoryDescription(String categoryCode) { if(categoryCode == null) { return null; } SectionCategory cat = (SectionCategory)getHibernateTemplate().get(SectionCategoryCmImpl.class, categoryCode); if(cat == null) { return null; } else { return cat.getCategoryDescription(); } } public Map<String, String> getEnrollmentStatusDescriptions(Locale locale) { Map<String, String> map = new HashMap<String, String>(); map.put("enrolled", "Enrolled"); map.put("wait", "Waitlisted"); return map; } public Map<String, String> getGradingSchemeDescriptions(Locale locale) { Map<String, String> map = new HashMap<String, String>(); map.put("standard", "Letter Grades"); map.put("pnp", "Pass / Not Pass"); return map; } public Map<String, String> getMembershipStatusDescriptions(Locale locale) { Map<String, String> map = new HashMap<String, String>(); map.put("member", "Member"); map.put("guest", "Guest"); return map; } }