package fi.otavanopisto.muikku.plugins.workspace.fieldio; import java.util.List; import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; import org.codehaus.jackson.map.ObjectMapper; import fi.otavanopisto.muikku.plugins.material.model.QueryMultiSelectField; import fi.otavanopisto.muikku.plugins.material.model.QueryMultiSelectFieldOption; import fi.otavanopisto.muikku.plugins.workspace.WorkspaceMaterialFieldAnswerController; import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceMaterialField; import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceMaterialMultiSelectFieldAnswer; import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceMaterialMultiSelectFieldAnswerOption; import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceMaterialReply; public class WorkspaceMultiSelectFieldIOHandler implements WorkspaceFieldIOHandler { @Inject private WorkspaceMaterialFieldAnswerController workspaceMaterialFieldAnswerController; @Override public void store(WorkspaceMaterialField field, WorkspaceMaterialReply reply, String value) throws WorkspaceFieldIOException { String[] postedValues = new String[0]; WorkspaceMaterialMultiSelectFieldAnswer fieldAnswer = workspaceMaterialFieldAnswerController.findWorkspaceMaterialMultiSelectFieldAnswerByFieldAndReply(field, reply); if (fieldAnswer == null && StringUtils.isNotBlank(value)) { fieldAnswer = workspaceMaterialFieldAnswerController.createWorkspaceMaterialMultiSelectFieldAnswer(field, reply); } if (StringUtils.isNotBlank(value)) { ObjectMapper objectMapper = new ObjectMapper(); try { postedValues = objectMapper.readValue(value, String[].class); } catch (Exception e) { throw new WorkspaceFieldIOException("Could not marshal field response", e); } } List<QueryMultiSelectFieldOption> options = workspaceMaterialFieldAnswerController.listMultiSelectFieldOptions((QueryMultiSelectField) field.getQueryField()); List<WorkspaceMaterialMultiSelectFieldAnswerOption> currentAnswers = workspaceMaterialFieldAnswerController.listWorkspaceMaterialMultiSelectFieldAnswerOptions(fieldAnswer); for (String postedValue : postedValues) { WorkspaceMaterialMultiSelectFieldAnswerOption answerOption = getAnswerOption(currentAnswers, postedValue); if (answerOption == null) { // From unchecked to checked QueryMultiSelectFieldOption fieldOption = getFieldOption(options, postedValue); if (fieldOption == null) { throw new WorkspaceFieldIOException("Multiselect lacks posted option " + postedValue); } workspaceMaterialFieldAnswerController.createWorkspaceMaterialMultiSelectFieldAnswerOption(fieldAnswer, fieldOption); } else { // From checked to checked currentAnswers.remove(answerOption); } } // From checked to unchecked for (WorkspaceMaterialMultiSelectFieldAnswerOption currentAnswer : currentAnswers) { workspaceMaterialFieldAnswerController.deleteWorkspaceMaterialMultiSelectFieldAnswerOption(currentAnswer); } } private QueryMultiSelectFieldOption getFieldOption(List<QueryMultiSelectFieldOption> options, String name) { for (QueryMultiSelectFieldOption option : options) { if (option.getName().equals(name)) { return option; } } return null; } private WorkspaceMaterialMultiSelectFieldAnswerOption getAnswerOption(List<WorkspaceMaterialMultiSelectFieldAnswerOption> options, String name) { for (WorkspaceMaterialMultiSelectFieldAnswerOption option : options) { if (option.getOption().getName().equals(name)) { return option; } } return null; } @Override public String retrieve(WorkspaceMaterialField field, WorkspaceMaterialReply reply) throws WorkspaceFieldIOException { String answer = "[]"; WorkspaceMaterialMultiSelectFieldAnswer fieldAnswer = workspaceMaterialFieldAnswerController.findWorkspaceMaterialMultiSelectFieldAnswerByFieldAndReply(field, reply); if (fieldAnswer != null) { List<WorkspaceMaterialMultiSelectFieldAnswerOption> options = workspaceMaterialFieldAnswerController.listWorkspaceMaterialMultiSelectFieldAnswerOptions(fieldAnswer); int i = 0; String[] values = new String[options.size()]; for (WorkspaceMaterialMultiSelectFieldAnswerOption option : options) { values[i++] = option.getOption().getName(); } ObjectMapper objectMapper = new ObjectMapper(); try { answer = objectMapper.writeValueAsString(values); } catch (Exception e) { throw new WorkspaceFieldIOException("Could not marshal field response", e); } } return answer; } @Override public String getType() { return "application/vnd.muikku.field.multiselect"; } }