Thursday, May 29, 2008

Logic Web Service API Details

Below are the details I interpreted from tracing through the various Logic Service methods like getting filters and tags as well as constructing a query to more fine tune a request. Appreciate any feedback or comments on any more details or any misinterpretations that I made.

Also, the project requirements are still a work in progress but are outlined here.

Details on the API

The org.openmrs.logic.LogicService class is an interface. The org.openmrs.logic.impl.LogicServiceImpl class is the default implementation for this interface.

The get and add methods use the org.openmrs.logic.RuleFactory to return or add their data. As a temporary hack, when initialized, the RuleFactory adds the following hard coded rules: [AGE, BIRTHDATE, DEATH DATE, GENDER, HIV POSITIVE, CAUSE OF DEATH, DEAD, BIRTHDATE ESTIMATED].

The following are details on all the get methods:

  • getDefaultDataType(String token)
    • The data type for a token is returned via RuleFactory.
    • The getDefaultDatatype method of the org.openmrs.logic.rule.Rule interface is called on the token. The AgeRule, EnrolledBeforeDateRule, HIVPositiveRule, and ReferenceRule classes all implement this class and return different data types as appropriate.
  • getLogicDataSource(String name)
  • getLogicDataSources(Map<String, LogicDataSource> logicDataSources)
    • Gets all the registered logic data sources via RuleFactory.
  • getParameterList(String token)
    • Returns the expected parameters for a rule under which the passed token is registered via RuleFactory.
    • The getParameterList method of the Rule interface is called on the token (similiar to getDefaultDataType). The AgeRule, EnrolledBeforeDateRule, HIVPositiveRule, and ReferenceRule classes all implement this class. All of these implementer classes return null when queried for the parameter list.
  • getRule(String token)
    • Pass the token under which the rule was registered.
    • Uses the RuleFactory class and returns an org.openmrs.logic.rule.ReferenceRule based on that token if the token starts with "%%".
  • getTagsByToken(String token)
    • Uses the RuleFactory class and returns all of the tags that are attached to a give token.
  • getTokens()
    • returns the Set of all hardcoded rules via the RuleFactory.
  • getTokensByTag(String tag)
    • returns the Set of all hardcoded rules that match the tag argument via the RuleFactory.

The following are the details on all the add methods:

  • addRule(String token, Rule rule)
    • Uses RuleFactory to first make sure that rule doesn't already exist.
    • If rule does not already exist, the rule is registered under the given token.
  • addRule(String token, String[] tags, Rule rule)
    • Same as addRule method described above except for it assigns given tag(s) to the rule at the same time.
  • addTokenTag(String token, String tag)
    • Uses RuleFactory to add a tag to a previously registered token.

There are many eval methods that are used to filter the token/tag data to return specific information. The org.openmrs.logic.LogicCriteria class is used to setup the criteria for the filtering. The eval methods are basically a series of methods that massage the query to eventually use org.openmrs.logic.LogicContext to evaluate a rule with LogicCriteria for a single patient. The evaluations can be done for a single patient or a list of patients (cohort). The following are more details on the eval methods:

  • Single patient
    • eval(Patient who, String token)
      • Gets information for a given token for a given patient.
      • A LogicCriteria object is created based on the token.
      • Uses eval(Patient who, LogicCriteria lc) discussed below.
    • eval(Patient who, String token, Map<String, Object> parameters)
      • Gets information for a given token and parameters for a given patient.
      • A LogicCriteria object is created based on the token and parameters.
      • Uses eval(Patient who, LogicCriteria lc) discussed below.
    • eval(Patient who, LogicCriteria criteria)
      • Evaluates a query for a given patient.
      • Uses eval(Patient who, LogicCriteria criteria, Map<String, Object> parameters) discussed below.
    • eval(Patient who, LogicCriteria criteria, Map<String, Object> parameters)
      • Creates a LogicContext object with the given patient.
      • The query is evaluated via the LogicContext object and an org.openmrs.logic.result.Result is returned.
  • List of patients
    • eval(Cohort who, String token)
      • Gets information for a given token for a list of patients.
      • A LogicCriteria object is created based on the token.
      • Uses eval(Cohort who, LogicCriteria criteria) discussed below.
    • eval(Cohort who, String token, Map<String, Object> parameters)
      • Gets information for a given token and parameters for a list of patients.
      • A LogicCriteria objects is created based on the token and parameters.
      • Uses eval(Cohort who, LogicCriteria criteria) discussed below.
    • eval(Cohort who, LogicCriteria criteria)
      • Evaluates a query for a list of patients.
      • Uses eval (Cohort who, LogicCriteria criteria, Map<String, Object> parameters) discussed below.
    • eval(Cohort who, LogicCriteria criteria, Map<String, Object> parameters)
      • Creates a LogicContext object with the list of patients.
      • The query is evaluated for via the LogicContext object for each patient id and a Map of Result and patient id pairs are returned.
    • eval(Cohort who, List<LogicCriteria> criterias)
      • This is similiar to the previous eval discussed above except that it evaluates a collection of queries instead of a single query for a set of patients.
      • Each query is evaluated via the LogicContext object for each id and a Map of each LogicCriteria is paired with a Map of Result and patient id pairs.

The LogicContext is what does the "work" for all the above discussed eval methods of the LogicService implementation. It evaluates a rule with criteria and parameters for a single patient. Each rule is evaluated as appropritate depending on the implementing class (AgeRule, EnrolledBeforeDateRule, HIVPositiveRule, and ReferenceRule). The Result from each class is put in a patient id / Result map. The LogicCriteria is then applied to these results via the private applyCriteria() method of the LogicContext class. For now, this method looks like it doesn't do anything and just returns the results without applying the criteria.

The following are some other miscellaneous methods:

  • findToken(String token)
    • Returns all known tokens based on the lookup string passed.
    • Uses the RuleFactory class to look through the registered tokens and return the Set that matches the lookup string.
  • findTags(String partialTag)
    • Returns a Set of tags based on the lookup string passed.
    • Uses the RuleFactory class to look through the tags and find tags that match the lookup string.
  • updateRule(String token, Rule rule)
    • Looks up the rule based on the token passed and replaces it with the rule passed.
    • The RuleFactory class makes sure that it exists and updates with the new rule if it does.
  • removeRule(String token)
    • Removes a rule for the token passed.
    • The RuleFactory class makes sure that the rule to be removed exists and removes it from the rule map if it does.
  • removeTokenTag(String token, String tag)
    • Removes a token's previously assigned tag.
    • The RuleFactory class makes sure that the the token had the given tag and then removes it.
  • registerLogicDataSource(String name, LogicDataSource logicDataSource)
    • Adds a LogicDataSource to the logic service with the given name.
  • setLogicDataSources()
    • Adds multiple LogicDataSource objects to the current data sources in the logic service.
    • Uses registerLogicDataSource method discussed above.
  • removeLogicDataSource()
    • Removes a logic data source from the list.