Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ mvn clean package
* Metadata Sharing 1.2.2 (*compatible*)
* Metadata Mapping 1.3.4 (*compatible*)
* Open Concept Lab 1.2.9 (*compatible*)
* Providermanagement 2.13.0 (*compatible*)

### Test your OpenMRS configs
See the [Initializer Validator README page](readme/validator.md).
Expand Down Expand Up @@ -219,6 +220,7 @@ See the [documentation on Initializer's logging properties](readme/rtprops.md#lo
* Support enhanced methods for loading htmlforms when running htmlformentry 5.5.0+
* Support loading drug ingredients within the drug domain, for compatible OpenMRS versions
* Moved the form name translation loader to the preload function to support loading form names on instance restarts
* Updated providerroles domain to support core ProviderRoles from OpenMRS 2.8.2+

#### Version 2.9.0
* Fix for InitializerSerializer to ensure compatibility with OpenMRS version 2.7.0+
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
package org.openmrs.module.initializer.api.providerroles;

import org.apache.commons.beanutils.PropertyUtils;
import org.openmrs.BaseOpenmrsMetadata;
import org.openmrs.OpenmrsMetadata;
import org.openmrs.OpenmrsObject;
import org.openmrs.ProviderAttributeType;
import org.openmrs.RelationshipType;
import org.openmrs.User;

import java.util.Date;
import java.util.Set;

/**
* This class provides an abstraction around a ProviderRole, whether that is the ProviderRole
* defined in OpenMRS 2.8 without the providermanagement module running, the ProviderRole defined in
* OpenMRS 2.8 that is extended by the providermanagement module, or the ProviderRole defined only
* in the providermanagement module (providermanagement < 4.0.0 and core < 2.8.0)
*/
public class ProviderRoleAdapter extends BaseOpenmrsMetadata {

private final OpenmrsMetadata providerRole;

public ProviderRoleAdapter(OpenmrsMetadata providerRole) {
this.providerRole = providerRole;
}

public OpenmrsMetadata getProviderRole() {
return providerRole;
}

@Override
public Integer getId() {
return providerRole.getId();
}

@Override
public void setId(Integer id) {
providerRole.setId(id);
}

@Override
public String getName() {
return providerRole.getName();
}

@Override
public void setName(String name) {
providerRole.setName(name);
}

@Override
public String getDescription() {
return providerRole.getDescription();
}

@Override
public void setDescription(String description) {
providerRole.setDescription(description);
}

@Override
public User getCreator() {
return providerRole.getCreator();
}

@Override
public void setCreator(User creator) {
providerRole.setCreator(creator);
}

@Override
public Date getDateCreated() {
return providerRole.getDateCreated();
}

@Override
public void setDateCreated(Date dateCreated) {
providerRole.setDateCreated(dateCreated);
}

@Override
public User getChangedBy() {
return providerRole.getChangedBy();
}

@Override
public void setChangedBy(User changedBy) {
providerRole.setChangedBy(changedBy);
}

@Override
public Date getDateChanged() {
return providerRole.getDateChanged();
}

@Override
public void setDateChanged(Date dateChanged) {
providerRole.setDateChanged(dateChanged);
}

@Override
public Boolean isRetired() {
return providerRole.isRetired();
}

@Override
public Boolean getRetired() {
return providerRole.getRetired();
}

@Override
public void setRetired(Boolean retired) {
providerRole.setRetired(retired);
}

@Override
public Date getDateRetired() {
return providerRole.getDateRetired();
}

@Override
public void setDateRetired(Date dateRetired) {
providerRole.setDateRetired(dateRetired);
}

@Override
public User getRetiredBy() {
return providerRole.getRetiredBy();
}

@Override
public void setRetiredBy(User retiredBy) {
providerRole.setRetiredBy(retiredBy);
}

@Override
public String getRetireReason() {
return providerRole.getRetireReason();
}

@Override
public void setRetireReason(String retireReason) {
providerRole.setRetireReason(retireReason);
}

@Override
public String getUuid() {
return providerRole.getUuid();
}

@Override
public void setUuid(String uuid) {
providerRole.setUuid(uuid);
}

@Override
public int hashCode() {
return providerRole.hashCode();
}

@Override
public boolean equals(Object obj) {
return obj.getClass() == providerRole.getClass() && providerRole.equals(obj);
}

@Override
public String toString() {
return providerRole.toString();
}

@SuppressWarnings("unchecked")
public Set<RelationshipType> getRelationshipTypes() {
try {
return (Set<RelationshipType>) PropertyUtils.getProperty(providerRole, "relationshipTypes");
}
catch (Exception e) {
throw new RuntimeException(e);
}
}

public void setRelationshipTypes(Set<RelationshipType> relationshipTypes) {
try {
PropertyUtils.setProperty(providerRole, "relationshipTypes", relationshipTypes);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}

@SuppressWarnings("unchecked")
public Set<OpenmrsObject> getSuperviseeProviderRoles() {
try {
return (Set<OpenmrsObject>) PropertyUtils.getProperty(providerRole, "superviseeProviderRoles");
}
catch (Exception e) {
throw new RuntimeException(e);
}
}

public void setSuperviseeProviderRoles(Set<OpenmrsObject> superviseeProviderRoles) {
try {
PropertyUtils.setProperty(providerRole, "superviseeProviderRoles", superviseeProviderRoles);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}

@SuppressWarnings("unchecked")
public Set<ProviderAttributeType> getProviderAttributeTypes() {
try {
return (Set<ProviderAttributeType>) PropertyUtils.getProperty(providerRole, "providerAttributeTypes");
}
catch (Exception e) {
throw new RuntimeException(e);
}
}

public void setProviderAttributeTypes(Set<ProviderAttributeType> providerAttributeTypes) {
try {
PropertyUtils.setProperty(providerRole, "providerAttributeTypes", providerAttributeTypes);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package org.openmrs.module.initializer.api.providerroles;

import org.openmrs.OpenmrsMetadata;
import org.openmrs.api.ProviderService;
import org.openmrs.api.context.Context;
import org.openmrs.util.OpenmrsClassLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
* This provides an abstraction layer over determining what service methods should be called for working with
* ProviderRole objects, and what object type a ProviderRole is instantiated into.
* This supports both core ProviderRole objects in OpenMRS 2.8.2+, while also supporting the original ProviderRole
* object defined in providermanagement < 4.0.0 and the revised ProviderManagementProviderRole type that is present
* in providermanagement 4.0.0+ and which extends the OpenMRS 2.8 ProviderRole class
*/
public class ProviderRoleServiceAdapter {

protected final static Logger log = LoggerFactory.getLogger(ProviderRoleServiceAdapter.class);

/**
* @return the ProviderManagementService from providermanagement if found, otherwise the ProviderService from core
*/
public Object getService() {
String providerManagementService = "org.openmrs.module.providermanagement.api.ProviderManagementService";
String providerService = ProviderService.class.getName();
Class<?> clazz = loadFirstFoundClass(providerManagementService, providerService);
return Context.getRegisteredComponents(clazz).get(0);
}

/**
* @return the providermanagement.ProviderRole class if found (providermanagement < 4.0.0, if not found, then
* the providermanagement.ProviderManagementProviderRole class if found (providermanagement >= 4.0.0).
* if not found, then this returns the core ProviderRole object if found.
* If none found, this throws an exception, as no support exists for ProviderRoles at runtime
*/
public ProviderRoleAdapter newProviderRoleAdapter() {
String providerRole1 = "org.openmrs.module.providermanagement.ProviderRole";
String providerRole2 = "org.openmrs.module.providermanagement.ProviderManagementProviderRole";
String providerRole3 = "org.openmrs.ProviderRole";
Class<?> clazz = loadFirstFoundClass(providerRole1, providerRole2, providerRole3);
try {
OpenmrsMetadata providerRoleInstance = (OpenmrsMetadata) clazz.newInstance();
return new ProviderRoleAdapter(providerRoleInstance);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}

/**
* @param uuid the uuid of the provider role
* @return the provider role instance returned from the appropriate service
*/
public OpenmrsMetadata getProviderRoleByUuid(String uuid) {
Object providerRole = invokeMethod(getService(), "getProviderRoleByUuid", uuid);
return (OpenmrsMetadata) providerRole;
}

/**
* Saves the providerRole contained within the given ProviderRoleAdapter
* @param providerRole the ProviderRoleAdapter instance that contains the ProviderRole to save
*/
public void saveProviderRole(ProviderRoleAdapter providerRole) {
invokeMethod(getService(), "saveProviderRole", providerRole.getProviderRole());
}

/**
* Takes in an array of class names and attempts to load each in order. Returns the first that loads
* successfully, otherwise throws an exception
*/
private Class<?> loadFirstFoundClass(String... classesToLoad) {
for (String className : classesToLoad) {
try {
return OpenmrsClassLoader.getInstance().loadClass(className);
}
catch (Exception e) {
log.debug("Class {} not found", className);
}
}
throw new RuntimeException("None of the matching classes were found: " + Arrays.toString(classesToLoad));
}

/**
* Retrieves the method with the given name from the given class. If the method name is not found or
* is not unique, throws an exception
*/
private Object invokeMethod(Object object, String methodName, Object... arguments) {
Class<?> clazz = object.getClass();
Class<?>[] parameterTypes = new Class[arguments.length];
for (int i = 0; i < arguments.length; i++) {
parameterTypes[i] = arguments[i].getClass();
}
try {
Method method = clazz.getMethod(methodName, parameterTypes);
return method.invoke(object, arguments);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Loading