Skip to content

Commit

Permalink
RESTWS-909: Condition resource fails when using a custom representati…
Browse files Browse the repository at this point in the history
…on of codedOrNonCoded (openmrs#573)
  • Loading branch information
mseaton committed Mar 31, 2023
1 parent 938b7d7 commit 8931523
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
import org.openmrs.annotation.Handler;
import org.openmrs.api.context.Context;
import org.openmrs.module.webservices.rest.SimpleObject;
import org.openmrs.module.webservices.rest.web.ConversionUtil;
import org.openmrs.module.webservices.rest.web.api.RestService;
import org.openmrs.module.webservices.rest.web.representation.CustomRepresentation;
import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation;
import org.openmrs.module.webservices.rest.web.representation.FullRepresentation;
import org.openmrs.module.webservices.rest.web.representation.Representation;
Expand All @@ -30,25 +32,37 @@ public class CodedOrFreeTextConverter extends BaseDelegatingConverter<CodedOrFre

@Override
public SimpleObject asRepresentation(CodedOrFreeText instance, Representation rep) throws ConversionException {
SimpleObject codedOfFreeText = new SimpleObject();

if (instance.getSpecificName() != null) {
ConceptNameResource1_9 conceptNameResource = (ConceptNameResource1_9) Context.getService(RestService.class)
.getResourceBySupportedClass(ConceptName.class);
codedOfFreeText.add("specificName", conceptNameResource.asRepresentation(instance.getSpecificName(), rep));
}

if (instance.getCoded() != null) {
ConceptResource2_0 conceptResource = (ConceptResource2_0) Context.getService(RestService.class)
.getResourceBySupportedClass(Concept.class);
codedOfFreeText.add("coded", conceptResource.asRepresentation(instance.getCoded(), rep));
SimpleObject codedOrFreeText = new SimpleObject();
if (rep instanceof CustomRepresentation) {
CustomRepresentation customRep = (CustomRepresentation) rep;
DelegatingResourceDescription drd = ConversionUtil.getCustomRepresentationDescription(customRep);
for (String propertyName : drd.getProperties().keySet()) {
DelegatingResourceDescription.Property property = drd.getProperties().get(propertyName);
Object o = ConversionUtil.getPropertyWithRepresentation(instance, propertyName, property.getRep());
if (o != null) {
codedOrFreeText.add(propertyName, o);
}
}
}

if (instance.getNonCoded() != null) {
codedOfFreeText.add("nonCoded", instance.getNonCoded());
else {
if (instance.getSpecificName() != null) {
ConceptNameResource1_9 conceptNameResource = (ConceptNameResource1_9) Context.getService(RestService.class)
.getResourceBySupportedClass(ConceptName.class);
codedOrFreeText.add("specificName", conceptNameResource.asRepresentation(instance.getSpecificName(), rep));
}

if (instance.getCoded() != null) {
ConceptResource2_0 conceptResource = (ConceptResource2_0) Context.getService(RestService.class)
.getResourceBySupportedClass(Concept.class);
codedOrFreeText.add("coded", conceptResource.asRepresentation(instance.getCoded(), rep));
}

if (instance.getNonCoded() != null) {
codedOrFreeText.add("nonCoded", instance.getNonCoded());
}
}

return codedOfFreeText;
return codedOrFreeText;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* Tests functionality of {@link ConditionController2_2}.
Expand Down Expand Up @@ -316,6 +317,7 @@ public void shouldReturnActiveConditions() throws Exception {
List<Condition> conditions = result.get("results");
Assert.assertEquals(2, conditions.size());
}

@Test
public void shouldReturnAllConditions() throws Exception {
MockHttpServletRequest request = request(RequestMethod.GET, getURI());
Expand All @@ -325,4 +327,30 @@ public void shouldReturnAllConditions() throws Exception {
List<Condition> conditions = result.get("results");
Assert.assertEquals(3, conditions.size());
}

@Test
public void shouldGetACustomRepresentation() throws Exception {
MockHttpServletRequest request = request(RequestMethod.GET, getURI());
request.addParameter("patientUuid", "da7f524f-27ce-4bb2-86d6-6d1d05312bd5");
request.addParameter("includeInactive", "true");
request.addParameter("v", "custom:(uuid,display,clinicalStatus,onsetDate,endDate,additionalDetail,condition:(coded:(id,uuid)))");
SimpleObject result = deserialize(handle(request));
List<Map<String, Object>> conditions = result.get("results");
Assert.assertEquals(3, conditions.size());
Map<String, Object> c1 = conditions.get(0);
Assert.assertEquals(7, c1.size());
Assert.assertEquals("c1d4185b-0364-4978-a635-3165a82a3178", c1.get("uuid"));
Assert.assertEquals("Concept 1", c1.get("display"));
Assert.assertEquals("ACTIVE", c1.get("clinicalStatus"));
Assert.assertNotNull(c1.get("onsetDate"));
Assert.assertNull(c1.get("endDate"));
Assert.assertNull(c1.get("additionalDetail"));
Map<String, Object> codedOrNonCoded = (Map<String, Object>) c1.get("condition");
Assert.assertNotNull(codedOrNonCoded);
Assert.assertEquals(1, codedOrNonCoded.size());
Map<String, Object> conditionCoded = (Map<String, Object>) codedOrNonCoded.get("coded");
Assert.assertEquals(2, conditionCoded.size());
Assert.assertEquals(111, conditionCoded.get("id"));
Assert.assertEquals("62a26128-006f-4e77-859b-4aa502e3dd62", conditionCoded.get("uuid"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.openmrs.api.context.Context;
import org.openmrs.module.webservices.rest.SimpleObject;
import org.openmrs.module.webservices.rest.web.api.RestService;
import org.openmrs.module.webservices.rest.web.representation.CustomRepresentation;
import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation;
import org.openmrs.module.webservices.rest.web.representation.Representation;
import org.openmrs.module.webservices.rest.web.resource.api.Converter;
Expand Down Expand Up @@ -504,5 +505,70 @@ public static SimpleObject getAuditInfo(Object delegate) {

return ret;
}


/**
* <strong>Should</strong> return delegating resource description
*/
public static DelegatingResourceDescription getCustomRepresentationDescription(CustomRepresentation representation) {
DelegatingResourceDescription desc = new DelegatingResourceDescription();

String def = representation.getRepresentation();
def = def.startsWith("(") ? def.substring(1) : def;
def = def.endsWith(")") ? def.substring(0, def.length() - 1) : def;
String[] fragments = def.split(",");
for (int i = 0; i < fragments.length; i++) {
String[] field = fragments[i].split(":"); //split into field and representation
if (field.length == 1) {
if (!field[0].equals("links"))
desc.addProperty(field[0]);
if (field[0].equals("links")) {
desc.addSelfLink();
desc.addLink("default", ".?v=" + RestConstants.REPRESENTATION_DEFAULT);
}
} else {
String property = field[0];
String rep = field[1];

// if custom representation
if (rep.startsWith("(")) {
StringBuilder customRep = new StringBuilder();
customRep.append(rep);
if (!rep.endsWith(")")) {
for (int j = 2; j < field.length; j++) {
customRep.append(":").append(field[j]);
}
int open = 1;
for (i = i + 1; i < fragments.length; i++) {
for (char fragment : fragments[i].toCharArray()) {
if (fragment == '(') {
open++;
} else if (fragment == ')') {
open--;
}
}

customRep.append(",");
customRep.append(fragments[i]);

if (open == 0) {
break;
}
}
}
desc.addProperty(property, new CustomRepresentation(customRep.toString()));
} else {
rep = rep.toUpperCase(); //normalize
if (rep.equals("REF")) {
desc.addProperty(property, Representation.REF);
} else if (rep.equals("FULL")) {
desc.addProperty(property, Representation.FULL);
} else if (rep.equals("DEFAULT")) {
desc.addProperty(property, Representation.DEFAULT);
}
}
}
}

return desc;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -410,82 +410,14 @@ public SimpleObject asRepresentation(T delegate, Representation representation)

// finally if it is a custom representation and not supported by any other handler
if (representation instanceof CustomRepresentation) {
repDescription = getCustomRepresentationDescription((CustomRepresentation) representation);
if (repDescription != null) {
return convertDelegateToRepresentation(delegate, repDescription);
}
repDescription = ConversionUtil.getCustomRepresentationDescription((CustomRepresentation) representation);
return convertDelegateToRepresentation(delegate, repDescription);
}

throw new ConversionException("Don't know how to get " + getClass().getSimpleName() + "(" + delegate.getClass()
+ ") as " + representation.getRepresentation(), null);
}

/**
* <strong>Should</strong> return delegating resource description
*/
private DelegatingResourceDescription getCustomRepresentationDescription(CustomRepresentation representation) {
DelegatingResourceDescription desc = new DelegatingResourceDescription();

String def = representation.getRepresentation();
def = def.startsWith("(") ? def.substring(1) : def;
def = def.endsWith(")") ? def.substring(0, def.length() - 1) : def;
String[] fragments = def.split(",");
for (int i = 0; i < fragments.length; i++) {
String[] field = fragments[i].split(":"); //split into field and representation
if (field.length == 1) {
if (!field[0].equals("links"))
desc.addProperty(field[0]);
if (field[0].equals("links")) {
desc.addSelfLink();
desc.addLink("default", ".?v=" + RestConstants.REPRESENTATION_DEFAULT);
}
} else {
String property = field[0];
String rep = field[1];

// if custom representation
if (rep.startsWith("(")) {
StringBuilder customRep = new StringBuilder();
customRep.append(rep);
if (!rep.endsWith(")")) {
for (int j = 2; j < field.length; j++) {
customRep.append(":").append(field[j]);
}
int open = 1;
for (i = i + 1; i < fragments.length; i++) {
for (char fragment : fragments[i].toCharArray()) {
if (fragment == '(') {
open++;
} else if (fragment == ')') {
open--;
}
}

customRep.append(",");
customRep.append(fragments[i]);

if (open == 0) {
break;
}
}
}
desc.addProperty(property, new CustomRepresentation(customRep.toString()));
} else {
rep = rep.toUpperCase(); //normalize
if (rep.equals("REF")) {
desc.addProperty(property, Representation.REF);
} else if (rep.equals("FULL")) {
desc.addProperty(property, Representation.FULL);
} else if (rep.equals("DEFAULT")) {
desc.addProperty(property, Representation.DEFAULT);
}
}
}
}

return desc;
}

/**
* Sets resourceVersion to {@link #getResourceVersion()} for representations other than REF.
*
Expand Down

0 comments on commit 8931523

Please sign in to comment.