Package org.olat.course.nodes.en

Source Code of org.olat.course.nodes.en.EnrollmentManager

/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <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>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <p>
*/

package org.olat.course.nodes.en;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.olat.basesecurity.Manager;
import org.olat.basesecurity.ManagerFactory;
import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.translator.Translator;
import org.olat.core.id.Identity;
import org.olat.core.logging.Tracing;
import org.olat.core.logging.activity.IUserActivityLogger;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.coordinate.SyncerExecutor;
import org.olat.core.util.mail.MailHelper;
import org.olat.core.util.mail.MailTemplate;
import org.olat.core.util.mail.MailerResult;
import org.olat.core.util.mail.MailerWithTemplate;
import org.olat.core.util.resource.OresHelper;
import org.olat.course.groupsandrights.CourseGroupManager;
import org.olat.course.nodes.ENCourseNode;
import org.olat.course.properties.CoursePropertyManager;
import org.olat.group.BusinessGroup;
import org.olat.group.BusinessGroupManager;
import org.olat.group.BusinessGroupManagerImpl;
import org.olat.group.ui.BGConfigFlags;
import org.olat.group.ui.BGMailHelper;
import org.olat.properties.Property;
import org.olat.resource.lock.pessimistic.PessimisticLockManager;
import org.olat.testutils.codepoints.server.Codepoint;

/**
* Description:<BR>
* Business-logic of enrollemnt
* <p>
* Handle enroll and cancel-enrollment
* <P>
* Initial Date: Nov 11, 2006
*
* @author Christian Guretzki
*/
public class EnrollmentManager {
  // my Instance
  static final EnrollmentManager enrollmentManager = new EnrollmentManager();
  // Managers
  private Manager securityManager;
  private BusinessGroupManager businessGroupManager;

  /**
   * @param moduleConfiguration
   * @param ureq
   * @param wControl
   * @param userCourseEnv
   * @param enNode
   */
  private EnrollmentManager() {
    this.securityManager = ManagerFactory.getManager();
    this.businessGroupManager = BusinessGroupManagerImpl.getInstance();
  }

  public static EnrollmentManager getInstance() {
    return enrollmentManager;
  }

  public EnrollStatus doEnroll(final Identity identity, final BusinessGroup group, final ENCourseNode enNode, final CoursePropertyManager coursePropertyManager,
      final WindowControl wControl, final Translator trans, List groupNames, List areaNames, CourseGroupManager cgm) {
    final EnrollStatus enrollStatus = new EnrollStatus();
    if (Tracing.isDebugEnabled(this.getClass())) Tracing.logDebug("doEnroll", this.getClass());
    // check if the user is already enrolled (user can be enrooled only in one group)
    if ( ( getBusinessGroupWhereEnrolled( identity, groupNames, areaNames, cgm) == null)
        && ( getBusinessGroupWhereInWaitingList( identity, groupNames, areaNames, cgm) == null) ) {
      if (Tracing.isDebugEnabled(this.getClass())) Tracing.logDebug("Identity is not enrolled identity=" + identity.getName() + "  group=" + group.getName() , this.getClass());
      // 1. Check if group has max size defined. If so check if group is full
      // o_clusterREVIEW cg please review it - also where does the group.getMaxParticipants().equals("") come from??
      // and: why can't we just have a group here and a max participants count and an identity to enrol?
      // the group was chosen, so why do we need the groupNames and areaNames here???

      Codepoint.codepoint(EnrollmentManager.class, "beforeDoInSync");
      CoordinatorManager.getCoordinator().getSyncer().doInSync(group, new SyncerExecutor(){
        public void execute() {
          Tracing.logInfo("doEnroll start: group="+OresHelper.createStringRepresenting(group), identity.getName(), EnrollmentManager.class);
          Codepoint.codepoint(EnrollmentManager.class, "doInSync1");
          // 6_1_0-RC15: reload group object here another node might have changed this in the meantime
          BusinessGroup reloadedGroup = (BusinessGroup) DBFactory.getInstance().loadObject(group, true);         
          if (reloadedGroup.getMaxParticipants() != null && !reloadedGroup.getMaxParticipants().equals("")) {
            int participantsCounter = securityManager.countIdentitiesOfSecurityGroup(reloadedGroup.getPartipiciantGroup());
           
            Tracing.logInfo("doEnroll - participantsCounter: " + participantsCounter + ", maxParticipants: " + reloadedGroup.getMaxParticipants().intValue(), identity.getName(), EnrollmentManager.class);
            if (participantsCounter >= reloadedGroup.getMaxParticipants().intValue()) {
              // already full, show error and updated choose page again
              if (!reloadedGroup.getWaitingListEnabled().booleanValue()) {
                // No Waiting List => List is full
                enrollStatus.setErrorMessage(trans.translate("error.group.full"));
              } else {
                boolean done = addUserToWaitingList(identity, reloadedGroup, enNode, coursePropertyManager, wControl, trans);
                enrollStatus.setIsInWaitingList(done);
              }
            } else {
              boolean done = addUserToParticipantList(identity, reloadedGroup, enNode, coursePropertyManager, wControl, trans);
              Codepoint.codepoint(EnrollmentManager.class, "doInSync2");
              enrollStatus.setIsEnrolled(done);
              Tracing.logInfo("doEnroll - setIsEnrolled ", identity.getName(), EnrollmentManager.class);
            }
          } else {
            if (Tracing.isDebugEnabled(this.getClass())) Tracing.logDebug("doEnroll beginTransaction", this.getClass());
            boolean done = addUserToParticipantList(identity, reloadedGroup, enNode, coursePropertyManager, wControl, trans);
            enrollStatus.setIsEnrolled(done);           
            if (Tracing.isDebugEnabled(this.getClass())) Tracing.logDebug("doEnroll committed", this.getClass());
          }
          Tracing.logInfo("doEnroll end", identity.getName(), EnrollmentManager.class);
        }       
      });// end of doInSync
      Codepoint.codepoint(EnrollmentManager.class, "afterDoInSync");
    } else {
      enrollStatus.setErrorMessage(trans.translate("error.group.already.enrolled"));
    }
    if (Tracing.isDebugEnabled(this.getClass())) Tracing.logDebug("doEnroll finished", this.getClass());
    return enrollStatus;
  }

  public void doCancelEnrollment(final Identity identity, final BusinessGroup enrolledGroup, final ENCourseNode enNode,
      final CoursePropertyManager coursePropertyManager, WindowControl wControl, Translator trans) {
    if (Tracing.isDebugEnabled(this.getClass())) Tracing.logDebug("doCancelEnrollment", this.getClass());
    // 1. Remove group membership, fire events, do loggin etc.
    final BGConfigFlags flags = BGConfigFlags.createLearningGroupDefaultFlags();
   
    CoordinatorManager.getCoordinator().getSyncer().doInSync(enrolledGroup, new SyncerExecutor(){
      public void execute() {
        // Remove participant. This will also check if a waiting-list with auto-close-ranks is configurated
        // and move the users accordingly
        businessGroupManager.removeParticipantAndFireEvent(identity, identity, enrolledGroup, flags, false);
        Tracing.logInfo("doCancelEnrollment in group " + enrolledGroup, identity.getName() , EnrollmentManager.class);
        // 2. Remove enrollmentdate property
        // only remove last time date, not firsttime
        Property lastTime = coursePropertyManager
        .findCourseNodeProperty(enNode, identity, null, ENCourseNode.PROPERTY_RECENT_ENROLLMENT_DATE);
        if (lastTime != null) {
          coursePropertyManager.deleteProperty(lastTime);
        }
      }});
   

    // 3. Send notification mail
    MailTemplate mailTemplate = BGMailHelper.createRemoveMyselfMailTemplate(enrolledGroup, identity);
    MailerWithTemplate mailer = MailerWithTemplate.getInstance();
    MailerResult mailerResult = mailer.sendMail(identity, null, null, mailTemplate, null);
    MailHelper.printErrorsAndWarnings(mailerResult, wControl, trans.getLocale());
  }

  public void doCancelEnrollmentInWaitingList(final Identity identity, final BusinessGroup enrolledWaitingListGroup, final ENCourseNode enNode,
      final CoursePropertyManager coursePropertyManager, WindowControl wControl, Translator trans) {
    // 1. Remove group membership, fire events, do loggin etc.
    CoordinatorManager.getCoordinator().getSyncer().doInSync(enrolledWaitingListGroup, new SyncerExecutor(){
      public void execute() {
        businessGroupManager.removeFromWaitingListAndFireEvent(identity, identity, enrolledWaitingListGroup, false);
        // 2. Remove enrollmentdate property
        // only remove last time date, not firsttime
        Property lastTime = coursePropertyManager.findCourseNodeProperty(enNode, identity, null,
            ENCourseNode.PROPERTY_RECENT_WAITINGLIST_DATE);
        if (lastTime != null) {
          coursePropertyManager.deleteProperty(lastTime);
        }
      }});
   

    // 3. Send notification mail
    MailTemplate mailTemplate = BGMailHelper.createRemoveWaitinglistMailTemplate(enrolledWaitingListGroup, identity);
    MailerWithTemplate mailer = MailerWithTemplate.getInstance();
    MailerResult mailerResult = mailer.sendMail(identity, null, null, mailTemplate, null);
    MailHelper.printErrorsAndWarnings(mailerResult, wControl, trans.getLocale());
  }

  // Helper Methods
  // ////////////////
  /**
   * @param identity
   * @param groupNames
   * @return BusinessGroup in which the identity is enrolled, null if identity
   *         is nowhere enrolled.
   */
  protected BusinessGroup getBusinessGroupWhereEnrolled(Identity identity, List groupNames, List areaNames, CourseGroupManager cgm) {
    Iterator iterator = groupNames.iterator();
    // 1. check in groups
    while (iterator.hasNext()) {
      String groupName = (String) iterator.next();
      List groups = cgm.getParticipatingLearningGroupsFromAllContexts(identity, groupName);
      if (groups.size() > 0) {
        // Usually it is only possible to be in one group. However,
        // theoretically the
        // admin can put the user in a second enrollment group or the user could
        // theoretically be in a second group context. For now, we only look for
        // the first
        // group. All groups found after the first one are disgarded.
        return (BusinessGroup) groups.get(0);
      }
    }
    // 2. check in areas
    iterator = areaNames.iterator();
    while (iterator.hasNext()) {
      String areaName = (String) iterator.next();
      List groups = cgm.getParticipatingLearningGroupsInAreaFromAllContexts(identity, areaName);
      if (groups.size() > 0) {
        // Usually it is only possible to be in one group. However,
        // theoretically the
        // admin can put the user in a second enrollment group or the user could
        // theoretically be in a second group context. For now, we only look for
        // the first
        // group. All groups found after the first one are disgarded.
        return (BusinessGroup) groups.get(0);
      }
    }
    return null; //
  }

  /**
   * @param identity
   * @param groupNames
   * @return true if this identity is any waiting-list group in this course that
   *         has a name that is in the group names list
   */
  protected BusinessGroup getBusinessGroupWhereInWaitingList(Identity identity, List groupNames, List areaNames, CourseGroupManager cgm) {
    List groups = loadGroupsFromNames(groupNames, areaNames, cgm);
    BusinessGroup businessGroup;
    // loop over all business-groups
    for (Iterator iter = groups.iterator(); iter.hasNext();) {
      businessGroup = (BusinessGroup) iter.next();
      if (securityManager.isIdentityInSecurityGroup(identity, businessGroup.getWaitingGroup())) { return businessGroup; }
    }
    return null;
  }

  /**
   * @param groupNames
   * @return a list of business groups from any of the courses group contexts
   *         that match the names from the groupNames list. If a groupname is
   *         not found it won't be in the list. So groupNames.size() can very
   *         well by different than loadGroupsFromNames().size()
   */
  protected List loadGroupsFromNames(List groupNames, List areaNames, CourseGroupManager cgm) {
    List groups = new ArrayList();
    // 1. add groups
    Iterator iterator = groupNames.iterator();
    while (iterator.hasNext()) {
      String groupName = (String) iterator.next();
      List mygroups = cgm.getLearningGroupsFromAllContexts(groupName);
      for (Iterator it = mygroups.iterator(); it.hasNext();) {
        BusinessGroup bg = (BusinessGroup) it.next();
        if (!groups.contains(bg)) groups.add(bg);
      }
    }
    // add groups from areas
    iterator = areaNames.iterator();
    while (iterator.hasNext()) {
      String areaName = (String) iterator.next();
      List mygroups = cgm.getLearningGroupsInAreaFromAllContexts(areaName);
      for (Iterator it = mygroups.iterator(); it.hasNext();) {
        BusinessGroup bg = (BusinessGroup) it.next();
        if (!groups.contains(bg)) groups.add(bg);
      }
    }
    return groups;
  }

  /**
   * Check if in any business-group a waiting-list is configured.
   *
   * @param groups
   * @return true : YES, there are waiting-list<br>
   *         false: NO, no waiting-list
   */
  protected boolean hasAnyWaitingList(List groups) {
    for (Iterator iter = groups.iterator(); iter.hasNext();) {
      BusinessGroup businessGroup = (BusinessGroup) iter.next();
      if (businessGroup.getWaitingListEnabled().booleanValue()) { return true; }
    }
    return false;
  }

  // /////////////////
  // Private Methods
  // /////////////////
  private boolean addUserToParticipantList(Identity identity, BusinessGroup group, ENCourseNode enNode,
      CoursePropertyManager coursePropertyManager, WindowControl wControl, Translator trans) {
    CoordinatorManager.getCoordinator().getSyncer().assertAlreadyDoInSyncFor(group);
    // 1. Add user to group, fire events, do loggin etc.
    BGConfigFlags flags = BGConfigFlags.createLearningGroupDefaultFlags();
    businessGroupManager.addParticipantAndFireEvent(identity, identity, group, flags, false);
    // 2. Set first enrollment date
    String nowString = Long.toString(System.currentTimeMillis());
    Property firstTime = coursePropertyManager
        .findCourseNodeProperty(enNode, identity, null, ENCourseNode.PROPERTY_INITIAL_ENROLLMENT_DATE);
    if (firstTime == null) {
      // create firsttime
      firstTime = coursePropertyManager.createCourseNodePropertyInstance(enNode, identity, null,
          ENCourseNode.PROPERTY_INITIAL_ENROLLMENT_DATE, null, null, nowString, null);
      coursePropertyManager.saveProperty(firstTime);
    }
    // 3. Set enrollmentdate property
    Property thisTime = coursePropertyManager.findCourseNodeProperty(enNode, identity, null, ENCourseNode.PROPERTY_RECENT_ENROLLMENT_DATE);
    if (thisTime == null) {
      // create firsttime
      thisTime = coursePropertyManager.createCourseNodePropertyInstance(enNode, identity, null,
          ENCourseNode.PROPERTY_RECENT_ENROLLMENT_DATE, null, null, nowString, null);
      coursePropertyManager.saveProperty(thisTime);
    } else {
      thisTime.setStringValue(nowString);
      coursePropertyManager.updateProperty(thisTime);
    }
    // 4. Send notification mail
    MailTemplate mailTemplate = BGMailHelper.createAddMyselfMailTemplate(group, identity);
    MailerWithTemplate mailer = MailerWithTemplate.getInstance();
    MailerResult mailerResult = mailer.sendMail(identity, null, null, mailTemplate, null);
    MailHelper.printErrorsAndWarnings(mailerResult, wControl, trans.getLocale());


    return true;
  }

  private boolean addUserToWaitingList(Identity identity, BusinessGroup group, ENCourseNode enNode,
      CoursePropertyManager coursePropertyManager, WindowControl wControl, Translator trans) {
    CoordinatorManager.getCoordinator().getSyncer().assertAlreadyDoInSyncFor(group);
    // 1. Add user to group, fire events, do loggin etc.
    businessGroupManager.addToWaitingListAndFireEvent(identity, identity, group, false);
    // 2. Set first waiting-list date
    String nowString = Long.toString(System.currentTimeMillis());
    Property firstTime = coursePropertyManager.findCourseNodeProperty(enNode, identity, null,
        ENCourseNode.PROPERTY_INITIAL_WAITINGLIST_DATE);
    if (firstTime == null) {
      // create firsttime
      firstTime = coursePropertyManager.createCourseNodePropertyInstance(enNode, identity, null,
          ENCourseNode.PROPERTY_INITIAL_WAITINGLIST_DATE, null, null, nowString, null);
      coursePropertyManager.saveProperty(firstTime);
    }
    // 3. Set waiting-list date property
    Property thisTime = coursePropertyManager.findCourseNodeProperty(enNode, identity, null, ENCourseNode.PROPERTY_RECENT_WAITINGLIST_DATE);
    if (thisTime == null) {
      // create firsttime
      thisTime = coursePropertyManager.createCourseNodePropertyInstance(enNode, identity, null,
          ENCourseNode.PROPERTY_RECENT_WAITINGLIST_DATE, null, null, nowString, null);
      coursePropertyManager.saveProperty(thisTime);
    } else {
      thisTime.setStringValue(nowString);
      coursePropertyManager.updateProperty(thisTime);
    }   
    // 4. Send notification mail
    MailTemplate mailTemplate = BGMailHelper.createAddWaitinglistMailTemplate(group, identity);
    MailerWithTemplate mailer = MailerWithTemplate.getInstance();
    MailerResult mailerResult = mailer.sendMail(identity, null, null, mailTemplate, null);
    MailHelper.printErrorsAndWarnings(mailerResult, wControl, trans.getLocale());

    return true;
  }

}
TOP

Related Classes of org.olat.course.nodes.en.EnrollmentManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.