Skip to content

Commit

Permalink
Add SerializableComplexObsHandler interface for form processing methods
Browse files Browse the repository at this point in the history
- TRUNK-3886(cherry picked from commit 7f2dca6)
  • Loading branch information
wluyima authored and dkayiwa committed Jul 3, 2013
1 parent 46d1bfb commit 769bf7d
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 8 deletions.
1 change: 1 addition & 0 deletions api/src/main/java/org/openmrs/api/FormService.java
Expand Up @@ -707,6 +707,7 @@ public FormField getFormField(Form form, Concept concept, Collection<FormField>
* @throws APIException
* @should propagate save to the Field property on the given FormField
* @should save given formField successfully
* @should inject form fields from serializable complex obs handlers
*/
@Authorized(PrivilegeConstants.MANAGE_FORMS)
public FormField saveFormField(FormField formField) throws APIException;
Expand Down
39 changes: 31 additions & 8 deletions api/src/main/java/org/openmrs/api/impl/FormServiceImpl.java
Expand Up @@ -29,6 +29,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.Concept;
import org.openmrs.ConceptComplex;
import org.openmrs.EncounterType;
import org.openmrs.Field;
import org.openmrs.FieldAnswer;
Expand All @@ -43,6 +44,8 @@
import org.openmrs.api.db.FormDAO;
import org.openmrs.api.handler.SaveHandler;
import org.openmrs.customdatatype.CustomDatatypeUtil;
import org.openmrs.obs.ComplexObsHandler;
import org.openmrs.obs.SerializableComplexObsHandler;
import org.openmrs.util.OpenmrsUtil;
import org.openmrs.validator.FormValidator;
import org.springframework.validation.BindException;
Expand Down Expand Up @@ -710,7 +713,27 @@ public FormField saveFormField(FormField formField) throws APIException {
if (field.getUuid() == null)
field.setUuid(UUID.randomUUID().toString());

return dao.saveFormField(formField);
formField = dao.saveFormField(formField);

//Include all formfields from all serializable complex obs handlers
Concept concept = formField.getField().getConcept();
if (concept != null && concept.isComplex()) {
ComplexObsHandler handler = Context.getObsService().getHandler(((ConceptComplex) concept).getHandler());
if (handler instanceof SerializableComplexObsHandler) {
SerializableComplexObsHandler sHandler = (SerializableComplexObsHandler) handler;
if (sHandler.getFormFields() != null) {
for (FormField ff : sHandler.getFormFields()) {
ff.setParent(formField);
ff.setForm(formField.getForm());
ff.setCreator(formField.getCreator());
ff.setDateCreated(formField.getDateCreated());
dao.saveFormField(ff);
}
}
}
}

return formField;
}

/**
Expand Down Expand Up @@ -819,31 +842,31 @@ private boolean fieldsAreSimilar(Field field, Field fieldToBeReplaced) {
}

/**
* @see org.openmrs.api.FormService#getFormResource(java.lang.Integer)
* @see org.openmrs.api.FormService#getFormResource(java.lang.Integer)
*/
@Override
public FormResource getFormResource(Integer formResourceId) throws APIException {
return dao.getFormResource(formResourceId);
}

/**
* @see org.openmrs.api.FormService#getFormResourceByUuid(java.lang.String)
* @see org.openmrs.api.FormService#getFormResourceByUuid(java.lang.String)
*/
@Override
public FormResource getFormResourceByUuid(String uuid) throws APIException {
return dao.getFormResourceByUuid(uuid);
}

/**
* @see org.openmrs.api.FormService#getFormResource(org.openmrs.Form, java.lang.String)
* @see org.openmrs.api.FormService#getFormResource(org.openmrs.Form, java.lang.String)
*/
@Override
public FormResource getFormResource(Form form, String name) throws APIException {
return dao.getFormResource(form, name);
}

/**
* @see org.openmrs.api.FormService#saveFormResource(org.openmrs.FormResource)
* @see org.openmrs.api.FormService#saveFormResource(org.openmrs.FormResource)
*/
@Override
public FormResource saveFormResource(FormResource formResource) throws APIException {
Expand All @@ -866,15 +889,15 @@ public FormResource saveFormResource(FormResource formResource) throws APIExcept
}

/**
* @see org.openmrs.api.FormService#purgeFormResource(org.openmrs.FormResource)
* @see org.openmrs.api.FormService#purgeFormResource(org.openmrs.FormResource)
*/
@Override
public void purgeFormResource(FormResource formResource) throws APIException {
dao.deleteFormResource(formResource);
}

/**
* @see org.openmrs.api.FormService#getFormResourcesForForm(org.openmrs.Form)
* @see org.openmrs.api.FormService#getFormResourcesForForm(org.openmrs.Form)
*/
@Override
public Collection<FormResource> getFormResourcesForForm(Form form) throws APIException {
Expand All @@ -883,7 +906,7 @@ public Collection<FormResource> getFormResourcesForForm(Form form) throws APIExc

/**
* duplicates form resources from one form to another
*
*
* @param source the form to copy resources from
* @param destination the form to copy resources to
*/
Expand Down
@@ -0,0 +1,48 @@
/**
* 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.obs;

import java.util.Set;

import org.openmrs.ConceptComplex;
import org.openmrs.FormField;

/**
* Interface for handling complex obs. Implementing classes are responsible for generating
* {@link FormField}s to embed inside a parent {@link FormField}. When a form is submitted and it
* has a {@link ConceptComplex} associated to an implementing handler class, then the handler's
* serializeFormData method is invoked to perform the serialization of the complex data.
*
* @since 1.10
*/
public interface SerializableComplexObsHandler extends ComplexObsHandler {

/**
* Gets the form fields that should be added to the forms using complex concepts that are
* associated to this handler
*
* @return Set of form fields
*/
public Set<FormField> getFormFields();

/**
* Transforms the incoming data from one format to another. For example, this can be useful if
* the data is to be sent as an hl7 message which doesn't support xml
*
* @param data the data to serialize
* @return the serialized form data
*/
public String serializeFormData(String data);

}
76 changes: 76 additions & 0 deletions api/src/test/java/org/openmrs/api/FormServiceTest.java
Expand Up @@ -32,6 +32,7 @@
import java.util.Set;
import java.util.Vector;

import org.apache.commons.collections.ListUtils;
import org.junit.Assert;
import org.junit.Test;
import org.openmrs.Concept;
Expand All @@ -40,7 +41,9 @@
import org.openmrs.Form;
import org.openmrs.FormField;
import org.openmrs.FormResource;
import org.openmrs.Obs;
import org.openmrs.api.context.Context;
import org.openmrs.obs.SerializableComplexObsHandler;
import org.openmrs.test.BaseContextSensitiveTest;
import org.openmrs.test.Verifies;

Expand Down Expand Up @@ -735,4 +738,77 @@ private String getResourceAsString(String filename) throws IOException {
return sb.toString();
}

/**
* @see {@link FormService#saveFormField(FormField)}
*/
@SuppressWarnings("unchecked")
@Test
@Verifies(value = "should inject form fields from serializable complex obs handlers", method = "saveFormField(FormField)")
public void saveFormField_shouldInjectFormFieldsFromSerializableComplexObsHandlers() throws Exception {
executeDataSet("org/openmrs/api/include/ConceptComplex.xml");
Context.getObsService().registerHandler("NeigborHandler", new NeighborHandler());
Concept concept = Context.getConceptService().getConcept(6043);
Field field = new Field();
field.setName("neighbor");
field.setConcept(concept);

FormField formField = new FormField();
formField.setField(field);
FormService fs = Context.getFormService();
formField.setForm(fs.getForm(1));

List<FormField> originalFormFields = fs.getAllFormFields();
int initialFormFieldCount = originalFormFields.size();
formField = fs.saveFormField(formField);
List<FormField> updatedFormFields = fs.getAllFormFields();
//should have this and the two form fields from the handler
Assert.assertEquals(initialFormFieldCount += 3, updatedFormFields.size());
//get the formfields added by the handler and check their parent
List<FormField> childFormFields = ListUtils.subtract(updatedFormFields, originalFormFields);
childFormFields.remove(formField);//exclude this form field
for (FormField ff : childFormFields) {
Assert.assertEquals(formField, ff.getParent());
}
}

/**
* This is a test complex obs handler that adds 2 form fields
*/
private class NeighborHandler implements SerializableComplexObsHandler {

public Set<FormField> getFormFields() {
Set<FormField> formFields = new HashSet<FormField>();
Field firstName = new Field();
firstName.setName("firstName");
Field lastName = new Field();
lastName.setName("lastName");

FormField firstNameFormField = new FormField();
firstNameFormField.setField(firstName);
FormField lastNameFormField = new FormField();
lastNameFormField.setField(lastName);

formFields.add(firstNameFormField);
formFields.add(lastNameFormField);

return formFields;
}

public Obs saveObs(Obs obs) throws APIException {
return null;
}

public Obs getObs(Obs obs, String view) {
return null;
}

public boolean purgeComplexData(Obs obs) {
return false;
}

public String serializeFormData(String data) {
return null;
}
}

}
@@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<concept concept_id="6043" retired="false" datatype_id="13" class_id="7" is_set="false" creator="1" date_created="2004-08-12 00:00:00.0" uuid="8b68403d-8c7e-4961-8952-2da8f249a156"/>
<concept_complex concept_id="6043" handler="NeigborHandler" />
<concept_name concept_id="6043" name="NEIGHBOR" locale="en" creator="1" date_created="2004-08-12 00:00:00.0" concept_name_id="2395" voided="0" uuid="9c067348-5bf2-4050-b824-0aa009436ed6" concept_name_type="FULLY_SPECIFIED" locale_preferred="0"/>
</dataset>

0 comments on commit 769bf7d

Please sign in to comment.