Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

OpenMRS is intentionally built with multiple layers in mind. One of the layers is a java API that can be used in other projects just as easily as it can be inside of OpenMRS.

(TODO: Link to javadocs)
(TODO: overview of openmrs database access via objects)

Context Singleton

Services The API allows developers to interact with the complex OpenMRS ?Data Model with common Java objects.  This provides greater data integrity as well as a simple to use approach.

See the API in Javadoc form .

Java Objects vs Tables

Most of the tables in the data model have a one-to-one relationship with a Java object in the OpenMRS API.

Compare the person patient table with the person java object .  There is a "gender" column and "getGender/setGender" methods.  A "birthdate" column and "get/setBirthdate" methods.  The "person_name" table contains any number of names of a person.  You can find a list of PersonName objects on the Person object.

Persisting and Retrieving Objects

To get data into and out of the database you go through the objects.  If you want a person with id #1, you ask the PersonService for the Person object:

Code Block

PersonService personService = Context.getPersonService();

Person p = personService.getPerson(1);

If you want to change data on this person and persist that in the database, you again use the personService:

Code Block

PersonService personService = Context.getPersonService();

Person p = personService.getPerson(1);

p.setGender("M");

personService.savePerson(p);

The Services in the OpenMRS API make sure that only the correct columns are saved/updated in the database.

Context Singleton

All services are accessed in a static way from the org.openmrs.api.context.Context object.  You do not have to instantiate a new "Context" object and you do not ever call "new" on a service:

Code Block
UserService userService = Context.getUserService();
User bobObject = userService.findUser("bob");

The Context object has two primarily goals. Access to the OpenMRS services and access to the currently logged in user.

The currently logged in user:

Code Block

User u = Context.getAuthenticatedUser();

The currently logged in user's current locale:

Code Block

Locale loc = Context.getLocale();

Programming to Interfaces

All of our services are interfaces. The default implementation of these services are named *ServiceImpl.java. The implementations can be found in the impl directory of the api package.

In order to create a new implementation of a service (for whatever unknown reason that would be in the future), we would only need to change the file specified in Spring's /metadataapi/src/apimain/springresources/applicationapplicationContext-contextservices.xml file.

Authentication and Authorization

Users are authenticated against the Context in a static wayContex.

Code Block
Context.authenticate("bob", "password");

The current user's information is stored on the current thread. For the webapp, we have a special problem. Every request to the server is potentially on a new thread. Our custom filter OpenmrsFilter class wraps every request. It stores the user's UserContext on the user's session. Before each request the userContext is taken off the session and placed on the thread. After the entire request is complete, the userContext is removed from the thread (and placed back on the session).

Authorization is done through annotations on the interface:

Code Block

@Transactional
public interface UserService
...
@Authorized({"View Users"})
void List<User> getUsers(Integer userId);
...

...