Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
4dd8f5c
Add MapStruct dependency
axlewin Sep 3, 2025
3625a2c
Add MapStruct annotation processor
axlewin Sep 3, 2025
678c4c8
Use MapStruct mapping for EventsFacade
axlewin Sep 10, 2025
5176ffc
Use MapStruct mapping for PagesFacade
axlewin Sep 10, 2025
8d5ba6a
Remove email addresses from UserSummaryDTOs in EventBookingDTOs
axlewin Sep 15, 2025
c9359d5
Use MapStruct mapping for UserAccountManager
axlewin Sep 15, 2025
2b9c5c8
Map `teacherAccountPending` from auth provider to local user
axlewin Sep 17, 2025
c5cc659
Add unimplemented mapping exception
axlewin Sep 17, 2025
efb7492
Use MapStruct mapping for GameManager
axlewin Sep 18, 2025
407e9af
Use MapStruct mapping for GameboardPersistenceManager
axlewin Sep 18, 2025
95d3557
Resolve merge conflicts
axlewin Sep 18, 2025
d0ddaf1
Fix gameManager initialisation
axlewin Sep 18, 2025
308e419
Use MapStruct mapping for GroupManager
axlewin Sep 19, 2025
3e46318
Use MapStruct mapping for PgQuizAttemptPersistenceManager
axlewin Sep 19, 2025
798fc1e
Use MapStruct mapping for PgAssignmentPersistenceManager
axlewin Sep 19, 2025
d0c7e93
Use MapStruct mapping for PgQuizAssignmentPersistenceManager
axlewin Sep 19, 2025
296a4d6
Remove unused orika imports
axlewin Sep 19, 2025
28e3ef9
Use MapStruct mapping for ContentSummarizerService
axlewin Sep 24, 2025
5247293
Use MapStruct mappings for QuestionManager
axlewin Sep 24, 2025
269af91
Use MapStruct mapping for QuizQuestionManager
axlewin Sep 24, 2025
fa93f20
Use MapStruct mapping for GitContentManager
axlewin Sep 24, 2025
0e05415
Replace remaining Orika usage in ContentMapper
axlewin Sep 25, 2025
e957613
Remove remaining Orika usage
axlewin Sep 25, 2025
7cf0f72
Remove Orika dependency
axlewin Sep 25, 2025
8073c1a
Rename content mappers
axlewin Sep 25, 2025
dbe1594
Add default Content to ContentDTO/Wildcard mapper
axlewin Sep 26, 2025
61c63b5
Set subclass exhaustive strategy to simplify ContentBase mappings
axlewin Sep 26, 2025
6738c4d
Rename GameboardMapper -> AssignmentMapper
axlewin Sep 26, 2025
39c9b28
Rename fields for consistency, update javadocs
axlewin Sep 26, 2025
c35b90d
Add remaining content subclass mappings
axlewin Sep 29, 2025
e81bbe2
Revert "Add remaining content subclass mappings"
axlewin Sep 29, 2025
2aeb4ad
Add missing content subclass mappings
axlewin Sep 30, 2025
067ee1c
Remove ignore annotations for specific fields
axlewin Sep 30, 2025
a475612
Ignore all unmapped target properties
axlewin Sep 30, 2025
f4cb150
Suppress unchecked cast warnings
axlewin Sep 30, 2025
600cdff
Simplify & rename mappings
axlewin Oct 1, 2025
b8c5422
Merge branch 'main' of https://github.com/isaacphysics/isaac-api into…
axlewin Oct 1, 2025
c81b269
Rename ContentSubclassMapper instances
axlewin Oct 1, 2025
06eedbe
Fix Checkstyle warnings in mappers
axlewin Oct 1, 2025
0bb6673
Fix Checkstyle warnings
axlewin Oct 2, 2025
66ab637
Change LLM questions to extend IsaacQuestionBase
axlewin Oct 20, 2025
7b8ca9a
Add new mappers to Guice config
axlewin Oct 20, 2025
4f2381f
Update mappers
axlewin Oct 20, 2025
7759fc5
Add subclass mapping for quizzes
axlewin Oct 21, 2025
930e32d
Add ignore annotation for end_date in event page mappings
axlewin Oct 21, 2025
cd79599
Fix CheckStyle warnings
axlewin Oct 21, 2025
90896a8
Add Content DO -> DTO mapping test
axlewin Oct 22, 2025
7559001
Add missing Content subclass mappings
axlewin Oct 22, 2025
43073e5
Add copy method for Wildcards, remove now-unused Content -> Wildcard …
axlewin Oct 22, 2025
106f398
Include all Content subclasses in mapper test
axlewin Oct 23, 2025
8817104
Add more Content subclass mappings
axlewin Oct 23, 2025
e2c139f
Avoid unnecessarily copying group membership DTO
axlewin Oct 24, 2025
d171bfa
Use copy instead of map where source class matches target class
axlewin Oct 24, 2025
61941a9
Revert "Use copy instead of map where source class matches target class"
axlewin Oct 24, 2025
7f45f0a
Simplify mapping UserSummaryDTO subclasses to parent class
axlewin Oct 24, 2025
4dd4321
Add QuestionValidationResponse DO -> DTO mapping test
axlewin Oct 24, 2025
778dd21
Name mapping methods consistently
axlewin Oct 27, 2025
7ecb76f
Rename EventMapper -> EventBookingMapper
axlewin Oct 27, 2025
c504ab7
Remove @Inject annotations from mapper instance methods
axlewin Oct 27, 2025
51f0f0a
Only attempt to use public constructors in mapper tests
axlewin Oct 27, 2025
0f43099
Remove redundant UserSummaryDTO mapping within event bookings
axlewin Oct 30, 2025
254913f
Clarify DetailedEventBookingDTO -> EventBookingDTO mapping
axlewin Nov 5, 2025
934b9d4
Delete unused method
axlewin Nov 5, 2025
42f8fdb
Preserve supersededBy in SeguePageDTO -> GameboardItem mapping
axlewin Nov 6, 2025
f9575a5
Preserve summary in SeguePageDTO -> ContentSummaryDTO mapping
axlewin Nov 6, 2025
4bb54e6
Preserve deprecated & hiddenFromRoles in QuizDTO -> QuizSummaryDTO ma…
axlewin Nov 7, 2025
8f83434
Avoid setting null exam board to the empty string in glossary terms
axlewin Nov 10, 2025
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
20 changes: 14 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<ossindex.version>3.2.0</ossindex.version>
<swagger-core.version>2.2.34</swagger-core.version>
<jgit.version>6.10.1.202505221210-r</jgit.version>
<mapstruct.version>1.6.3</mapstruct.version>
<surefire.jacoco.args />
<failsafe.jacoco.args />
</properties>
Expand Down Expand Up @@ -139,12 +140,6 @@
<version>${jgit.version}</version>
</dependency>

<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.5.4</version>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
Expand Down Expand Up @@ -480,6 +475,12 @@
<version>4.3.1</version>
</dependency>

<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>

<!-- These two don't need to be included in the war package so their scope is "provided" which means we
promise to make them available in the deployment environment, but we aren't going to because they are
not needed at runtime anyway. -->
Expand Down Expand Up @@ -536,6 +537,13 @@
<version>3.10.1</version>
<configuration>
<release>11</release>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
Expand Down
25 changes: 13 additions & 12 deletions src/main/java/uk/ac/cam/cl/dtg/isaac/api/EventsFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import com.opencsv.CSVWriter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import ma.glasnost.orika.MapperFacade;
import org.jboss.resteasy.annotations.GZIP;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -66,6 +65,7 @@
import uk.ac.cam.cl.dtg.segue.search.AbstractFilterInstruction;
import uk.ac.cam.cl.dtg.segue.search.DateRangeFilterInstruction;
import uk.ac.cam.cl.dtg.util.AbstractConfigLoader;
import uk.ac.cam.cl.dtg.util.mappers.MainMapper;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.ws.rs.DELETE;
Expand Down Expand Up @@ -117,7 +117,7 @@ public class EventsFacade extends AbstractIsaacFacade {
private final UserAccountManager userAccountManager;
private final SchoolListReader schoolListReader;

private final MapperFacade mapper;
private final MainMapper mapper;

/**
* EventsFacade.
Expand All @@ -136,7 +136,7 @@ public EventsFacade(final AbstractConfigLoader properties, final ILogManager log
final UserAssociationManager userAssociationManager,
final GroupManager groupManager,
final UserAccountManager userAccountManager, final SchoolListReader schoolListReader,
final MapperFacade mapper) {
final MainMapper mapper) {
super(properties, logManager);
this.bookingManager = bookingManager;
this.userManager = userManager;
Expand Down Expand Up @@ -327,7 +327,7 @@ private ResultsWrapper<ContentDTO> getEventsReservedByUser(final HttpServletRequ
throws SegueDatabaseException, ContentManagerException {
List<ContentDTO> filteredResults = Lists.newArrayList();

List<EventBookingDTO> userReservationList = this.mapper.mapAsList(bookingManager.getAllEventReservationsForUser(currentUser.getId()), EventBookingDTO.class);
List<EventBookingDTO> userReservationList = this.mapper.mapToListOfEventBookingDTO(bookingManager.getAllEventReservationsForUser(currentUser.getId()));

for (EventBookingDTO booking : userReservationList) {

Expand Down Expand Up @@ -557,15 +557,15 @@ public final Response getEventBookingForGivenGroup(@Context final HttpServletReq
.collect(Collectors.toList());

// Filter eventBookings based on whether the booked user is a member of the given group
List<EventBookingDTO> eventBookings = bookingManager.getBookingsByEventId(eventId)
List<DetailedEventBookingDTO> eventBookings = bookingManager.getBookingsByEventId(eventId)
.stream().filter(booking -> groupMemberIds.contains(booking.getUserBooked().getId()))
.collect(Collectors.toList());

// Event leaders are only allowed to see the bookings of connected users
eventBookings = userAssociationManager.filterUnassociatedRecords(currentUser, eventBookings,
booking -> booking.getUserBooked().getId());

return Response.ok(this.mapper.mapAsList(eventBookings, EventBookingDTO.class)).build();
return Response.ok(this.mapper.mapToListOfEventBookingDTO(eventBookings)).build();
} catch (SegueDatabaseException e) {
String errorMsg = String.format(
"Database error occurred while trying retrieve bookings for group (%s) on event (%s).",
Expand Down Expand Up @@ -598,7 +598,7 @@ public final Response getEventBookingForAllGroups(@Context final HttpServletRequ
return new SegueErrorResponse(Status.FORBIDDEN, "You do not have permission to use this endpoint.").toResponse();
}

List<EventBookingDTO> eventBookings = this.mapper.mapAsList(bookingManager.getBookingsByEventId(eventId), EventBookingDTO.class);
List<EventBookingDTO> eventBookings = this.mapper.mapToListOfEventBookingDTO(bookingManager.getBookingsByEventId(eventId));

// Only allowed to see the bookings of connected users
eventBookings = userAssociationManager.filterUnassociatedRecords(
Expand Down Expand Up @@ -778,7 +778,7 @@ public final Response createBookingForGivenUser(@Context final HttpServletReques
ADMIN_BOOKING_REASON_FIELDNAME, additionalInformation.get("authorisation") == null ? "NOT_PROVIDED" : additionalInformation.get("authorisation")
));

return Response.ok(this.mapper.map(booking, EventBookingDTO.class)).build();
return Response.ok(this.mapper.copy(booking)).build();
} catch (NoUserLoggedInException e) {
return SegueErrorResponse.getNotLoggedInResponse();
} catch (SegueDatabaseException e) {
Expand Down Expand Up @@ -859,7 +859,7 @@ public final Response createReservationsForGivenUsers(@Context final HttpServlet
USER_ID_LIST_FKEY_FIELDNAME, userIds.toArray(),
BOOKING_STATUS_FIELDNAME, BookingStatus.RESERVED.toString()
));
return Response.ok(this.mapper.mapAsList(bookings, EventBookingDTO.class)).build();
return Response.ok(this.mapper.copy(bookings)).build();

} catch (NoUserLoggedInException e) {
return SegueErrorResponse.getNotLoggedInResponse();
Expand Down Expand Up @@ -1017,7 +1017,7 @@ public final Response createBookingForMe(@Context final HttpServletRequest reque
this.getLogManager().logEvent(userManager.getCurrentUser(request), request,
SegueServerLogType.EVENT_BOOKING, ImmutableMap.of(EVENT_ID_FKEY_FIELDNAME, event.getId()));

return Response.ok(this.mapper.map(eventBookingDTO, EventBookingDTO.class)).build();
return Response.ok(this.mapper.copy(eventBookingDTO)).build();
} catch (NoUserLoggedInException e) {
return SegueErrorResponse.getNotLoggedInResponse();
} catch (SegueDatabaseException e) {
Expand Down Expand Up @@ -1072,7 +1072,7 @@ public final Response addMeToWaitingList(@Context final HttpServletRequest reque
this.getLogManager().logEvent(userManager.getCurrentUser(request), request,
SegueServerLogType.EVENT_WAITING_LIST_BOOKING, ImmutableMap.of(EVENT_ID_FKEY_FIELDNAME, event.getId()));

return Response.ok(this.mapper.map(eventBookingDTO, EventBookingDTO.class)).build();
return Response.ok(this.mapper.copy(eventBookingDTO)).build();
} catch (NoUserLoggedInException e) {
return SegueErrorResponse.getNotLoggedInResponse();
} catch (SegueDatabaseException e) {
Expand Down Expand Up @@ -1608,7 +1608,8 @@ private IsaacEventPageDTO getRawEventDTOById(final String eventId)
// The Events Facade *mutates* the EventDTO returned by this method; we must return a copy of
// the original object else we will poison the contentManager's cache!
// TODO: might it be better to get the DO from the cache and map it to DTO here to reduce overhead?
return mapper.map(possibleEvent, IsaacEventPageDTO.class);
IsaacEventPageDTO eventPageDTO = (IsaacEventPageDTO) possibleEvent;
return mapper.copy(eventPageDTO);
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@
import uk.ac.cam.cl.dtg.isaac.api.managers.InvalidGameboardException;
import uk.ac.cam.cl.dtg.isaac.api.managers.NoWildcardException;
import uk.ac.cam.cl.dtg.isaac.dos.GameboardCreationMethod;
import uk.ac.cam.cl.dtg.isaac.dos.IsaacWildcard;
import uk.ac.cam.cl.dtg.isaac.dos.LightweightQuestionValidationResponse;
import uk.ac.cam.cl.dtg.isaac.dos.QuestionValidationResponse;
import uk.ac.cam.cl.dtg.isaac.dto.GameboardDTO;
import uk.ac.cam.cl.dtg.isaac.dto.GameboardItem;
import uk.ac.cam.cl.dtg.isaac.dto.GameboardListDTO;
import uk.ac.cam.cl.dtg.isaac.dto.IsaacWildcardDTO;
import uk.ac.cam.cl.dtg.isaac.dto.SegueErrorResponse;
import uk.ac.cam.cl.dtg.isaac.dto.users.AbstractSegueUserDTO;
import uk.ac.cam.cl.dtg.isaac.dto.users.AnonymousUserDTO;
Expand Down Expand Up @@ -741,7 +741,7 @@ public Response unlinkUserFromGameboard(@Context final HttpServletRequest reques
public final Response getWildCards(@Context final Request request) {

try {
List<IsaacWildcard> wildcards = gameManager.getWildcards();
List<IsaacWildcardDTO> wildcards = gameManager.getWildcards();
if (null == wildcards || wildcards.isEmpty()) {
return new SegueErrorResponse(Status.NOT_FOUND, "No wildcards found.").toResponse();
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/uk/ac/cam/cl/dtg/isaac/api/PagesFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.google.inject.Inject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import ma.glasnost.orika.MapperFacade;
import org.jboss.resteasy.annotations.GZIP;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -60,6 +59,7 @@
import uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException;
import uk.ac.cam.cl.dtg.segue.dao.content.GitContentManager;
import uk.ac.cam.cl.dtg.util.AbstractConfigLoader;
import uk.ac.cam.cl.dtg.util.mappers.MainMapper;

import jakarta.annotation.Nullable;
import jakarta.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -102,7 +102,7 @@ public class PagesFacade extends AbstractIsaacFacade {
private static final Logger log = LoggerFactory.getLogger(PagesFacade.class);

private final ContentService api;
private final MapperFacade mapper;
private final MainMapper mapper;
private final UserAccountManager userManager;
private final URIManager uriManager;
private final QuestionManager questionManager;
Expand Down Expand Up @@ -134,7 +134,7 @@ public class PagesFacade extends AbstractIsaacFacade {
*/
@Inject
public PagesFacade(final ContentService api, final AbstractConfigLoader propertiesLoader,
final ILogManager logManager, final MapperFacade mapper, final GitContentManager contentManager,
final ILogManager logManager, final MainMapper mapper, final GitContentManager contentManager,
final UserAccountManager userManager, final URIManager uriManager,
final QuestionManager questionManager, final GameManager gameManager,
final UserAttemptManager userAttemptManager) {
Expand Down
39 changes: 11 additions & 28 deletions src/main/java/uk/ac/cam/cl/dtg/isaac/api/managers/GameManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.google.api.client.util.Maps;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections4.comparators.ComparatorChain;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.tuple.ImmutablePair;
Expand All @@ -44,6 +43,7 @@
import uk.ac.cam.cl.dtg.isaac.dto.GameboardListDTO;
import uk.ac.cam.cl.dtg.isaac.dto.IsaacQuestionPageDTO;
import uk.ac.cam.cl.dtg.isaac.dto.IsaacQuickQuestionDTO;
import uk.ac.cam.cl.dtg.isaac.dto.IsaacWildcardDTO;
import uk.ac.cam.cl.dtg.isaac.dto.ResultsWrapper;
import uk.ac.cam.cl.dtg.isaac.dto.content.ContentBaseDTO;
import uk.ac.cam.cl.dtg.isaac.dto.content.ContentDTO;
Expand All @@ -56,10 +56,11 @@
import uk.ac.cam.cl.dtg.segue.dao.SegueDatabaseException;
import uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException;
import uk.ac.cam.cl.dtg.segue.dao.content.GitContentManager;
import uk.ac.cam.cl.dtg.util.AbstractConfigLoader;
import uk.ac.cam.cl.dtg.util.mappers.MainMapper;

import jakarta.annotation.Nullable;
import jakarta.validation.constraints.NotNull;
import uk.ac.cam.cl.dtg.util.AbstractConfigLoader;

import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -93,7 +94,7 @@ public class GameManager {

private final GameboardPersistenceManager gameboardPersistenceManager;
private final Random randomGenerator;
private final MapperFacade mapper;
private final MainMapper mapper;
private final GitContentManager contentManager;
private final QuestionManager questionManager;

Expand All @@ -111,7 +112,7 @@ public class GameManager {
*/
@Inject
public GameManager(final GitContentManager contentManager,
final GameboardPersistenceManager gameboardPersistenceManager, final MapperFacade mapper,
final GameboardPersistenceManager gameboardPersistenceManager, final MainMapper mapper,
final QuestionManager questionManager,
final AbstractConfigLoader properties) {
this.contentManager = contentManager;
Expand Down Expand Up @@ -677,7 +678,7 @@ public List<ImmutablePair<RegisteredUserDTO, List<GameboardItem>>> gatherGamePro
* @throws ContentManagerException
* - if we cannot access the content requested.
*/
public List<IsaacWildcard> getWildcards() throws NoWildcardException, ContentManagerException {
public List<IsaacWildcardDTO> getWildcards() throws NoWildcardException, ContentManagerException {
List<GitContentManager.BooleanSearchClause> fieldsToMap = Lists.newArrayList();

fieldsToMap.add(new GitContentManager.BooleanSearchClause(
Expand All @@ -693,10 +694,12 @@ public List<IsaacWildcard> getWildcards() throws NoWildcardException, ContentMan
throw new NoWildcardException();
}

List<IsaacWildcard> result = Lists.newArrayList();
List<IsaacWildcardDTO> result = Lists.newArrayList();
for (ContentDTO c : wildcardResults.getResults()) {
IsaacWildcard wildcard = mapper.map(c, IsaacWildcard.class);
result.add(wildcard);
if ((c instanceof IsaacWildcardDTO)) {
IsaacWildcardDTO wildcard = (IsaacWildcardDTO) c;
result.add(wildcard);
}
}

return result;
Expand Down Expand Up @@ -1195,26 +1198,6 @@ private void augmentGameItemWithAttemptInformation(
gameItem.setState(state);
}

/**
* Get a wildcard by id.
*
* @param id
* - of wildcard
* @return wildcard or an exception.
* @throws ContentManagerException
* - if we cannot access the content requested.
*/
private IsaacWildcard getWildCardById(final String id) throws ContentManagerException {
Map<Map.Entry<BooleanOperator, String>, List<String>> fieldsToMap = Maps.newHashMap();

fieldsToMap.put(immutableEntry(BooleanOperator.AND, ID_FIELDNAME), Collections.singletonList(id));
fieldsToMap.put(immutableEntry(BooleanOperator.AND, TYPE_FIELDNAME), Collections.singletonList(WILDCARD_TYPE));

Content wildcardResults = this.contentManager.getContentDOById(id);

return mapper.map(wildcardResults, IsaacWildcard.class);
}

/**
* Helper method to generate field to match requirements for search queries (specialised for isaac-filtering rules)
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,14 @@
import uk.ac.cam.cl.dtg.segue.api.managers.QuestionManager;
import uk.ac.cam.cl.dtg.segue.dao.SegueDatabaseException;
import uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException;
import uk.ac.cam.cl.dtg.segue.dao.content.ContentMapper;
import uk.ac.cam.cl.dtg.isaac.dos.QuestionValidationResponse;
import uk.ac.cam.cl.dtg.isaac.dos.content.Choice;
import uk.ac.cam.cl.dtg.isaac.dos.content.DTOMapping;
import uk.ac.cam.cl.dtg.isaac.dos.content.Question;
import uk.ac.cam.cl.dtg.isaac.dto.QuestionValidationResponseDTO;
import uk.ac.cam.cl.dtg.isaac.dto.SegueErrorResponse;
import uk.ac.cam.cl.dtg.isaac.dto.content.ChoiceDTO;
import uk.ac.cam.cl.dtg.isaac.dto.content.QuestionDTO;
import uk.ac.cam.cl.dtg.isaac.dto.users.RegisteredUserDTO;
import uk.ac.cam.cl.dtg.util.mappers.MainMapper;

import jakarta.annotation.Nullable;
import jakarta.ws.rs.core.Response;
Expand All @@ -58,7 +56,7 @@

public class QuizQuestionManager {
private final QuestionManager questionManager;
private final ContentMapper mapper;
private final MainMapper mapper;
private final IQuizQuestionAttemptPersistenceManager quizQuestionAttemptManager;
private final QuizManager quizManager;
private final QuizAttemptManager quizAttemptManager;
Expand All @@ -83,7 +81,7 @@ public class QuizQuestionManager {
* - for attempts, particularly checking attempts are completed before revealing feedback.
*/
@Inject
public QuizQuestionManager(final QuestionManager questionManager, final ContentMapper mapper,
public QuizQuestionManager(final QuestionManager questionManager, final MainMapper mapper,
final IQuizQuestionAttemptPersistenceManager quizQuestionAttemptManager,
final QuizManager quizManager, final QuizAttemptManager quizAttemptManager) {
this.questionManager = questionManager;
Expand All @@ -109,7 +107,7 @@ public QuestionValidationResponseDTO validateAnswer(Question question, ChoiceDTO
}

public void recordQuestionAttempt(QuizAttemptDTO quizAttempt, QuestionValidationResponseDTO questionResponse) throws SegueDatabaseException {
QuestionValidationResponse questionResponseDO = this.mapper.getAutoMapper().map(questionResponse, QuestionValidationResponse.class);
QuestionValidationResponse questionResponseDO = this.mapper.map(questionResponse);

this.quizQuestionAttemptManager.registerQuestionAttempt(quizAttempt.getId(), questionResponseDO);
}
Expand Down Expand Up @@ -301,11 +299,8 @@ void augmentQuestionObjectWithAttemptInformation(Map<QuestionDTO, QuestionValida
lastAttempt = questionManager.convertQuestionValidationResponseToDTO(lastResponse);
} else {
// Manual extract only the safe details (questionId, answer).
Choice answer = lastResponse.getAnswer();
lastAttempt = new QuestionValidationResponseDTO();
DTOMapping dtoMapping = answer.getClass().getAnnotation(DTOMapping.class);
lastAttempt.setAnswer(mapper.getAutoMapper().map(lastResponse.getAnswer(),
(Class<? extends ChoiceDTO>) dtoMapping.value()));
lastAttempt.setAnswer(mapper.map(lastResponse.getAnswer()));
lastAttempt.setQuestionId(lastResponse.getQuestionId());
}
lastAttempt.setDateAttempted(null); // Strip timestamps, since quiz responses may be seen by other users.
Expand Down
Loading
Loading