Package org.olat.course.nodes.ta

Source Code of org.olat.course.nodes.ta.TaskController

/**
* 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.ta;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import org.olat.core.commons.modules.bc.FolderConfig;
import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
import org.olat.core.dispatcher.mapper.Mapper;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.components.link.LinkFactory;
import org.olat.core.gui.components.table.BaseTableDataModelWithoutFilter;
import org.olat.core.gui.components.table.DefaultColumnDescriptor;
import org.olat.core.gui.components.table.StaticColumnDescriptor;
import org.olat.core.gui.components.table.Table;
import org.olat.core.gui.components.table.TableController;
import org.olat.core.gui.components.table.TableDataModel;
import org.olat.core.gui.components.table.TableEvent;
import org.olat.core.gui.components.table.TableGuiConfiguration;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.ControllerEventListener;
import org.olat.core.gui.control.DefaultController;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.translator.PackageTranslator;
import org.olat.core.gui.translator.Translator;
import org.olat.core.id.Identity;
import org.olat.core.logging.AssertException;
import org.olat.core.logging.Tracing;
import org.olat.core.util.Formatter;
import org.olat.core.util.Util;
import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.core.util.vfs.VFSMediaResource;
import org.olat.course.nodes.CourseNode;
import org.olat.course.nodes.TACourseNode;
import org.olat.course.properties.CoursePropertyManager;
import org.olat.course.run.environment.CourseEnvironment;
import org.olat.modules.ModuleConfiguration;
import org.olat.properties.Property;

/**
* Initial Date:  02.09.2004
*
* @author Mike Stock
*
* Comment: 
*
*/

public class TaskController extends DefaultController implements ControllerEventListener {
  private static final String PACKAGE = Util.getPackageName(TaskController.class);
  private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(PACKAGE);

  private static final String ACTION_PREVIEW = "ta.preview";
 
  private static final String VC_NOMORETASKS = "nomoretasks";
  private static final String VC_ASSIGNEDTASK = "assignedtask";
  private static final String VC_ASSIGNEDTASK_NEWWINDOW = "newwindow";
  private static final String VC_TASKTEXT = "taskText";
 
  static final String PROP_SAMPLED = "smpl";
  /** Property key for "assigned" property. */
  public static final String PROP_ASSIGNED = "ass";
 
  /** Configuration parameter indicating manual selection task type. */
  public static final String TYPE_MANUAL = "manual";
  /** Configuration parameter indicating auto selection task type. */
  public static final String TYPE_AUTO = "auto";
  /** Configuration parameter indicating task-preview mode. */
  public static final String WITH_PREVIEW = "preview";
  /** Configuration parameter indicating non task-preview mode. */
  public static final String WITHOUT_PREVIEW = "no_preview";
 
  // config
  private String taskType;
  private String taskText;
  private File taskFolder;
  private boolean samplingWithReplacement = true;
 
 
  private CourseEnvironment courseEnv;
  private CourseNode node;
  private Translator translator;
  private VelocityContainer myContent;
  private Link taskLaunchButton;
  private TableController tableCtr;
  private TaskTableModel taskTableModel;
  private String assignedTask;
  private Mapper mapper;

  /**
   * Implements a task component.
   * @param ureq
   * @param wControl
   * @param config
   * @param node
   * @param courseEnv
   */
  public TaskController(UserRequest ureq, WindowControl wControl, ModuleConfiguration config,
      CourseNode node, CourseEnvironment courseEnv) {
    super(wControl);
   
    this.node = node;
    this.courseEnv = courseEnv;
    readConfig(config);
   
    translator = new PackageTranslator(PACKAGE, ureq.getLocale());
    myContent = new VelocityContainer("taskVC", VELOCITY_ROOT + "/taskAssigned.html", translator, this);
    taskLaunchButton = LinkFactory.createButtonSmall("task.launch", myContent, this);
    taskLaunchButton.setTarget("_blank");
    taskLaunchButton.setAjaxEnabled(false); // opened in new window
   
    if ( (taskText != null) && (taskText.length() > 0) ) {
      myContent.contextPut(VC_TASKTEXT, taskText);
    }

    // check if user already chose a task
    assignedTask = getAssignedTask(ureq.getIdentity(), courseEnv, node);
    if (assignedTask != null) { //
      pushTaskToVC();
    } else {
      // prepare choose task
      if (taskType.equals(TYPE_AUTO)) { // automatically choose a task
        assignedTask = assignTask(ureq.getIdentity());
        if (assignedTask != null)  {
          pushTaskToVC();
        else {
          myContent.contextPut(VC_NOMORETASKS, translator.translate("task.nomoretasks"));
        }
      } else { // let user choose a task
        myContent.setPage(VELOCITY_ROOT + "/taskChoose.html");
       
        TableGuiConfiguration tableConfig = new TableGuiConfiguration();
        tableCtr = new TableController(tableConfig, ureq, wControl, translator, this);
        // Switch between non-task-preview or task-preview
        Boolean hasPreview = config.getBooleanEntry(TACourseNode.CONF_TASK_PREVIEW);
        if ( (hasPreview == null) || (hasPreview.booleanValue()==false )) {
          // No Preview Mode, Show only file-name
          tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("task.table.th_task", 0, null, ureq.getLocale()));
        } else {
          // Preview Mode, Show only file-name
          DefaultColumnDescriptor columnDescriptor = new DefaultColumnDescriptor("task.table.th_task", 0, ACTION_PREVIEW, ureq.getLocale());
          columnDescriptor.setIsPopUpWindowAction(true,DefaultColumnDescriptor.DEFAULT_POPUP_ATTRIBUTES );
          tableCtr.addColumnDescriptor(columnDescriptor);
        }
        tableCtr.addColumnDescriptor(new StaticColumnDescriptor("seltask", "task.table.th_action", translator.translate("task.table.choose")));
        List availableTasks = compileAvailableTasks();
        if (availableTasks.size() == 0) { // no more tasks available
          myContent.contextPut(VC_NOMORETASKS, translator.translate("task.nomoretasks"));
        }
        taskTableModel = new TaskTableModel(availableTasks);
        tableCtr.setTableDataModel(taskTableModel);
        myContent.put("taskTable", tableCtr.getInitialComponent());
      }
    }
    setInitialComponent(myContent);
  }

  /**
   * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event)
   */
  public void event(UserRequest ureq, Component source, Event event) {
    if (Tracing.isDebugEnabled(TaskController.class)){
      Tracing.logDebug("Test Component.event source" + source + "  , event=" + event, TaskController.class);
    }
    if (source == taskLaunchButton) {
      //deliver files the same way as in preview
      doFileDelivery(ureq, assignedTask);
    }
  }

  /**
   * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event)
   */
  public void event(UserRequest ureq, Controller source, Event event) {
    if (Tracing.isDebugEnabled(TaskController.class)){
      Tracing.logDebug("Test Controller.event source" + source + "  , event=" + event, TaskController.class);
    }
    if (source == tableCtr) {
      if (event.getCommand().equals(Table.COMMANDLINK_ROWACTION_CLICKED)) {
        TableEvent ta = (TableEvent) event;
        if (ta.getActionId().equals(TaskController.ACTION_PREVIEW)) {
          String previewTask = taskTableModel.getRowData(ta.getRowId());
          doFileDelivery(ureq, previewTask);
        } else {
          // select a task
          assignedTask = taskTableModel.getRowData(ta.getRowId());
          List availableTasks = compileAvailableTasks();
          if (!availableTasks.contains(assignedTask)) {
            getWindowControl().setWarning(translator.translate("task.chosen"));
            taskTableModel.setTasks(availableTasks);
            tableCtr.modelChanged();
            if (availableTasks.size() == 0) { // no more tasks available
              myContent.contextPut(VC_NOMORETASKS, translator.translate("task.nomoretasks"));
            }
          } else {
            setAssignedTask(ureq.getIdentity(), assignedTask);
            if (!samplingWithReplacementmarkTaskAsSampled(assignedTask);
            pushTaskToVC();
          }
        }
      }
    }
  }
 
  private void pushTaskToVC() {
    if (assignedTask == null) return;
    myContent.contextPut(VC_ASSIGNEDTASK, assignedTask);
    /*myContent.contextPut(VC_ASSIGNEDTASK_NEWWINDOW,
        new Boolean(!(assignedTask.toLowerCase().endsWith(".html") || assignedTask.toLowerCase().endsWith(".htm"))));*/
    myContent.contextPut(VC_ASSIGNEDTASK_NEWWINDOW,Boolean.TRUE);
    myContent.setPage(VELOCITY_ROOT + "/taskAssigned.html");
  }

  /**
   * Auto-assign a task to an identity and mark it as sampled if necessary.
   * @param identity
   * @return name of the assigned task or null if no more tasks are available.
   */
  private String assignTask(Identity identity) {
    List availableTasks = compileAvailableTasks();
    if (availableTasks.size() == 0 && samplingWithReplacement) {
      unmarkAllSampledTasks(); // unmark all tasks if samplingWithReplacement and no more tasks available
      availableTasks = compileAvailableTasks(); // refetch tasks
    }
    if (availableTasks.size() == 0return null; // no more task available
   
    String task = (String)availableTasks.get((new Random()).nextInt(availableTasks.size()));
    setAssignedTask(identity, task); // assignes the file to this identity
    if (!samplingWithReplacement)
      markTaskAsSampled(task); // remove the file from available files
    return task;
  }
 
  public static String getAssignedTask(Identity identity, CourseEnvironment courseEnv, CourseNode node) {
    List samples = courseEnv.getCoursePropertyManager()
      .findCourseNodeProperties(node, identity, null, PROP_ASSIGNED);
    if (samples.size() == 0) return null; // no sample assigned yet
    return ((Property)samples.get(0)).getStringValue();
  }

  private void setAssignedTask(Identity identity, String task) {
    CoursePropertyManager cpm = courseEnv.getCoursePropertyManager();
    Property p = cpm.createCourseNodePropertyInstance(node, identity, null, PROP_ASSIGNED, null, null, task, null);
    cpm.saveProperty(p);
  }
 
  private void markTaskAsSampled(String task) {
    CoursePropertyManager cpm = courseEnv.getCoursePropertyManager();
    Property p = cpm.createCourseNodePropertyInstance(node, null, null, PROP_SAMPLED, null, null, task, null);
    cpm.saveProperty(p);
  }
 
  private void unmarkAllSampledTasks() {
    courseEnv.getCoursePropertyManager().deleteNodeProperties(node, PROP_SAMPLED);
  }
 
  /**
   * Compiles a list of tasks based on the available files in the task folder,
   * which have not been sampled so far.
   * @return List of available tasks.
   */
  private List compileAvailableTasks() {
    File[] taskSources = taskFolder.listFiles();
    List tasks = new ArrayList(taskSources.length);
    List sampledTasks = compileSampledTasks();
    for (int i = 0; i < taskSources.length; i++) {
      File nextTask = taskSources[i];
      if (nextTask.isFile() && !sampledTasks.contains(nextTask.getName()))
          tasks.add(nextTask.getName());
    }
    return tasks;
  }

  /**
   * Compile a list of tasks marked as sampled.
   * @return List of sampled tasks.
   */
  private List compileSampledTasks() {
    List sampledTasks = new ArrayList();
    List samples = courseEnv.getCoursePropertyManager()
      .findCourseNodeProperties(node, null, null, PROP_SAMPLED);
    for (Iterator iter = samples.iterator(); iter.hasNext();) {
      Property sample = (Property) iter.next();
      sampledTasks.add(sample.getStringValue());
    }
    return sampledTasks;
  }
 
  private void readConfig(ModuleConfiguration config) {
    // get task type
    taskType = (String)config.get(TACourseNode.CONF_TASK_TYPE);
    if (!(taskType.equals(TYPE_MANUAL) || taskType.equals(TYPE_AUTO)))
      throw new AssertException("Invalid task type: " + taskType);

    // get folder path
    String sTaskFolder = FolderConfig.getCanonicalRoot() + TACourseNode.getTaskFolderPathRelToFolderRoot(courseEnv, node);
    taskFolder = new File(sTaskFolder);
    if (!taskFolder.exists() && !taskFolder.mkdirs())
      throw new AssertException("Task folder " + sTaskFolder + " does not exist.");
   
    // get sampling type
    Boolean bSampling = (Boolean)config.get(TACourseNode.CONF_TASK_SAMPLING_WITH_REPLACEMENT);
    samplingWithReplacement = (bSampling == null) ? true : bSampling.booleanValue();
   
    // get task introductory text
    taskText = (String)config.get(TACourseNode.CONF_TASK_TEXT);
   
  }

  /**
   * Model holding available tasks.
   */
  public class TaskTableModel extends BaseTableDataModelWithoutFilter implements TableDataModel {

    private List tasks;
    private static final int columnCount = 1;
   
    /**
     * @param tasks
     */
    public TaskTableModel(List tasks) {  this.tasks = tasks;  }
    /**
     * @param tasks
     */
    public void setTasks(List tasks) { this.tasks = tasks; }
    /**
     * @see org.olat.core.gui.components.table.TableDataModel#getColumnCount()
     */
    public int getColumnCount() { return columnCount; }
    /**
     * @see org.olat.core.gui.components.table.TableDataModel#getRowCount()
     */
    public int getRowCount() { return tasks.size(); }
    /**
     * @see org.olat.core.gui.components.table.TableDataModel#getValueAt(int, int)
     */
    public Object getValueAt(int row, int col) { return getRowData(row)}
    /**
     * @param row
     * @return selected task name.
     */
    public String getRowData(int row) { return (String)tasks.get(row); }
  }
 
  /**
   *
   * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
   */
  protected void doDispose() {
    if (tableCtr != null) {
      tableCtr.dispose();
      tableCtr = null;
    }
  }

  /**
   * deliver the selected file and show in a popup
   *
   * @param ureq
   * @param command
   */
  private void doFileDelivery(UserRequest ureq, String taskFile) {
    OlatRootFolderImpl forumContainer = new OlatRootFolderImpl(TACourseNode.getTaskFolderPathRelToFolderRoot(courseEnv, node), null);
    VFSItem item = forumContainer.resolve(taskFile);
    if (item instanceof VFSLeaf) {
      VFSLeaf leaf = (VFSLeaf)item;
      ureq.getDispatchResult().setResultingMediaResource(new VFSMediaResource(leaf));
    } else if (item==null) {
      Tracing.logWarn("Can not cast to VFSLeaf. item==null, taskFile=" + taskFile,null, TaskController.class);
    } else {
      Tracing.logWarn("Can not cast to VFSLeaf. item.class.name=" + item.getClass().getName() + ", taskFile="+taskFile,null, TaskController.class);
    }
  }

 
}
TOP

Related Classes of org.olat.course.nodes.ta.TaskController

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.