/** * 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.db.hibernate; import java.util.Collection; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.SessionFactory; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Expression; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Subqueries; 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.api.APIException; import org.openmrs.api.db.DAOException; import org.openmrs.api.db.FormDAO; /** * Hibernate specific Form related functions This class should not be used directly. All calls * should go through the {@link org.openmrs.api.FormService} methods. * * @see org.openmrs.api.db.FormDAO * @see org.openmrs.api.FormService */ public class HibernateFormDAO implements FormDAO { protected final Log log = LogFactory.getLog(getClass()); /** * Hibernate session factory */ private SessionFactory sessionFactory; /** * Set session factory * * @param sessionFactory */ public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } /** * Returns the form object originally passed in, which will have been persisted. * * @see org.openmrs.api.FormService#createForm(org.openmrs.Form) */ public Form saveForm(Form form) throws DAOException { sessionFactory.getCurrentSession().saveOrUpdate(form); return form; } /** * @see org.openmrs.api.FormService#duplicateForm(org.openmrs.Form) */ public Form duplicateForm(Form form) throws DAOException { return (Form) sessionFactory.getCurrentSession().merge(form); } /** * @see org.openmrs.api.FormService#deleteForm(org.openmrs.Form) */ public void deleteForm(Form form) throws DAOException { sessionFactory.getCurrentSession().delete(form); } /** * @see org.openmrs.api.FormService#getForm(java.lang.Integer) */ public Form getForm(Integer formId) throws DAOException { return (Form) sessionFactory.getCurrentSession().get(Form.class, formId); } /** * @see org.openmrs.api.FormService#getFormFields(Form) */ @SuppressWarnings("unchecked") public List<FormField> getFormFields(Form form) throws DAOException { return sessionFactory.getCurrentSession().createCriteria(FormField.class, "ff").add(Expression.eq("ff.form", form)) .list(); } /** * @see org.openmrs.api.db.FormDAO#getFields(java.lang.String) */ @SuppressWarnings("unchecked") public List<Field> getFields(String search) throws DAOException { Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Field.class); criteria.add(Restrictions.like("name", search, MatchMode.ANYWHERE)); criteria.addOrder(Order.asc("name")); return criteria.list(); } /** * @see org.openmrs.api.FormService#getFieldsByConcept(org.openmrs.Concept) */ @SuppressWarnings("unchecked") public List<Field> getFieldsByConcept(Concept concept) throws DAOException { Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Field.class); criteria.add(Expression.eq("concept", concept)); criteria.addOrder(Order.asc("name")); return criteria.list(); } /** * @see org.openmrs.api.FormService#getField(java.lang.Integer) * @see org.openmrs.api.db.FormDAO#getField(java.lang.Integer) */ public Field getField(Integer fieldId) throws DAOException { return (Field) sessionFactory.getCurrentSession().get(Field.class, fieldId); } /** * @see org.openmrs.api.FormService#getAllFields(boolean) * @see org.openmrs.api.db.FormDAO#getAllFields(boolean) */ @SuppressWarnings("unchecked") public List<Field> getAllFields(boolean includeRetired) throws DAOException { Criteria crit = sessionFactory.getCurrentSession().createCriteria(Field.class); if (includeRetired == false) crit.add(Expression.eq("retired", false)); return crit.list(); } /** * @see org.openmrs.api.FormService#getFieldType(java.lang.Integer) * @see org.openmrs.api.db.FormDAO#getFieldType(java.lang.Integer) */ public FieldType getFieldType(Integer fieldTypeId) throws DAOException { return (FieldType) sessionFactory.getCurrentSession().get(FieldType.class, fieldTypeId); } /** * @see org.openmrs.api.FormService#getFieldTypes() * @see org.openmrs.api.db.FormDAO#getAllFieldTypes(boolean) */ @SuppressWarnings("unchecked") public List<FieldType> getAllFieldTypes(boolean includeRetired) throws DAOException { Criteria crit = sessionFactory.getCurrentSession().createCriteria(FieldType.class); if (includeRetired == false) crit.add(Expression.eq("retired", false)); return crit.list(); } /** * @see org.openmrs.api.FormService#getFormField(java.lang.Integer) * @see org.openmrs.api.db.FormDAO#getFormField(java.lang.Integer) */ public FormField getFormField(Integer formFieldId) throws DAOException { return (FormField) sessionFactory.getCurrentSession().get(FormField.class, formFieldId); } /** * @see org.openmrs.api.FormService#getFormField(org.openmrs.Form, org.openmrs.Concept, * java.util.Collection, boolean) * @see org.openmrs.api.db.FormDAO#getFormField(org.openmrs.Form, org.openmrs.Concept, * java.util.Collection, boolean) */ @SuppressWarnings("unchecked") public FormField getFormField(Form form, Concept concept, Collection<FormField> ignoreFormFields, boolean force) throws DAOException { if (form == null) { log.debug("form is null, no fields will be matched"); return null; } Criteria crit = sessionFactory.getCurrentSession().createCriteria(FormField.class, "ff").createAlias("field", "field").add(Expression.eq("field.concept", concept)).add(Expression.eq("form", form)); // get the list of all formfields with this concept for this form List<FormField> formFields = crit.list(); String err = "FormField warning. No FormField matching concept '" + concept + "' for form '" + form + "'"; if (formFields.size() < 1) { log.debug(err); return null; } // save the first formfield in case we're not a in a "force" situation FormField backupPlan = formFields.get(0); // remove the formfields we're supposed to ignore from the return list formFields.removeAll(ignoreFormFields); // if we ended up removing all of the formfields, check to see if we're // in a "force" situation if (formFields.size() < 1) { if (force == false) return backupPlan; else { log.debug(err); return null; } } else { // if formFields.size() is still greater than 0 FormField ff = (FormField) formFields.get(0); return ff; } } /** * @see org.openmrs.api.FormService#getForms() */ @SuppressWarnings("unchecked") public List<Form> getAllForms(boolean includeRetired) throws DAOException { Criteria crit = sessionFactory.getCurrentSession().createCriteria(Form.class); if (includeRetired == false) crit.add(Expression.eq("retired", false)); crit.addOrder(Order.asc("name")); crit.addOrder(Order.asc("formId")); return crit.list(); } /** * @see org.openmrs.api.db.FormDAO#getFormsContainingConcept(org.openmrs.Concept) */ @SuppressWarnings("unchecked") public List<Form> getFormsContainingConcept(Concept c) throws DAOException { String q = "select distinct ff.form from FormField ff where ff.field.concept = :concept"; Query query = sessionFactory.getCurrentSession().createQuery(q); query.setEntity("concept", c); return query.list(); } /** * @see org.openmrs.api.FormService#saveField(org.openmrs.Field) * @see org.openmrs.api.db.FormDAO#saveField(org.openmrs.Field) */ public Field saveField(Field field) throws DAOException { sessionFactory.getCurrentSession().saveOrUpdate(field); return field; } /** * @see org.openmrs.api.FormService#deleteField(org.openmrs.Field) * @see org.openmrs.api.db.FormDAO#deleteField(org.openmrs.Field) */ public void deleteField(Field field) throws DAOException { sessionFactory.getCurrentSession().delete(field); } /** * @see org.openmrs.api.FormService#createFormField(org.openmrs.FormField) */ public FormField saveFormField(FormField formField) throws DAOException { sessionFactory.getCurrentSession().saveOrUpdate(formField); return formField; } /** * @see org.openmrs.api.FormService#deleteFormField(org.openmrs.FormField) * @see org.openmrs.api.db.FormDAO#deleteFormField(org.openmrs.FormField) */ public void deleteFormField(FormField formField) throws DAOException { sessionFactory.getCurrentSession().delete(formField); } /** * @see org.openmrs.api.db.FormDAO#getAllFormFields() */ @SuppressWarnings("unchecked") public List<FormField> getAllFormFields() throws DAOException { Criteria crit = sessionFactory.getCurrentSession().createCriteria(FormField.class); return crit.list(); } /** * @see org.openmrs.api.db.FormDAO#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) */ @SuppressWarnings("unchecked") 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 DAOException { Criteria crit = sessionFactory.getCurrentSession().createCriteria(Field.class); if (!forms.isEmpty()) crit.add(Expression.in("form", forms)); if (!fieldTypes.isEmpty()) crit.add(Expression.in("fieldType", fieldTypes)); if (!concepts.isEmpty()) crit.add(Expression.in("concept", concepts)); if (!tableNames.isEmpty()) crit.add(Expression.in("tableName", tableNames)); if (!attributeNames.isEmpty()) crit.add(Expression.in("attributeName", attributeNames)); if (selectMultiple != null) crit.add(Expression.eq("selectMultiple", selectMultiple)); if (!containsAllAnswers.isEmpty()) throw new APIException("containsAllAnswers must be empty because this is not yet implemented"); if (!containsAnyAnswer.isEmpty()) throw new APIException("containsAnyAnswer must be empty because this is not yet implemented"); if (retired != null) crit.add(Expression.eq("retired", retired)); return crit.list(); } /** * @see org.openmrs.api.db.FormDAO#getForm(java.lang.String, java.lang.String) */ public Form getForm(String name, String version) throws DAOException { Criteria crit = sessionFactory.getCurrentSession().createCriteria(Form.class); crit.add(Expression.eq("name", name)); crit.add(Expression.eq("version", version)); return (Form) crit.uniqueResult(); } /** * @see org.openmrs.api.db.FormDAO#getForms(java.lang.String, java.lang.Boolean, * java.util.Collection, java.lang.Boolean, java.util.Collection, java.util.Collection, * java.util.Collection) */ @SuppressWarnings("unchecked") public List<Form> getForms(String partialName, Boolean published, Collection<EncounterType> encounterTypes, Boolean retired, Collection<FormField> containingAnyFormField, Collection<FormField> containingAllFormFields, Collection<Field> fields) throws DAOException { Criteria crit = sessionFactory.getCurrentSession().createCriteria(Form.class, "form"); if (partialName != null && !"".equals(partialName)) { crit.add(Expression.or(Expression.like("name", partialName, MatchMode.START), Expression.like("name", " " + partialName, MatchMode.ANYWHERE))); } if (published != null) crit.add(Expression.eq("published", published)); if (!encounterTypes.isEmpty()) crit.add(Expression.in("encounterType", encounterTypes)); if (retired != null) crit.add(Expression.eq("retired", retired)); // TODO junit test if (!containingAnyFormField.isEmpty()) crit.add(Expression.in("formField", containingAnyFormField)); // TODO junit test //select * from form where len(containingallformfields) = (select count(*) from form_field ff where ff.form_id = form_id and form_field_id in (containingallformfields); if (!containingAllFormFields.isEmpty()) { DetachedCriteria detachedCrit = DetachedCriteria.forClass(FormField.class, "ff"); detachedCrit.setProjection(Projections.count("formFieldId")); detachedCrit.add(Expression.eqProperty("ff.formId", "form.formId")); crit.add(Subqueries.eq(containingAllFormFields.size(), detachedCrit)); } // get all forms (dupes included) that have this field on them if (!fields.isEmpty()) { Criteria crit2 = crit.createCriteria("formFields", "ff"); crit2.add(Expression.eqProperty("ff.form.formId", "form.formId")); crit2.add(Expression.in("ff.field", fields)); } return crit.list(); } /** * @see org.openmrs.api.db.FormDAO#getFieldByUuid(java.lang.String) */ public Field getFieldByUuid(String uuid) { return (Field) sessionFactory.getCurrentSession().createQuery("from Field f where f.uuid = :uuid").setString("uuid", uuid).uniqueResult(); } public FieldAnswer getFieldAnswerByUuid(String uuid) { return (FieldAnswer) sessionFactory.getCurrentSession().createQuery("from FieldAnswer f where f.uuid = :uuid") .setString("uuid", uuid).uniqueResult(); } /** * @see org.openmrs.api.db.FormDAO#getFieldTypeByUuid(java.lang.String) */ public FieldType getFieldTypeByUuid(String uuid) { return (FieldType) sessionFactory.getCurrentSession().createQuery("from FieldType ft where ft.uuid = :uuid") .setString("uuid", uuid).uniqueResult(); } /** * @see org.openmrs.api.db.FormDAO#getFormByUuid(java.lang.String) */ public Form getFormByUuid(String uuid) { return (Form) sessionFactory.getCurrentSession().createQuery("from Form f where f.uuid = :uuid").setString("uuid", uuid).uniqueResult(); } /** * @see org.openmrs.api.db.FormDAO#getFormFieldByUuid(java.lang.String) */ public FormField getFormFieldByUuid(String uuid) { return (FormField) sessionFactory.getCurrentSession().createQuery("from FormField ff where ff.uuid = :uuid") .setString("uuid", uuid).uniqueResult(); } /** * @see org.openmrs.api.db.FormDAO#getFormsByName(java.lang.String) */ @SuppressWarnings("unchecked") public List<Form> getFormsByName(String name) throws DAOException { Criteria crit = sessionFactory.getCurrentSession().createCriteria(Form.class); crit.add(Expression.eq("name", name)); crit.add(Expression.eq("retired", false)); crit.addOrder(Order.desc("version")); return crit.list(); } /** * @see org.openmrs.api.db.FormDAO#deleteFieldType(org.openmrs.FieldType) */ public void deleteFieldType(FieldType fieldType) throws DAOException { sessionFactory.getCurrentSession().delete(fieldType); } /** * @see org.openmrs.api.db.FormDAO#saveFieldType(org.openmrs.FieldType) */ public FieldType saveFieldType(FieldType fieldType) throws DAOException { sessionFactory.getCurrentSession().saveOrUpdate(fieldType); return fieldType; } }