/**
* 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.api.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.Concept;
import org.openmrs.EncounterType;
import org.openmrs.Field;
import org.openmrs.FieldAnswer;
import org.openmrs.FieldType;
import org.openmrs.Form;
import org.openmrs.FormField;
import org.openmrs.aop.RequiredDataAdvice;
import org.openmrs.api.APIException;
import org.openmrs.api.FormService;
import org.openmrs.api.context.Context;
import org.openmrs.api.db.FormDAO;
import org.openmrs.api.handler.SaveHandler;
import org.openmrs.validator.FormValidator;
import org.springframework.validation.BindException;
/**
* Default implementation of the {@link FormService}
* <p>
* This class should not be instantiated alone, get a service class from the Context:
* Context.getFormService();
*
* @see org.openmrs.api.context.Context
* @see org.openmrs.api.FormService
*/
public class FormServiceImpl extends BaseOpenmrsService implements FormService {
protected final Log log = LogFactory.getLog(getClass());
private FormDAO dao;
private FormValidator formValidator;
/**
* Default empty constructor
*/
public FormServiceImpl() {
formValidator = new FormValidator();
}
/**
* Method used to inject the data access object.
*
* @param dao
*/
public void setFormDAO(FormDAO dao) {
this.dao = dao;
}
/**
* @see org.openmrs.api.FormService#createForm(org.openmrs.Form)
* @deprecated
*/
public Form createForm(Form form) throws APIException {
return Context.getFormService().saveForm(form);
}
/**
* @see org.openmrs.api.FormService#getForm(java.lang.Integer)
*/
public Form getForm(Integer formId) throws APIException {
return dao.getForm(formId);
}
/**
* @see org.openmrs.api.FormService#getForms(boolean, boolean)
* @deprecated
*/
public List<Form> getForms(boolean publishedOnly) throws APIException {
if (publishedOnly)
return getPublishedForms();
else
return getAllForms();
}
/**
* @see org.openmrs.api.FormService#getForms(boolean, boolean)
* @deprecated
*/
public List<Form> getForms(boolean publishedOnly, boolean includeRetired) throws APIException {
if (publishedOnly && includeRetired) {
log.warn("Should probably not be searching for published forms, but including retired ones");
List<Form> ret = new ArrayList<Form>();
ret.addAll(getPublishedForms());
ret.addAll(getForms(null, true, null, true, null, null, null));
return ret;
} else {
if (publishedOnly)
return getPublishedForms();
else
return getAllForms(includeRetired);
}
}
/**
* @see org.openmrs.api.FormService#updateForm(org.openmrs.Form)
* @deprecated
*/
public void updateForm(Form form) throws APIException {
Context.getFormService().saveForm(form);
}
/**
* Duplicate this form and form_fields associated with this form
*
* @param form
* @return New duplicated form
* @throws APIException
* @see org.openmrs.api.FormService#duplicateForm(org.openmrs.Form)
*/
public Form duplicateForm(Form form) throws APIException {
// Map of /Old FormFieldId/ to /New FormField Object/
//TreeMap<Integer, FormField> formFieldMap = new TreeMap<Integer, FormField>();
//formFieldMap.put(null, null); //for parentless formFields
for (FormField formField : form.getFormFields()) {
//formFieldMap.put(formField.getFormFieldId(), formField);
formField.setUuid(null);
formField.setFormFieldId(null);
//formField.setParent(formFieldMap.get(formField.getParent().getFormFieldId()));
}
// this is required because Hibernate would recognize the original collection
form.setFormFields(new HashSet<FormField>(form.getFormFields()));
form.setUuid(null);
form.setFormId(null);
form.setCreator(null);
form.setDateCreated(null);
form.setChangedBy(null);
form.setDateChanged(null);
Context.clearSession();
RequiredDataAdvice.recursivelyHandle(SaveHandler.class, form, null);
Form newForm = dao.duplicateForm(form);
return newForm;
}
/**
* @see org.openmrs.api.FormService#retireForm(org.openmrs.Form, java.lang.String)
*/
public void retireForm(Form form, String reason) throws APIException {
form.setRetired(true);
form.setRetireReason(reason);
saveForm(form);
}
/**
* @see org.openmrs.api.FormService#unretireForm(org.openmrs.Form)
*/
public void unretireForm(Form form) throws APIException {
form.setRetired(false);
saveForm(form);
}
/**
* @see org.openmrs.api.FormService#deleteForm(org.openmrs.Form)
* @deprecated
*/
public void deleteForm(Form form) throws APIException {
Context.getFormService().purgeForm(form, false);
}
/**
* @see org.openmrs.api.FormService#getFieldTypes()
* @deprecated
*/
public List<FieldType> getFieldTypes() throws APIException {
return getAllFieldTypes();
}
/**
* @see org.openmrs.api.FormService#getAllFieldTypes()
*/
public List<FieldType> getAllFieldTypes() throws APIException {
return getAllFieldTypes(true);
}
/**
* @see org.openmrs.api.FormService#getAllFieldTypes(boolean)
*/
public List<FieldType> getAllFieldTypes(boolean includeRetired) throws APIException {
return dao.getAllFieldTypes(includeRetired);
}
/**
* @see org.openmrs.api.FormService#getFieldType(java.lang.Integer)
*/
public FieldType getFieldType(Integer fieldTypeId) throws APIException {
return dao.getFieldType(fieldTypeId);
}
/**
* @see org.openmrs.api.FormService#getForms()
* @deprecated
*/
public List<Form> getForms() throws APIException {
return getAllForms();
}
/**
* @see org.openmrs.api.FormService#getForms(org.openmrs.Concept)
* @deprecated
*/
public Set<Form> getForms(Concept c) throws APIException {
return new HashSet<Form>(getFormsContainingConcept(c));
}
/**
* @see org.openmrs.api.FormService#getFormFields(org.openmrs.Form)
* @deprecated
*/
public List<FormField> getFormFields(Form form) throws APIException {
List<FormField> formFields = new Vector<FormField>();
if (form != null && form.getFormFields() != null)
formFields.addAll(form.getFormFields());
return formFields;
}
/**
* @see org.openmrs.api.FormService#findFields(java.lang.String)
* @deprecated
*/
public List<Field> findFields(String searchPhrase) throws APIException {
return getFields(searchPhrase);
}
/**
* @see org.openmrs.api.FormService#findFields(org.openmrs.Concept)
* @deprecated
*/
public List<Field> findFields(Concept concept) throws APIException {
return getFieldsByConcept(concept);
}
/**
* @see org.openmrs.api.FormService#getFields()
* @deprecated
*/
public List<Field> getFields() throws APIException {
return getAllFields();
}
/**
* @see org.openmrs.api.FormService#getField(java.lang.Integer)
*/
public Field getField(Integer fieldId) throws APIException {
return dao.getField(fieldId);
}
/**
* @see org.openmrs.api.FormService#createField(org.openmrs.Field)
* @deprecated
*/
public void createField(Field field) throws APIException {
Context.getFormService().saveField(field);
}
/**
* @see org.openmrs.api.FormService#updateField(org.openmrs.Field)
* @deprecated
*/
public void updateField(Field field) throws APIException {
Context.getFormService().saveField(field);
}
/**
* @see org.openmrs.api.FormService#deleteField(org.openmrs.Field)
* @deprecated
*/
public void deleteField(Field field) throws APIException {
Context.getFormService().purgeField(field);
}
/**
* @see org.openmrs.api.FormService#getFormField(java.lang.Integer)
*/
public FormField getFormField(Integer formFieldId) throws APIException {
return dao.getFormField(formFieldId);
}
/**
* @see org.openmrs.api.FormService#getFormField(org.openmrs.Form, org.openmrs.Concept)
* @see #getFormField(Form, Concept, Collection, boolean)
* @deprecated
*/
public FormField getFormField(Form form, Concept concept) throws APIException {
return getFormField(form, concept, null, false);
}
/**
* @see org.openmrs.api.FormService#getFormField(org.openmrs.Form, org.openmrs.Concept,
* java.util.Collection, boolean)
*/
public FormField getFormField(Form form, Concept concept, Collection<FormField> ignoreFormFields, boolean force)
throws APIException {
// create an empty ignoreFormFields list if none was passed in
if (ignoreFormFields == null)
ignoreFormFields = Collections.emptyList();
return dao.getFormField(form, concept, ignoreFormFields, force);
}
/**
* @see org.openmrs.api.FormService#createFormField(org.openmrs.FormField)
* @deprecated
*/
public void createFormField(FormField formField) throws APIException {
Context.getFormService().saveFormField(formField);
}
/**
* @see org.openmrs.api.FormService#updateFormField(org.openmrs.FormField)
* @deprecated
*/
public void updateFormField(FormField formField) throws APIException {
Context.getFormService().saveFormField(formField);
}
/**
* @see org.openmrs.api.FormService#deleteFormField(org.openmrs.FormField)
* @deprecated
*/
public void deleteFormField(FormField formField) throws APIException {
Context.getFormService().purgeFormField(formField);
}
/**
* @see org.openmrs.api.FormService#getFieldByUuid(java.lang.String)
*/
public Field getFieldByUuid(String uuid) throws APIException {
return dao.getFieldByUuid(uuid);
}
public FieldAnswer getFieldAnswerByUuid(String uuid) throws APIException {
return dao.getFieldAnswerByUuid(uuid);
}
/**
* @see org.openmrs.api.FormService#getFieldTypeByUuid(java.lang.String)
*/
public FieldType getFieldTypeByUuid(String uuid) throws APIException {
return dao.getFieldTypeByUuid(uuid);
}
/**
* @see org.openmrs.api.FormService#getFormByUuid(java.lang.String)
*/
public Form getFormByUuid(String uuid) throws APIException {
return dao.getFormByUuid(uuid);
}
/**
* @see org.openmrs.api.FormService#getFormFieldByUuid(java.lang.String)
*/
public FormField getFormFieldByUuid(String uuid) throws APIException {
return dao.getFormFieldByUuid(uuid);
}
/**
* @see org.openmrs.api.FormService#findForms(java.lang.String, boolean, boolean)
* @deprecated
*/
public List<Form> findForms(String text, boolean includeUnpublished, boolean includeRetired) {
if (includeUnpublished)
return getForms(text, null, null, includeRetired, null, null, null);
else
return getForms(text, true, null, includeRetired, null, null, null);
}
/**
* @see org.openmrs.api.FormService#getAllFields()
*/
public List<Field> getAllFields() throws APIException {
return getAllFields(true);
}
/**
* @see org.openmrs.api.FormService#getAllFields(boolean)
*/
public List<Field> getAllFields(boolean includeRetired) throws APIException {
return dao.getAllFields(includeRetired);
}
/**
* @see org.openmrs.api.FormService#getAllFormFields()
*/
public List<FormField> getAllFormFields() throws APIException {
return dao.getAllFormFields();
}
/**
* @see org.openmrs.api.FormService#getAllForms()
*/
public List<Form> getAllForms() throws APIException {
return getAllForms(true);
}
/**
* @see org.openmrs.api.FormService#getAllForms(boolean)
*/
public List<Form> getAllForms(boolean includeRetired) throws APIException {
return dao.getAllForms(includeRetired);
}
/**
* @see org.openmrs.api.FormService#getFields(java.util.Collection, java.util.Collection,
* java.util.Collection, java.util.Collection, java.util.Collection, java.lang.Boolean,
* java.util.Collection, java.util.Collection, java.lang.Boolean)
*/
public List<Field> getFields(Collection<Form> forms, Collection<FieldType> fieldTypes, Collection<Concept> concepts,
Collection<String> tableNames, Collection<String> attributeNames, Boolean selectMultiple,
Collection<FieldAnswer> containsAllAnswers, Collection<FieldAnswer> containsAnyAnswer,
Boolean retired) throws APIException {
if (forms == null)
forms = Collections.emptyList();
if (fieldTypes == null)
fieldTypes = Collections.emptyList();
if (concepts == null)
concepts = Collections.emptyList();
if (tableNames == null)
tableNames = Collections.emptyList();
if (attributeNames == null)
attributeNames = Collections.emptyList();
if (containsAllAnswers == null)
containsAllAnswers = Collections.emptyList();
if (containsAnyAnswer == null)
containsAnyAnswer = Collections.emptyList();
return dao.getFields(forms, fieldTypes, concepts, tableNames, attributeNames, selectMultiple, containsAllAnswers,
containsAnyAnswer, retired);
}
/**
* @see org.openmrs.api.FormService#getForm(java.lang.String)
* @should return the form with the highest version, if more than one form with the given name exists
*/
public Form getForm(String name) throws APIException {
List<Form> forms = dao.getFormsByName(name);
if (forms == null || forms.size() == 0)
return null;
else
return forms.get(0);
}
/**
* @see org.openmrs.api.FormService#getForm(java.lang.String, java.lang.String)
*/
public Form getForm(String name, String version) throws APIException {
return dao.getForm(name, version);
}
/**
* @see org.openmrs.api.FormService#getForms(java.lang.String, boolean)
*/
public List<Form> getForms(String fuzzyName, boolean onlyLatestVersion) {
// get all forms including unpublished and including retired
List<Form> forms = getForms(fuzzyName, null, null, null, null, null, null);
Set<String> namesAlreadySeen = new HashSet<String>();
for (Iterator<Form> i = forms.iterator(); i.hasNext();) {
Form form = i.next();
if (namesAlreadySeen.contains(form.getName()))
i.remove();
else
namesAlreadySeen.add(form.getName());
}
return forms;
}
/**
* @deprecated see
* {@link #getForms(String, Boolean, Collection, Boolean, Collection, Collection, Collection)}
*/
public List<Form> getForms(String partialName, Boolean published, Collection<EncounterType> encounterTypes,
Boolean retired, Collection<FormField> containingAnyFormField,
Collection<FormField> containingAllFormFields) {
return getForms(partialName, published, encounterTypes, retired, containingAnyFormField, containingAllFormFields,
null);
}
/**
* @see org.openmrs.api.FormService#getForms(java.lang.String, java.lang.Boolean,
* java.util.Collection, java.lang.Boolean, java.util.Collection, java.util.Collection)
*/
public List<Form> getForms(String partialName, Boolean published, Collection<EncounterType> encounterTypes,
Boolean retired, Collection<FormField> containingAnyFormField,
Collection<FormField> containingAllFormFields, Collection<Field> fields) {
if (encounterTypes == null)
encounterTypes = Collections.emptyList();
if (containingAllFormFields == null)
containingAllFormFields = Collections.emptyList();
if (containingAnyFormField == null)
containingAnyFormField = Collections.emptyList();
if (fields == null)
fields = Collections.emptyList();
return dao.getForms(partialName, published, encounterTypes, retired, containingAnyFormField,
containingAllFormFields, fields);
}
/**
* @see org.openmrs.api.FormService#getPublishedForms()
*/
public List<Form> getPublishedForms() throws APIException {
return getForms(null, true, null, false, null, null, null);
}
/**
* @see org.openmrs.api.FormService#purgeField(org.openmrs.Field)
*/
public void purgeField(Field field) throws APIException {
purgeField(field, false);
}
/**
* @see org.openmrs.api.FormService#purgeField(org.openmrs.Field, boolean)
*/
public void purgeField(Field field, boolean cascade) throws APIException {
if (cascade == true)
throw new APIException("Not Yet Implemented");
else
dao.deleteField(field);
}
/**
* @see org.openmrs.api.FormService#purgeForm(org.openmrs.Form)
*/
public void purgeForm(Form form) throws APIException {
purgeForm(form, false);
}
/**
* @see org.openmrs.api.FormService#purgeForm(org.openmrs.Form, boolean)
*/
public void purgeForm(Form form, boolean cascade) throws APIException {
if (cascade == true)
throw new APIException("Not Yet Implemented");
else
dao.deleteForm(form);
}
/**
* @see org.openmrs.api.FormService#purgeFormField(org.openmrs.FormField)
*/
public void purgeFormField(FormField formField) throws APIException {
dao.deleteFormField(formField);
}
/**
* @see org.openmrs.api.FormService#retireField(org.openmrs.Field)
*/
public Field retireField(Field field) throws APIException {
if (field.getRetired() == false) {
field.setRetired(true);
return saveField(field);
} else {
return field;
}
}
/**
* @see org.openmrs.api.FormService#saveField(org.openmrs.Field)
*/
public Field saveField(Field field) throws APIException {
return dao.saveField(field);
}
/**
* @see org.openmrs.api.FormService#saveForm(org.openmrs.Form)
*/
public Form saveForm(Form form) throws APIException {
BindException errors = new BindException(form, "form");
formValidator.validate(form, errors);
if (errors.hasErrors()) {
throw new APIException(errors);
}
if (form.getFormFields() != null) {
for (FormField ff : form.getFormFields()) {
if (ff.getForm() == null)
ff.setForm(form);
else if (!ff.getForm().equals(form))
throw new APIException("Form contains FormField " + ff + " that already belongs to a different form");
}
}
return dao.saveForm(form);
}
/**
* @see org.openmrs.api.FormService#saveFormField(org.openmrs.FormField)
*/
public FormField saveFormField(FormField formField) throws APIException {
Field field = formField.getField();
if (field.getCreator() == null)
field.setCreator(Context.getAuthenticatedUser());
if (field.getDateCreated() == null)
field.setDateCreated(new Date());
// don't change the changed by and date changed on field for
// form field updates
// set the uuid here because the RequiredDataAdvice only looks at child lists
if (field.getUuid() == null)
field.setUuid(UUID.randomUUID().toString());
return dao.saveFormField(formField);
}
/**
* @see org.openmrs.api.FormService#unretireField(org.openmrs.Field)
*/
public Field unretireField(Field field) throws APIException {
if (field.getRetired() == true) {
field.setRetired(false);
return saveField(field);
} else {
return field;
}
}
/**
* @see org.openmrs.api.FormService#getFields(java.lang.String)
*/
public List<Field> getFields(String fuzzySearchPhrase) throws APIException {
return dao.getFields(fuzzySearchPhrase);
}
/**
* @see org.openmrs.api.FormService#getFieldsByConcept(org.openmrs.Concept)
*/
public List<Field> getFieldsByConcept(Concept concept) throws APIException {
return getFields(null, null, Collections.singleton(concept), null, null, null, null, null, null);
}
/**
* @see org.openmrs.api.FormService#getFormsContainingConcept(org.openmrs.Concept)
*/
public List<Form> getFormsContainingConcept(Concept concept) throws APIException {
if (concept.getConceptId() == null)
return Collections.emptyList();
return dao.getFormsContainingConcept(concept);
}
/**
* @see org.openmrs.api.FormService#purgeFieldType(org.openmrs.FieldType)
*/
public void purgeFieldType(FieldType fieldType) throws APIException {
dao.deleteFieldType(fieldType);
}
/**
* @see org.openmrs.api.FormService#saveFieldType(org.openmrs.FieldType)
*/
public FieldType saveFieldType(FieldType fieldType) throws APIException {
return dao.saveFieldType(fieldType);
}
}