Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SAK-51065 LTI+Assignments: Include LTI Assignment GB Columns in AGS Service Requests #13369

Merged
merged 1 commit into from
Mar 13, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 66 additions & 5 deletions lti/lti-common/src/java/org/sakaiproject/lti13/LineItemUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Iterator;
import java.util.Map;
import java.util.Date;
import java.util.HashMap;

import org.apache.commons.lang3.StringUtils;

Expand All @@ -41,6 +43,7 @@
import org.sakaiproject.lti.util.SakaiLTIUtil;

import org.sakaiproject.site.api.Site;
import org.sakaiproject.util.foorm.Foorm;
import org.sakaiproject.component.cover.ComponentManager;
import org.sakaiproject.lti.api.LTIService;
import org.sakaiproject.component.cover.ServerConfigurationService;
Expand All @@ -63,6 +66,7 @@ public class LineItemUtil {

public static final String GB_EXTERNAL_APP_NAME = "IMS-AGS";
public static final String ASSIGNMENTS_EXTERNAL_APP_NAME = "Assignments"; // Avoid circular references
public static final String ASSIGNMENT_REFERENCE_PREFIX = "/assignment/a";

public final static String ID_SEPARATOR = "|";
public final static String ID_SEPARATOR_REGEX = "\\|";
Expand Down Expand Up @@ -290,27 +294,70 @@ public static Assignment updateLineItem(Site site, Long tool_id, Long column_id,
return gradebookColumn;
}

/**
* Return a map of external_id values for LTI assignments in a site
*
* @param context_id
*
* The format of the external_id is:
*
* tool_id|content_id|resourceLink|tag|
*
* This should be called with the appropriate security advisor in place
*
* @return A map of assignment references to their external_id values
*/
public static Map<String, String> getExternalIdsForToolAssignments(String context_id) {
Map<String, String> retval = new HashMap<>();
org.sakaiproject.assignment.api.AssignmentService assignmentService = ComponentManager.get(org.sakaiproject.assignment.api.AssignmentService.class);
LTIService ltiService = ComponentManager.get(LTIService.class);

try {
Collection<org.sakaiproject.assignment.api.model.Assignment> assignments = assignmentService.getAssignmentsForContext(context_id);
for (org.sakaiproject.assignment.api.model.Assignment a : assignments) {
String assignmentReference = org.sakaiproject.assignment.api.AssignmentReferenceReckoner.reckoner().assignment(a).reckon().getReference();
Integer assignmentContentId = a.getContentId();
if ( assignmentContentId == null ) continue;
Map<String, Object> content = ltiService.getContent(assignmentContentId.longValue(), context_id);
if ( content == null ) continue;
retval.put(assignmentReference, constructExternalId(content, null));
}
} catch (Throwable e) {
log.error("Unexpected Throwable", e.getMessage());
}
return retval;
}

/**
* Return a list of assignments associated with this tool in a site
* @param context_id - The site id
* @param tool_id - The tool id
* @return A list of Assignment objects (perhaps empty) or null on failure
*/
protected static List<Assignment> getColumnsForToolDAO(String context_id, Long tool_id) {
List retval = new ArrayList();
List<Assignment> retval = new ArrayList<>();
GradingService g = (GradingService) ComponentManager
.get("org.sakaiproject.grading.api.GradingService");
Map<String, String> externalIds = null;

pushAdvisor();
try {
List<Assignment> gradebookColumns = g.getAssignments(context_id);
for (Iterator i = gradebookColumns.iterator(); i.hasNext();) {
Assignment gbColumn = (Assignment) i.next();
if ( ! isGradebookColumnLTI(gbColumn) ) continue;
String external_id = gbColumn.getExternalId();
if ( isGradebookColumnLTI(gbColumn) ) {
// We are good to go
} else if ( isAssignmentColumn(external_id) ) {
if ( externalIds == null ) {
externalIds = getExternalIdsForToolAssignments(context_id);
}
external_id = externalIds.get(external_id);
if ( external_id == null ) continue;
}

// Parse the external_id
// tool_id|content_id|resourceLink|tag|
String external_id = gbColumn.getExternalId();
if ( external_id == null || external_id.length() < 1 ) continue;

String[] parts = external_id.split(ID_SEPARATOR_REGEX);
Expand Down Expand Up @@ -437,6 +484,10 @@ public static boolean isGradebookColumnLTI(Assignment gradebookColumn) {
return false;
}

public static boolean isAssignmentColumn(String external_id) {
return external_id.startsWith(ASSIGNMENT_REFERENCE_PREFIX);
}

/**
* Get the line items from the gradebook for a tool
* @param site The site we are looking at
Expand All @@ -454,17 +505,27 @@ public static List<SakaiLineItem> getLineItemsForTool(String signed_placement, S
.get("org.sakaiproject.grading.api.GradingService");

List<SakaiLineItem> retval = new ArrayList<>();
Map<String, String> externalIds = null;

pushAdvisor();
try {

List gradebookColumns = g.getAssignments(context_id);
for (Iterator i = gradebookColumns.iterator(); i.hasNext();) {
Assignment gbColumn = (Assignment) i.next();
if ( ! isGradebookColumnLTI(gbColumn) ) continue;
String external_id = gbColumn.getExternalId();
if ( isGradebookColumnLTI(gbColumn) ) {
// We are good to go
} else if ( isAssignmentColumn(external_id) ) {
if ( externalIds == null ) {
externalIds = getExternalIdsForToolAssignments(context_id);
}
external_id = externalIds.get(external_id);
if ( external_id == null ) continue;
}

// Parse the external_id
// tool_id|content_id|resourceLink|tag|assignmentRef (optional)
String external_id = gbColumn.getExternalId();
if ( external_id == null || external_id.length() < 1 ) continue;

String[] parts = external_id.split(ID_SEPARATOR_REGEX);
Expand Down
Loading