/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.propertyeditor; import java.beans.PropertyEditorSupport; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.Concept; import org.openmrs.ConceptAnswer; import org.openmrs.Drug; import org.openmrs.api.ConceptService; import org.openmrs.api.context.Context; import org.springframework.util.StringUtils; /** * Handles lists of conceptids that correspond to answers. */ public class ConceptAnswersEditor extends PropertyEditorSupport { private Log log = LogFactory.getLog(this.getClass()); private Collection<ConceptAnswer> originalConceptAnswers = null; /** * Default constructor taking in the original answers. This should be the actual list on the * pojo object to prevent hibernate errors later on. * * @param originalAnswers the list on the pojo */ public ConceptAnswersEditor(Collection<ConceptAnswer> originalAnswers) { if (originalAnswers == null) originalConceptAnswers = new HashSet<ConceptAnswer>(); else originalConceptAnswers = originalAnswers; } /** * loops over the textbox assigned to this property. The textbox is assumed to be a string of * conceptIds^drugIds separated by spaces. * * @param text list of conceptIds (not conceptAnswerIds) * @should set the sort weights with the least possible changes */ public void setAsText(String text) throws IllegalArgumentException { if (StringUtils.hasText(text)) { ConceptService cs = Context.getConceptService(); String[] conceptIds = text.split(" "); List<String> requestConceptIds = new Vector<String>(); //set up parameter answer Set for easier add/delete functions and removal of duplicates for (String id : conceptIds) { id = id.trim(); if (!id.equals("") && !requestConceptIds.contains(id)) //remove whitespace, blank lines, and duplicates requestConceptIds.add(id); } Collection<ConceptAnswer> deletedConceptAnswers = new HashSet<ConceptAnswer>(); // loop over original concept answers to find any deleted answers for (ConceptAnswer origConceptAnswer : originalConceptAnswers) { boolean answerDeleted = true; for (String conceptId : requestConceptIds) { Integer id = getConceptId(conceptId); Integer drugId = getDrugId(conceptId); Drug answerDrug = origConceptAnswer.getAnswerDrug(); if (id.equals(origConceptAnswer.getAnswerConcept().getConceptId())) { if (drugId == null && answerDrug == null) answerDeleted = false; else if ((drugId != null && answerDrug != null) && drugId.equals(origConceptAnswer.getAnswerDrug().getDrugId())) answerDeleted = false; } } if (answerDeleted) deletedConceptAnswers.add(origConceptAnswer); } // loop over those deleted answers to delete them for (ConceptAnswer conceptAnswer : deletedConceptAnswers) { originalConceptAnswers.remove(conceptAnswer); } // loop over concept ids in the request to add any that are new for (String conceptId : requestConceptIds) { Integer id = getConceptId(conceptId); Integer drugId = getDrugId(conceptId); boolean newAnswerConcept = true; for (ConceptAnswer origConceptAnswer : originalConceptAnswers) { Drug answerDrug = origConceptAnswer.getAnswerDrug(); if (id.equals(origConceptAnswer.getAnswerConcept().getConceptId())) { if (drugId == null && answerDrug == null) newAnswerConcept = false; else if ((drugId != null && answerDrug != null) && drugId.equals(answerDrug.getDrugId())) newAnswerConcept = false; } } // if the current request answer is new, add it to the originals if (newAnswerConcept) { Concept answer = cs.getConcept(id); Drug drug = null; if (drugId != null) drug = cs.getDrug(drugId); ConceptAnswer ac = new ConceptAnswer(answer, drug); originalConceptAnswers.add(ac); } } //loop over to set the order //as the list comes into 'requestConceptIds' in the order the user wants // there are 2 conditions that will require the sort_weights to be reassigned // 1) any ConceptAnswer.sortWeight == NULL (meaning it is just added) // 2) the list is not in ASCENDING order (example sort order of the list is 1, 2, 10, 9) // -startIdx (start index) is where in this list we will start to reassign the sort_weights Double lastWeightSeen = null; int startIdx = -1;//the idx to start at, if we have a NULL sort weight (new concept answer) or sort weights are not ascending for (int i = 0; i < requestConceptIds.size() - 1; i++) { Integer id1 = getConceptId(requestConceptIds.get(i)); ConceptAnswer ca1 = getConceptAnswerFromOriginal(id1); if (ca1.getSortWeight() == null) { if (lastWeightSeen == null) { //start at 1, we're at the beginning lastWeightSeen = 1d; } else { //we start at +1 lastWeightSeen += 1; } startIdx = i; break; } Integer id2 = getConceptId(requestConceptIds.get(i + 1)); ConceptAnswer ca2 = getConceptAnswerFromOriginal(id2); int c = ca1.compareTo(ca2); if (c > 0) { startIdx = i; lastWeightSeen = ca1.getSortWeight(); break; } lastWeightSeen = ca1.getSortWeight(); } if (startIdx != -1) { //then we need to re-weight for (int i = startIdx; i < requestConceptIds.size(); i++) { Integer id = getConceptId(requestConceptIds.get(i)); ConceptAnswer ca = getConceptAnswerFromOriginal(id); ca.setSortWeight(lastWeightSeen++); } } log.debug("originalConceptAnswers.getConceptId(): "); for (ConceptAnswer a : originalConceptAnswers) log.debug("id: " + a.getAnswerConcept().getConceptId()); log.debug("requestConceptIds: "); for (String i : requestConceptIds) log.debug("id: " + i); } else { originalConceptAnswers.clear(); } setValue(originalConceptAnswers); } /** * find this conceptId in the original set and set its weight */ private ConceptAnswer getConceptAnswerFromOriginal(Integer id) { for (ConceptAnswer ca : originalConceptAnswers) { if (ca.getAnswerConcept().getConceptId().equals(id)) { return ca; } } return null; } /** * Parses the string and returns the Integer concept id Expected string: "123" or "123^34" * ("conceptId^drugId") * * @param conceptId * @return */ private Integer getConceptId(String conceptId) { if (conceptId.contains("^")) return Integer.valueOf(conceptId.substring(0, conceptId.indexOf("^"))); else return Integer.valueOf(conceptId); } /** * Parses the string and returns the Integer drug id or null if none Expected string: "123" or * "123^34" ("conceptId^drugId") * * @param conceptId * @return */ private Integer getDrugId(String conceptId) { if (conceptId.contains("^")) return Integer.valueOf(conceptId.substring(conceptId.indexOf("^") + 1, conceptId.length())); return null; } }