/**
* 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.logic.datasource;
import java.util.Collection;
import java.util.Map;
import org.openmrs.Cohort;
import org.openmrs.logic.LogicContext;
import org.openmrs.logic.LogicCriteria;
import org.openmrs.logic.LogicException;
import org.openmrs.logic.result.Result;
/**
* Provides data to the logic service engine. Each data source is responsible for exposing a set of
* keys to the logic service and delivering results to the logic service engine upon request.
* Requests to the data source reference the evaluation context, a patient cohort, and criteria.
* <ul>
* <li><strong>Context.</strong> The evaluation context (org.openmrs.logic.LogicContext) defines the
* index date and any global parameters. All criteria should be applied as if the current date is
* the index date, allowing for retrospective queries.</li>
* <li><strong>Cohort.</strong> The list of patients for which results should be returned</li>
* <li><strong>Criteria.</strong> A chain of criteria to be applied to the results, passed to the
* data source, since each data source knows how to apply these criteria in the most efficient
* matter.</li>
* </ul>
* Keys (and their subsequent results) work best if they are well documented and maximize the re-use
* of data. For example, consider a data source that has access to a historical listing of pharmacy
* visits for patients. For each visit to the name of the pharmacy, the date of the visit and the
* number of prescriptions filled at that visit are known. You might want to make a key for each
* attribute, e.g.
* <ul>
* <li><strong>pharmacy</strong> — returns a text result with the name of the pharmacy</li>
* <li><strong>visit date</strong> — returns a date result with the date of the pharmacy visit
* </li>
* <li><strong>number of prescriptions</strong — returns a numeric result with the number of
* prescriptions filled</li>
* </ul>
* A consumer of the logic service could then use
*
* <pre>
* Context.getLogicService().eval(myPatient, "@pharmacy visit.pharmacy");
* </pre>
*
* to get a list of the names of pharamacies visited by the patient. However, this limits the ways
* we can use the result. On the other hand, consider defining the key:
* <ul>
* <li><strong>visit</strong> — returns a text result with the result date equal to the
* pharmacy visit date, the text value equal to the name of the pharmacy, and the numeric result
* overloaded with the number of prescriptions filled at the pharmacy visit.
* </ul>
* Now a consumer of the logic service can use the same result in several different ways:
*
* <pre>
*
* Result result = Context.getLogicService().eval(myPatient, "@pharmacy visit.visit");
*
* Result lastVisit = result.latest();
*
* Date dateOfVisit = result.getResultDate();
*
* String pharmacy = result.toString();
*
* int numberOfPrescriptions = result.toNumber();
* </pre>
*
* One way to approach the design of a new data service is to avoid thinking of the individual
* attributes, but rather think about turning the data into the fewest number of observations (a key
* for each) filled with as much data as possible. Remember that you can overload values within
* results; however, such overloading should aim to be as intuitive as possible and well documented.
* New logic data sources should be documented on the <a
* href="http://openmrs.org/wiki/Logic_Data_Sources">OpenMRS wiki</a>, including a description of
* the keys available from the data source as well as the characteristics of the result returned for
* each key.
*/
public interface LogicDataSource {
/**
* The name by which this data source should be registered when it is loaded.
* Implementations should override this like
* public static final String NAME = "person";
*/
public static String NAME = "org.openmrs.logic.LogicDataSource.name";
/**
* Extracts data from the data source. Actually, this function only checks for cached data and
* forwards all non-cached requests to its subclass(es).
*
* @param context the current logic context
* @param patients Cohort of Patient(s) for whom to perform the queries
* @param criteria <code>LogicCriteria</code> identifying which data is to be extracted
* @return <code>Map</code> of results for each patient, grouped by requested data element
*/
public Map<Integer, Result> read(LogicContext context, Cohort patients, LogicCriteria criteria) throws LogicException;
public abstract Collection<String> getKeys();
public boolean hasKey(String key);
public abstract int getDefaultTTL();
}