Skip to content

Instantly share code, notes, and snippets.

@collinsnji
Created December 16, 2016 20:20
Show Gist options
  • Save collinsnji/041e07489fe381df76dd74f40614bf98 to your computer and use it in GitHub Desktop.
Save collinsnji/041e07489fe381df76dd74f40614bf98 to your computer and use it in GitHub Desktop.
find bugs diff
diff --git a/api/src/main/java/org/openmrs/Encounter.java b/api/src/main/java/org/openmrs/Encounter.java
index 913724a..692d96c 100644
--- a/api/src/main/java/org/openmrs/Encounter.java
+++ b/api/src/main/java/org/openmrs/Encounter.java
@@ -19,7 +19,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.Deque;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
@@ -36,41 +35,41 @@ import java.util.Set;
* @see Order
*/
public class Encounter extends BaseOpenmrsData {
-
+
public static final long serialVersionUID = 2L;
-
+
// Fields
-
+
private Integer encounterId;
private Date encounterDatetime;
-
+
private Patient patient;
-
+
private Integer patientId;
-
+
private Location location;
-
+
private Form form;
-
+
private EncounterType encounterType;
-
+
private Set<Order> orders;
-
+
@AllowDirectAccess
private Set<Obs> obs;
-
+
private Visit visit;
-
+
@DisableHandlers(handlerTypes = { VoidHandler.class })
private Set<EncounterProvider> encounterProviders = new LinkedHashSet<EncounterProvider>();
-
+
// Constructors
-
+
/** default constructor */
public Encounter() {
}
-
+
/**
* @param encounterId
* @should set encounter id
@@ -78,65 +77,65 @@ public class Encounter extends BaseOpenmrsData {
public Encounter(Integer encounterId) {
this.encounterId = encounterId;
}
-
+
// Property accessors
-
+
/**
* @return Returns the encounterDatetime.
*/
public Date getEncounterDatetime() {
return encounterDatetime;
}
-
+
/**
* @param encounterDatetime The encounterDatetime to set.
*/
public void setEncounterDatetime(Date encounterDatetime) {
this.encounterDatetime = encounterDatetime;
}
-
+
/**
* @return Returns the encounterId.
*/
public Integer getEncounterId() {
return encounterId;
}
-
+
/**
* @param encounterId The encounterId to set.
*/
public void setEncounterId(Integer encounterId) {
this.encounterId = encounterId;
}
-
+
/**
* @return Returns the encounterType.
*/
public EncounterType getEncounterType() {
return encounterType;
}
-
+
/**
* @param encounterType The encounterType to set.
*/
public void setEncounterType(EncounterType encounterType) {
this.encounterType = encounterType;
}
-
+
/**
* @return Returns the location.
*/
public Location getLocation() {
return location;
}
-
+
/**
* @param location The location to set.
*/
public void setLocation(Location location) {
this.location = location;
}
-
+
/**
* @return Returns a Set&lt;Obs&gt; of all non-voided, non-obsGroup children Obs of this Encounter
* @should not return null with null obs set
@@ -151,7 +150,7 @@ public class Encounter extends BaseOpenmrsData {
*/
public Set<Obs> getObs() {
Set<Obs> ret = new LinkedHashSet<>();
-
+
if (this.obs != null) {
for (Obs o : this.obs) {
ret.addAll(getObsLeaves(o));
@@ -160,10 +159,10 @@ public class Encounter extends BaseOpenmrsData {
//if (o.isVoided() == false && o.isObsGrouping() == false)
// ret.add(o);
}
-
+
return ret;
}
-
+
/**
* Convenience method to recursively get all leaf obs of this encounter. This method goes down
* into each obs and adds all non-grouping obs to the return list
@@ -173,7 +172,7 @@ public class Encounter extends BaseOpenmrsData {
*/
private List<Obs> getObsLeaves(Obs obsParent) {
List<Obs> leaves = new ArrayList<Obs>();
-
+
if (obsParent.hasGroupMembers()) {
for (Obs child : obsParent.getGroupMembers()) {
if (!child.isVoided()) {
@@ -188,10 +187,10 @@ public class Encounter extends BaseOpenmrsData {
} else if (!obsParent.isVoided()) {
leaves.add(obsParent);
}
-
+
return leaves;
}
-
+
/**
* Returns all Obs where Obs.encounterId = Encounter.encounterId In practice, this method should
* not be used very often...
@@ -208,9 +207,9 @@ public class Encounter extends BaseOpenmrsData {
if (includeVoided && obs != null) {
return obs;
}
-
+
Set<Obs> ret = new LinkedHashSet<>();
-
+
if (this.obs != null) {
for (Obs o : this.obs) {
if (includeVoided) {
@@ -222,7 +221,7 @@ public class Encounter extends BaseOpenmrsData {
}
return ret;
}
-
+
/**
* Convenience method to call {@link #getAllObs(boolean)} with a false parameter
*
@@ -232,7 +231,7 @@ public class Encounter extends BaseOpenmrsData {
public Set<Obs> getAllObs() {
return getAllObs(false);
}
-
+
/**
* Returns a Set&lt;Obs&gt; of all root-level Obs of an Encounter, including obsGroups
*
@@ -254,14 +253,14 @@ public class Encounter extends BaseOpenmrsData {
}
return ret;
}
-
+
/**
* @param obs The obs to set.
*/
public void setObs(Set<Obs> obs) {
this.obs = obs;
}
-
+
/**
* Add the given Obs to the list of obs for this Encounter.
*
@@ -277,30 +276,30 @@ public class Encounter extends BaseOpenmrsData {
if (obs == null) {
obs = new LinkedHashSet<>();
}
-
+
if (observation != null) {
obs.add(observation);
-
+
//Propagate some attributes to the obs and any groupMembers
-
+
// a Deque is a two-ended queue, that lets us add to the end, and fetch from the beginning
Deque<Obs> obsToUpdate = new ArrayDeque<Obs>();
obsToUpdate.add(observation);
-
+
//prevent infinite recursion if an obs is its own group member
Set<Obs> seenIt = new LinkedHashSet<>();
-
+
while (!obsToUpdate.isEmpty()) {
Obs o = obsToUpdate.removeFirst();
-
+
//has this obs already been processed?
if (o == null || seenIt.contains(o)) {
continue;
}
seenIt.add(o);
-
+
o.setEncounter(this);
-
+
//if the attribute was already set, preserve it
//if not, inherit the values sfrom the encounter
if (o.getObsDatetime() == null) {
@@ -312,16 +311,16 @@ public class Encounter extends BaseOpenmrsData {
if (o.getLocation() == null) {
o.setLocation(getLocation());
}
-
+
//propagate attributes to all group members as well
if (o.getGroupMembers(true) != null) {
obsToUpdate.addAll(o.getGroupMembers());
}
}
-
+
}
}
-
+
/**
* Remove the given observation from the list of obs for this Encounter
*
@@ -335,7 +334,7 @@ public class Encounter extends BaseOpenmrsData {
obs.remove(observation);
}
}
-
+
/**
* @return Returns the orders
*/
@@ -345,14 +344,14 @@ public class Encounter extends BaseOpenmrsData {
}
return orders;
}
-
+
/**
* @param orders The orders to set.
*/
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
-
+
/**
* Add the given Order to the list of orders for this Encounter
*
@@ -369,7 +368,7 @@ public class Encounter extends BaseOpenmrsData {
getOrders().add(order);
}
}
-
+
/**
* Remove the given observation from the list of orders for this Encounter
*
@@ -383,14 +382,14 @@ public class Encounter extends BaseOpenmrsData {
orders.remove(order);
}
}
-
+
/**
* @return Returns the patient.
*/
public Patient getPatient() {
return patient;
}
-
+
/**
* @param patient The patient to set.
*/
@@ -398,10 +397,10 @@ public class Encounter extends BaseOpenmrsData {
this.patient = patient;
this.patientId = patient.getPersonId();
}
-
+
/**
* Basic property accessor for encounterProviders. The convenience methods getProvidersByRoles
- * and getProvidersByRole are the preferred methods for getting providers. This getter is
+ * and getProvidersByRole are the preferred methods for getting providers. This getter is
* provided as a convenience for treating this like a DTO
*
* @return list of all existing providers on this encounter
@@ -412,7 +411,7 @@ public class Encounter extends BaseOpenmrsData {
public Set<EncounterProvider> getEncounterProviders() {
return encounterProviders;
}
-
+
/**
* Basic property setter for encounterProviders. The convenience methods addProvider,
* removeProvider, and setProvider are the preferred methods for adding/removing providers. This
@@ -448,21 +447,21 @@ public class Encounter extends BaseOpenmrsData {
}
return activeEncounterProviders;
}
-
+
/**
* @return Returns the form.
*/
public Form getForm() {
return form;
}
-
+
/**
* @param form The form to set.
*/
public void setForm(Form form) {
this.form = form;
}
-
+
/**
* @see java.lang.Object#toString()
* @should not fail with empty object
@@ -480,25 +479,25 @@ public class Encounter extends BaseOpenmrsData {
ret += "num Orders: " + this.getOrders().size() + " ";
return "Encounter: [" + ret + "]";
}
-
+
/**
* @since 1.5
* @see org.openmrs.OpenmrsObject#getId()
*/
public Integer getId() {
-
+
return getEncounterId();
}
-
+
/**
* @since 1.5
* @see org.openmrs.OpenmrsObject#setId(java.lang.Integer)
*/
public void setId(Integer id) {
setEncounterId(id);
-
+
}
-
+
/**
* Gets the visit.
*
@@ -508,7 +507,7 @@ public class Encounter extends BaseOpenmrsData {
public Visit getVisit() {
return visit;
}
-
+
/**
* Sets the visit
*
@@ -518,7 +517,7 @@ public class Encounter extends BaseOpenmrsData {
public void setVisit(Visit visit) {
this.visit = visit;
}
-
+
/**
* Gets all unvoided providers, grouped by role.
*
@@ -530,7 +529,7 @@ public class Encounter extends BaseOpenmrsData {
public Map<EncounterRole, Set<Provider>> getProvidersByRoles() {
return getProvidersByRoles(false);
}
-
+
/**
* Gets all providers, grouped by role.
*
@@ -541,26 +540,26 @@ public class Encounter extends BaseOpenmrsData {
* @should return all roles and providers
*/
public Map<EncounterRole, Set<Provider>> getProvidersByRoles(boolean includeVoided) {
-
+
Map<EncounterRole, Set<Provider>> providers = new HashMap<EncounterRole, Set<Provider>>();
for (EncounterProvider encounterProvider : encounterProviders) {
-
+
if (!includeVoided && encounterProvider.getVoided()) {
continue;
}
-
+
Set<Provider> list = providers.get(encounterProvider.getEncounterRole());
if (list == null) {
list = new LinkedHashSet<Provider>();
providers.put(encounterProvider.getEncounterRole(), list);
}
-
+
list.add(encounterProvider.getProvider());
}
-
+
return providers;
}
-
+
/**
* Gets unvoided providers who had the given role in this encounter.
*
@@ -574,7 +573,7 @@ public class Encounter extends BaseOpenmrsData {
public Set<Provider> getProvidersByRole(EncounterRole role) {
return getProvidersByRole(role, false);
}
-
+
/**
* Gets providers who had the given role in this encounter.
*
@@ -588,20 +587,20 @@ public class Encounter extends BaseOpenmrsData {
*/
public Set<Provider> getProvidersByRole(EncounterRole role, boolean includeVoided) {
Set<Provider> providers = new LinkedHashSet<Provider>();
-
+
for (EncounterProvider encounterProvider : encounterProviders) {
if (encounterProvider.getEncounterRole().equals(role)) {
if (!includeVoided && encounterProvider.getVoided()) {
continue;
}
-
+
providers.add(encounterProvider.getProvider());
}
}
-
+
return providers;
}
-
+
/**
* Adds a new provider for the encounter, with the given role.
*
@@ -627,7 +626,7 @@ public class Encounter extends BaseOpenmrsData {
encounterProvider.setCreator(Context.getAuthenticatedUser());
encounterProviders.add(encounterProvider);
}
-
+
/**
* Sets the provider for the given role.
* <p>
@@ -654,12 +653,12 @@ public class Encounter extends BaseOpenmrsData {
}
}
}
-
+
if (!hasProvider) {
addProvider(role, provider);
}
}
-
+
/**
* Removes the provider for a given role.
*
@@ -678,7 +677,7 @@ public class Encounter extends BaseOpenmrsData {
}
}
}
-
+
/**
* Copied encounter will not have visit field copied.
*
@@ -689,7 +688,7 @@ public class Encounter extends BaseOpenmrsData {
*/
public Encounter copyAndAssignToAnotherPatient(Patient patient) {
Encounter target = new Encounter();
-
+
target.setChangedBy(getChangedBy());
target.setCreator(getCreator());
target.setDateChanged(getDateChanged());
@@ -698,23 +697,23 @@ public class Encounter extends BaseOpenmrsData {
target.setVoided(getVoided());
target.setVoidedBy(getVoidedBy());
target.setVoidReason(getVoidReason());
-
+
// Encounter specific data
target.setEncounterDatetime(getEncounterDatetime());
target.setEncounterType(getEncounterType());
target.setForm(getForm());
target.setLocation(getLocation());
target.setPatient(patient);
-
+
//encounter providers
for (EncounterProvider encounterProvider : getEncounterProviders()) {
EncounterProvider encounterProviderCopy = encounterProvider.copy();
encounterProviderCopy.setEncounter(target);
target.getEncounterProviders().add(encounterProviderCopy);
}
-
+
Context.getEncounterService().saveEncounter(target);
-
+
//obs
for (Obs obs : getAllObs()) {
Obs obsCopy = Obs.newInstance(obs);
@@ -722,7 +721,7 @@ public class Encounter extends BaseOpenmrsData {
obsCopy.setPerson(patient);
target.addObs(obsCopy);
}
-
+
return target;
}
@@ -746,10 +745,10 @@ public class Encounter extends BaseOpenmrsData {
orderGroupList.addAll(orderGroups.values());
return orderGroupList;
}
-
+
/**
* Takes in a list of orders and filters out the orders which have orderGroups
- *
+ *
* @since 1.12
* @return list of orders not having orderGroups
*/
diff --git a/api/src/main/java/org/openmrs/api/AdministrationService.java b/api/src/main/java/org/openmrs/api/AdministrationService.java
index 0f33b31..90962e8 100644
--- a/api/src/main/java/org/openmrs/api/AdministrationService.java
+++ b/api/src/main/java/org/openmrs/api/AdministrationService.java
@@ -25,65 +25,64 @@ import org.openmrs.util.HttpClient;
import org.openmrs.util.OpenmrsConstants;
import org.openmrs.util.PrivilegeConstants;
import org.openmrs.validator.ValidateUtil;
-import org.springframework.cache.annotation.Cacheable;
import org.springframework.validation.Errors;
/**
* Contains methods pertaining to doing some administrative tasks in OpenMRS
* <p>
* Use:<br>
- *
+ *
* <pre>
- *
+ *
* List&lt;GlobalProperty&gt; globalProperties = Context.getAdministrationService().getGlobalProperties();
* </pre>
- *
+ *
* @see org.openmrs.api.context.Context
*/
public interface AdministrationService extends OpenmrsService {
-
+
/**
* Used by Spring to set the specific/chosen database access implementation
- *
+ *
* @param dao The dao implementation to use
*/
public void setAdministrationDAO(AdministrationDAO dao);
-
+
/**
* Get a global property by its uuid. There should be only one of these in the database (well,
* in the world actually). If multiple are found, an error is thrown.
- *
+ *
* @return the global property matching the given uuid
* @should find object given valid uuid
* @should return null if no object found with given uuid
*/
public GlobalProperty getGlobalPropertyByUuid(String uuid) throws APIException;
-
+
/**
* Get a listing or important variables used in openmrs
- *
+ *
* @return a map from variable name to variable value
* @should return all registered system variables
*/
-
+
@Authorized(PrivilegeConstants.VIEW_ADMIN_FUNCTIONS)
public SortedMap<String, String> getSystemVariables() throws APIException;
-
+
/**
* Get a map of all the System Information. Java, user, time, runtime properties, etc
- *
+ *
* @return a map from variable name to a map of the information
* @should return all system information
*/
@Authorized(PrivilegeConstants.VIEW_ADMIN_FUNCTIONS)
public Map<String, Map<String, String>> getSystemInformation() throws APIException;
-
+
/**
* Gets the global property that has the given <code>propertyName</code>.
* <p>
* If <code>propertyName</code> is not found in the list of Global Properties currently in the
* database, a null value is returned. This method should not have any authorization check.
- *
+ *
* @param propertyName property key to look for
* @return value of property returned or null if none
* @see #getGlobalProperty(String, String)
@@ -92,7 +91,7 @@ public interface AdministrationService extends OpenmrsService {
* @should get property in case insensitive way
*/
public String getGlobalProperty(String propertyName) throws APIException;
-
+
/**
* Gets the global property that has the given <code>propertyName</code>
* <p>
@@ -100,7 +99,7 @@ public interface AdministrationService extends OpenmrsService {
* <code>defaultValue</code> is returned
* <p>
* This method should not have any authorization check
- *
+ *
* @param propertyName property key to look for
* @param defaultValue value to return if propertyName is not found
* @return value of propertyName property or defaultValue if none
@@ -108,48 +107,48 @@ public interface AdministrationService extends OpenmrsService {
* @should not fail with null default value
*/
public String getGlobalProperty(String propertyName, String defaultValue) throws APIException;
-
+
/**
* Gets the global property that has the given <code>propertyName</code>
- *
+ *
* @param propertyName property key to look for
* @return the global property that matches the given <code>propertyName</code>
* @should return null when no global property match given property name
*/
public GlobalProperty getGlobalPropertyObject(String propertyName);
-
+
/**
* Gets all global properties that begin with <code>prefix</code>.
- *
+ *
* @param prefix The beginning of the property name to match.
* @return a <code>List</code> of <code>GlobalProperty</code>s that match <code>prefix</code>
* @since 1.5
* @should return all relevant global properties in the database
*/
public List<GlobalProperty> getGlobalPropertiesByPrefix(String prefix);
-
+
/**
* Gets all global properties that end with <code>suffix</code>.
- *
+ *
* @param suffix The end of the property name to match.
* @return a <code>List</code> of <code>GlobalProperty</code>s that match <code>.*suffix</code>
* @since 1.6
* @should return all relevant global properties in the database
*/
public List<GlobalProperty> getGlobalPropertiesBySuffix(String suffix);
-
+
/**
* Get a list of all global properties in the system
- *
+ *
* @return list of global properties
* @should return all global properties in the database
*/
@Authorized(PrivilegeConstants.GET_GLOBAL_PROPERTIES)
public List<GlobalProperty> getAllGlobalProperties() throws APIException;
-
+
/**
* Save the given list of global properties to the database.
- *
+ *
* @param props list of GlobalProperty objects to save
* @return the saved global properties
* @should save all global properties to the database
@@ -159,31 +158,31 @@ public interface AdministrationService extends OpenmrsService {
*/
@Authorized(PrivilegeConstants.MANAGE_GLOBAL_PROPERTIES)
public List<GlobalProperty> saveGlobalProperties(List<GlobalProperty> props) throws APIException;
-
+
/**
* Completely remove the given global property from the database
- *
+ *
* @param globalProperty the global property to delete/remove from the database
* @throws APIException
* @should delete global property from database
*/
@Authorized(PrivilegeConstants.PURGE_GLOBAL_PROPERTIES)
public void purgeGlobalProperty(GlobalProperty globalProperty) throws APIException;
-
+
/**
* Completely remove the given global properties from the database
- *
+ *
* @param globalProperties the global properties to delete/remove from the database
* @throws APIException
* @should delete global properties from database
*/
@Authorized(PrivilegeConstants.PURGE_GLOBAL_PROPERTIES)
public void purgeGlobalProperties(List<GlobalProperty> globalProperties) throws APIException;
-
+
/**
* Save the given global property to the database. If the global property already exists,
* then it will be overwritten
- *
+ *
* @param propertyName the name of the global property to save
* @param propertyValue the value of the global property to save
* @should create global property in database
@@ -191,7 +190,7 @@ public interface AdministrationService extends OpenmrsService {
* @should save a global property whose typed value is handled by a custom datatype
*/
public void setGlobalProperty(String propertyName, String propertyValue);
-
+
/**
* Overwrites the value of the global property if it already exists. If the global property does
* not exist, an exception will be thrown
@@ -204,10 +203,10 @@ public interface AdministrationService extends OpenmrsService {
* @should update a global property whose typed value is handled by a custom datatype
*/
public void updateGlobalProperty(String propertyName, String propertyValue) throws IllegalStateException;
-
+
/**
* Save the given global property to the database
- *
+ *
* @param gp global property to save
* @return the saved global property
* @throws APIException
@@ -219,27 +218,27 @@ public interface AdministrationService extends OpenmrsService {
*/
@Authorized(PrivilegeConstants.MANAGE_GLOBAL_PROPERTIES)
public GlobalProperty saveGlobalProperty(GlobalProperty gp) throws APIException;
-
+
/**
* Allows code to be notified when a global property is created/edited/deleted.
- *
+ *
* @see GlobalPropertyListener
* @param listener The listener to register
*/
public void addGlobalPropertyListener(GlobalPropertyListener listener);
-
+
/**
* Removes a GlobalPropertyListener previously registered by
* {@link #addGlobalPropertyListener(GlobalPropertyListener)}
- *
+ *
* @param listener
*/
public void removeGlobalPropertyListener(GlobalPropertyListener listener);
-
+
/**
* Runs the <code>sql</code> on the database. If <code>selectOnly</code> is flagged then any
* non-select sql statements will be rejected.
- *
+ *
* @param sql
* @param selectOnly
* @return ResultSet
@@ -248,20 +247,20 @@ public interface AdministrationService extends OpenmrsService {
*/
@Authorized(PrivilegeConstants.SQL_LEVEL_ACCESS)
public List<List<Object>> executeSQL(String sql, boolean selectOnly) throws APIException;
-
+
/**
* Get the implementation id stored for this server Returns null if no implementation id has
* been successfully set yet
- *
+ *
* @return ImplementationId object that is this implementation's unique id
* @should return null if no implementation id is defined yet
*/
@Authorized(PrivilegeConstants.MANAGE_IMPLEMENTATION_ID)
public ImplementationId getImplementationId() throws APIException;
-
+
/**
* Set the given <code>implementationId</code> as this implementation's unique id
- *
+ *
* @param implementationId the ImplementationId to save
* @throws APIException if implementationId is empty or is invalid according to central id
* server
@@ -275,25 +274,25 @@ public interface AdministrationService extends OpenmrsService {
*/
@Authorized(PrivilegeConstants.MANAGE_IMPLEMENTATION_ID)
public void setImplementationId(ImplementationId implementationId) throws APIException;
-
+
/**
* Gets the list of locales which the administrator has allowed for use on the system. This is
* specified with a global property named
* {@link OpenmrsConstants#GLOBAL_PROPERTY_LOCALE_ALLOWED_LIST}.
- *
+ *
* @return list of allowed locales
* @should return at least one locale if no locales defined in database yet
* @should not fail if not global property for locales allowed defined yet
* @should not return duplicates even if the global property has them
*/
public List<Locale> getAllowedLocales();
-
+
/**
* Gets the list of locales for which localized messages are available for the user interface
* (presentation layer). This set includes all the available locales (as indicated by the
* MessageSourceService) filtered by the allowed locales (as indicated by this
* AdministrationService).
- *
+ *
* @return list of allowed presentation locales TODO change this return type to list?
* @should return at least one locale if no locales defined in database yet
* @should not return more locales than message source service locales
@@ -303,10 +302,10 @@ public interface AdministrationService extends OpenmrsService {
* @should return language locale if it is specified in allowed list and there are no country locale message files available
*/
public Set<Locale> getPresentationLocales();
-
+
/**
* Returns a global property according to the type specified
- *
+ *
* @param <T>
* @param propertyName
* @should get property value in the proper type specified
@@ -315,19 +314,19 @@ public interface AdministrationService extends OpenmrsService {
* @since 1.7
*/
public <T> T getGlobalPropertyValue(String propertyName, T defaultValue) throws APIException;
-
+
/**
* @param aClass class of object getting length for
* @param fieldName name of the field to get the length for
* @return the max field length of a property
*/
public int getMaximumPropertyLength(Class<? extends OpenmrsObject> aClass, String fieldName);
-
+
/**
* Performs validation in the manual flush mode to prevent any premature flushes.
* <p>
* Used by {@link ValidateUtil#validate(Object)}.
- *
+ *
* @since 1.9
* @param object
* @param errors
@@ -351,7 +350,7 @@ public interface AdministrationService extends OpenmrsService {
* Returns a list of locales used by the user when searching.
* <p>
* The list is constructed from a currently selected locale and allowed user proficient locales.
- *
+ *
* @return locales
* @throws APIException
* @since 1.8.4, 1.9.1, 1.10
@@ -361,14 +360,14 @@ public interface AdministrationService extends OpenmrsService {
* @should cache results for a user
*/
public List<Locale> getSearchLocales() throws APIException;
-
+
/**
* Used by Spring to set the http client for accessing the openmrs implementation service
*
* @param implementationHttpClient The implementation http client
*/
public void setImplementationIdHttpClient(HttpClient implementationHttpClient);
-
+
/**
* Reads a GP which specifies if database string comparison is case sensitive.
* <p>
@@ -376,7 +375,7 @@ public interface AdministrationService extends OpenmrsService {
* See http://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html
* <p>
* It is set to <b>true</b> by default.
- *
+ *
* @return true if database string comparison is case sensitive
* @since 1.9.9, 1.10.2, 1.11
*/
diff --git a/api/src/main/java/org/openmrs/api/cache/CachePropertiesUtil.java b/api/src/main/java/org/openmrs/api/cache/CachePropertiesUtil.java
index 74de2b3..e501e6b 100644
--- a/api/src/main/java/org/openmrs/api/cache/CachePropertiesUtil.java
+++ b/api/src/main/java/org/openmrs/api/cache/CachePropertiesUtil.java
@@ -11,7 +11,6 @@ package org.openmrs.api.cache;
import net.sf.ehcache.config.CacheConfiguration;
-import net.sf.ehcache.config.PersistenceConfiguration;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
diff --git a/api/src/main/java/org/openmrs/api/cache/OpenmrsCacheConfiguration.java b/api/src/main/java/org/openmrs/api/cache/OpenmrsCacheConfiguration.java
index 8f3266f..b678076 100644
--- a/api/src/main/java/org/openmrs/api/cache/OpenmrsCacheConfiguration.java
+++ b/api/src/main/java/org/openmrs/api/cache/OpenmrsCacheConfiguration.java
@@ -11,9 +11,10 @@ package org.openmrs.api.cache;
import java.util.HashMap;
import java.util.Set;
+import java.util.Map;
public class OpenmrsCacheConfiguration {
- private HashMap<String, String> cacheProperties = new HashMap<>();
+ private Map<String, String> cacheProperties = new HashMap<>();
public void addProperty(String key, String value){
cacheProperties.put(key, value);
diff --git a/api/src/main/java/org/openmrs/api/cache/OpenmrsCacheManagerFactoryBean.java b/api/src/main/java/org/openmrs/api/cache/OpenmrsCacheManagerFactoryBean.java
index 9064c19..eb4f270 100644
--- a/api/src/main/java/org/openmrs/api/cache/OpenmrsCacheManagerFactoryBean.java
+++ b/api/src/main/java/org/openmrs/api/cache/OpenmrsCacheManagerFactoryBean.java
@@ -12,7 +12,6 @@ package org.openmrs.api.cache;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.config.CacheConfiguration;
-import net.sf.ehcache.config.Configuration;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import java.util.List;
diff --git a/api/src/main/java/org/openmrs/api/db/hibernate/HibernatePatientDAO.java b/api/src/main/java/org/openmrs/api/db/hibernate/HibernatePatientDAO.java
index 7fbaeb5..fc0f752 100644
--- a/api/src/main/java/org/openmrs/api/db/hibernate/HibernatePatientDAO.java
+++ b/api/src/main/java/org/openmrs/api/db/hibernate/HibernatePatientDAO.java
@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import java.util.Vector;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -55,14 +56,14 @@ import org.openmrs.api.db.PatientDAO;
* @see org.openmrs.api.PatientService
*/
public class HibernatePatientDAO implements PatientDAO {
-
+
protected final Log log = LogFactory.getLog(getClass());
-
+
/**
* Hibernate session factory
*/
private SessionFactory sessionFactory;
-
+
/**
* Set session factory
*
@@ -71,7 +72,7 @@ public class HibernatePatientDAO implements PatientDAO {
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
-
+
/**
* @param patientId internal patient identifier
* @return patient with given internal identifier
@@ -81,7 +82,7 @@ public class HibernatePatientDAO implements PatientDAO {
public Patient getPatient(Integer patientId) {
return (Patient) sessionFactory.getCurrentSession().get(Patient.class, patientId);
}
-
+
/**
* @param patient patient to be created or updated
* @return patient who was created or updated
@@ -100,22 +101,22 @@ public class HibernatePatientDAO implements PatientDAO {
// row exists but a patient row does not. hibernate does not deal
// with this correctly right now, so we must create a dummy row
// in the patient table before saving
-
+
// Check to make sure we have a row in the patient table already.
// If we don't have a row, create it so Hibernate doesn't bung
// things up
insertPatientStubIfNeeded(patient);
-
+
// Note: A merge might be necessary here because hibernate thinks that Patients
// and Persons are the same objects. So it sees a Person object in the
// cache and claims it is a duplicate of this Patient object.
//patient = (Patient) sessionFactory.getCurrentSession().merge(patient);
sessionFactory.getCurrentSession().saveOrUpdate(patient);
-
+
return patient;
}
}
-
+
/**
* Inserts a row into the patient table This avoids hibernate's bunging of our
* person/patient/user inheritance
@@ -123,18 +124,18 @@ public class HibernatePatientDAO implements PatientDAO {
* @param patient
*/
private void insertPatientStubIfNeeded(Patient patient) {
-
+
boolean stubInsertNeeded = false;
-
+
if (patient.getPatientId() != null) {
// check if there is a row with a matching patient.patient_id
String sql = "SELECT 1 FROM patient WHERE patient_id = :patientId";
Query query = sessionFactory.getCurrentSession().createSQLQuery(sql);
query.setInteger("patientId", patient.getPatientId());
-
+
stubInsertNeeded = (query.uniqueResult() == null);
}
-
+
if (stubInsertNeeded) {
//If not yet persisted
if (patient.getCreator() == null) {
@@ -144,15 +145,15 @@ public class HibernatePatientDAO implements PatientDAO {
if (patient.getDateCreated() == null) {
patient.setDateCreated(new Date());
}
-
+
String insert = "INSERT INTO patient (patient_id, creator, voided, date_created) VALUES (:patientId, :creator, 0, :dateCreated)";
Query query = sessionFactory.getCurrentSession().createSQLQuery(insert);
query.setInteger("patientId", patient.getPatientId());
query.setInteger("creator", patient.getCreator().getUserId());
query.setDate("dateCreated", patient.getDateCreated());
-
+
query.executeUpdate();
-
+
//Without evicting person, you will get this error when promoting person to patient
//org.hibernate.NonUniqueObjectException: a different object with the same identifier
//value was already associated with the session: [org.openmrs.Patient#]
@@ -160,9 +161,9 @@ public class HibernatePatientDAO implements PatientDAO {
Person person = (Person) sessionFactory.getCurrentSession().get(Person.class, patient.getPersonId());
sessionFactory.getCurrentSession().evict(person);
}
-
+
}
-
+
/**
* @see org.openmrs.api.db.PatientDAO#getPatients(String, boolean, Integer, Integer)
* @should return exact match first
@@ -172,71 +173,71 @@ public class HibernatePatientDAO implements PatientDAO {
if (StringUtils.isBlank(query) || (length != null && length < 1)) {
return Collections.emptyList();
}
-
+
if (start == null || start < 0) {
start = 0;
}
if (length == null) {
length = HibernatePersonDAO.getMaximumSearchResults();
}
-
+
Criteria criteriaExactMatch = sessionFactory.getCurrentSession().createCriteria(Patient.class);
criteriaExactMatch = new PatientSearchCriteria(sessionFactory, criteriaExactMatch).prepareCriteria(query, true,
false, includeVoided);
-
+
criteriaExactMatch.setProjection(Projections.rowCount());
Integer listSize = ((Number) criteriaExactMatch.uniqueResult()).intValue();
-
+
criteriaExactMatch = sessionFactory.getCurrentSession().createCriteria(Patient.class);
criteriaExactMatch = new PatientSearchCriteria(sessionFactory, criteriaExactMatch).prepareCriteria(query, true,
true, includeVoided);
-
+
Set<Patient> patients = new LinkedHashSet<>();
-
+
if (start < listSize) {
setFirstAndMaxResult(criteriaExactMatch, start, length);
patients.addAll(criteriaExactMatch.list());
-
+
length -= patients.size();
}
-
+
if (length > 0) {
Criteria criteriaAllMatch = sessionFactory.getCurrentSession().createCriteria(Patient.class);
criteriaAllMatch = new PatientSearchCriteria(sessionFactory, criteriaAllMatch).prepareCriteria(query, null,
false, includeVoided);
criteriaAllMatch.setProjection(Projections.rowCount());
-
+
start -= listSize;
listSize = ((Number) criteriaAllMatch.uniqueResult()).intValue();
-
+
criteriaAllMatch = sessionFactory.getCurrentSession().createCriteria(Patient.class);
criteriaAllMatch = new PatientSearchCriteria(sessionFactory, criteriaAllMatch).prepareCriteria(query, null,
true, includeVoided);
-
+
if (start < listSize) {
setFirstAndMaxResult(criteriaAllMatch, start, length);
-
+
List<Patient> patientsList = criteriaAllMatch.list();
-
+
patients.addAll(patientsList);
-
+
length -= patientsList.size();
}
}
-
+
if (length > 0) {
Criteria criteriaNoExactMatch = sessionFactory.getCurrentSession().createCriteria(Patient.class);
criteriaNoExactMatch = new PatientSearchCriteria(sessionFactory, criteriaNoExactMatch).prepareCriteria(query,
false, false, includeVoided);
criteriaNoExactMatch.setProjection(Projections.rowCount());
-
+
start -= listSize;
listSize = ((Number) criteriaNoExactMatch.uniqueResult()).intValue();
-
+
criteriaNoExactMatch = sessionFactory.getCurrentSession().createCriteria(Patient.class);
criteriaNoExactMatch = new PatientSearchCriteria(sessionFactory, criteriaNoExactMatch).prepareCriteria(query,
false, true, includeVoided);
-
+
if (start < listSize) {
setFirstAndMaxResult(criteriaNoExactMatch, start, length);
patients.addAll(criteriaNoExactMatch.list());
@@ -244,7 +245,7 @@ public class HibernatePatientDAO implements PatientDAO {
}
return new ArrayList<>(patients);
}
-
+
/**
* @see org.openmrs.api.db.PatientDAO#getPatients(String, Integer, Integer)
*/
@@ -252,12 +253,12 @@ public class HibernatePatientDAO implements PatientDAO {
public List<Patient> getPatients(String query, Integer start, Integer length) throws DAOException {
return getPatients(query, false, start, length);
}
-
+
private void setFirstAndMaxResult(Criteria criteria, Integer start, Integer length) {
if (start != null) {
criteria.setFirstResult(start);
}
-
+
int maximumSearchResults = HibernatePersonDAO.getMaximumSearchResults();
if (length != null && length < maximumSearchResults) {
criteria.setMaxResults(length);
@@ -268,7 +269,7 @@ public class HibernatePatientDAO implements PatientDAO {
criteria.setMaxResults(maximumSearchResults);
}
}
-
+
/**
* @see org.openmrs.api.db.PatientDAO#getAllPatients(boolean)
*/
@@ -276,14 +277,14 @@ public class HibernatePatientDAO implements PatientDAO {
@Override
public List<Patient> getAllPatients(boolean includeVoided) throws DAOException {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Patient.class);
-
+
if (!includeVoided) {
criteria.add(Restrictions.eq("voided", false));
}
-
+
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.PatientService#purgePatientIdentifierType(org.openmrs.PatientIdentifierType)
* @see org.openmrs.api.db.PatientDAO#deletePatientIdentifierType(org.openmrs.PatientIdentifierType)
@@ -292,7 +293,7 @@ public class HibernatePatientDAO implements PatientDAO {
public void deletePatientIdentifierType(PatientIdentifierType patientIdentifierType) throws DAOException {
sessionFactory.getCurrentSession().delete(patientIdentifierType);
}
-
+
/**
* @see org.openmrs.api.PatientService#getPatientIdentifiers(java.lang.String, java.util.List, java.util.List, java.util.List, java.lang.Boolean)
*/
@@ -302,40 +303,40 @@ public class HibernatePatientDAO implements PatientDAO {
List<PatientIdentifierType> patientIdentifierTypes, List<Location> locations, List<Patient> patients,
Boolean isPreferred) throws DAOException {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PatientIdentifier.class);
-
+
// join with the patient table to prevent patient identifiers from patients
// that already voided getting returned
criteria.createAlias("patient", "patient");
criteria.add(Restrictions.eq("patient.voided", false));
-
+
// make sure the patient object isn't voided
criteria.add(Restrictions.eq("voided", false));
-
+
if (identifier != null) {
criteria.add(Restrictions.eq("identifier", identifier));
}
-
+
// TODO add junit test for getting by identifier type
if (patientIdentifierTypes.size() > 0) {
criteria.add(Restrictions.in("identifierType", patientIdentifierTypes));
}
-
+
if (locations.size() > 0) {
criteria.add(Restrictions.in("location", locations));
}
-
+
// TODO add junit test for getting by patients
if (patients.size() > 0) {
criteria.add(Restrictions.in("patient", patients));
}
-
+
if (isPreferred != null) {
criteria.add(Restrictions.eq("preferred", isPreferred));
}
-
+
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.db.PatientDAO#savePatientIdentifierType(org.openmrs.PatientIdentifierType)
*/
@@ -344,7 +345,7 @@ public class HibernatePatientDAO implements PatientDAO {
sessionFactory.getCurrentSession().saveOrUpdate(patientIdentifierType);
return patientIdentifierType;
}
-
+
/**
* @see org.openmrs.api.PatientService#deletePatient(org.openmrs.Patient)
*/
@@ -352,7 +353,7 @@ public class HibernatePatientDAO implements PatientDAO {
public void deletePatient(Patient patient) throws DAOException {
HibernatePersonDAO.deletePersonAndAttributes(sessionFactory, patient);
}
-
+
/**
* @see org.openmrs.api.PatientService#getPatientIdentifierType(java.lang.Integer)
*/
@@ -361,7 +362,7 @@ public class HibernatePatientDAO implements PatientDAO {
return (PatientIdentifierType) sessionFactory.getCurrentSession().get(PatientIdentifierType.class,
patientIdentifierTypeId);
}
-
+
/**
* @should not return null when includeRetired is false
* @should not return retired when includeRetired is false
@@ -374,22 +375,22 @@ public class HibernatePatientDAO implements PatientDAO {
@Override
public List<PatientIdentifierType> getAllPatientIdentifierTypes(boolean includeRetired) throws DAOException {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PatientIdentifierType.class);
-
+
if (!includeRetired) {
criteria.add(Restrictions.eq("retired", false));
} else {
//retired last
criteria.addOrder(Order.asc("retired"));
}
-
+
//required first
criteria.addOrder(Order.desc("required"));
criteria.addOrder(Order.asc("name"));
criteria.addOrder(Order.asc("patientIdentifierTypeId"));
-
+
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.db.PatientDAO#getPatientIdentifierTypes(java.lang.String,
* java.lang.String, java.lang.Boolean, java.lang.Boolean)
@@ -410,35 +411,35 @@ public class HibernatePatientDAO implements PatientDAO {
@Override
public List<PatientIdentifierType> getPatientIdentifierTypes(String name, String format, Boolean required,
Boolean hasCheckDigit) throws DAOException {
-
+
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PatientIdentifierType.class);
-
+
if (name != null) {
criteria.add(Restrictions.eq("name", name));
}
-
+
if (format != null) {
criteria.add(Restrictions.eq("format", format));
}
-
+
if (required != null) {
criteria.add(Restrictions.eq("required", required));
}
-
+
if (hasCheckDigit != null) {
criteria.add(Restrictions.eq("checkDigit", hasCheckDigit));
}
-
+
criteria.add(Restrictions.eq("retired", false));
-
+
//required first
criteria.addOrder(Order.desc("required"));
criteria.addOrder(Order.asc("name"));
criteria.addOrder(Order.asc("patientIdentifierTypeId"));
-
+
return criteria.list();
}
-
+
/**
* @param attributes attributes on a Person or Patient object. similar to: [gender, givenName,
* middleName, familyName]
@@ -465,7 +466,7 @@ public class HibernatePatientDAO implements PatientDAO {
patients = query.list();
}
}
-
+
}
sortDuplicatePatients(patients, patientIds);
@@ -579,7 +580,7 @@ public class HibernatePatientDAO implements PatientDAO {
log.warn("Unidentified attribute: " + attribute);
}
}
- if(innerFields.size() > 0 || whereConditions.size() > 0) {
+ if(CollectionUtils.isNotEmpty(innerFields) || CollectionUtils.isNotEmpty(whereConditions)) {
String innerFieldsJoined = StringUtils.join(innerFields, ", ");
String whereFieldsJoined = StringUtils.join(whereConditions, " and ");
String innerWhereCondition = "";
@@ -623,26 +624,26 @@ public class HibernatePatientDAO implements PatientDAO {
}
Collections.sort(patients, new PatientIdComparator(patientIdOrder));
}
-
+
/**
* @see org.openmrs.api.db.PatientDAO#getPatientByUuid(java.lang.String)
*/
@Override
public Patient getPatientByUuid(String uuid) {
Patient p = null;
-
+
p = (Patient) sessionFactory.getCurrentSession().createQuery("from Patient p where p.uuid = :uuid").setString(
"uuid", uuid).uniqueResult();
-
+
return p;
}
-
+
@Override
public PatientIdentifier getPatientIdentifierByUuid(String uuid) {
return (PatientIdentifier) sessionFactory.getCurrentSession().createQuery(
"from PatientIdentifier p where p.uuid = :uuid").setString("uuid", uuid).uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PatientDAO#getPatientIdentifierTypeByUuid(java.lang.String)
*/
@@ -651,7 +652,7 @@ public class HibernatePatientDAO implements PatientDAO {
return (PatientIdentifierType) sessionFactory.getCurrentSession().createQuery(
"from PatientIdentifierType pit where pit.uuid = :uuid").setString("uuid", uuid).uniqueResult();
}
-
+
/**
* This method uses a SQL query and does not load anything into the hibernate session. It exists
* because of ticket #1375.
@@ -664,18 +665,18 @@ public class HibernatePatientDAO implements PatientDAO {
&& patientIdentifier.getPatient().getPatientId() != null;
boolean checkLocation = patientIdentifier.getLocation() != null
&& patientIdentifier.getIdentifierType().getUniquenessBehavior() == UniquenessBehavior.LOCATION;
-
+
// switched this to an hql query so the hibernate cache can be considered as well as the database
String hql = "select count(*) from PatientIdentifier pi, Patient p where pi.patient.patientId = p.patient.patientId "
+ "and p.voided = false and pi.voided = false and pi.identifier = :identifier and pi.identifierType = :idType";
-
+
if (checkPatient) {
hql += " and p.patientId != :ptId";
}
if (checkLocation) {
hql += " and pi.location = :locationId";
}
-
+
Query query = sessionFactory.getCurrentSession().createQuery(hql);
query.setString("identifier", patientIdentifier.getIdentifier());
query.setInteger("idType", patientIdentifier.getIdentifierType().getPatientIdentifierTypeId());
@@ -687,7 +688,7 @@ public class HibernatePatientDAO implements PatientDAO {
}
return !query.uniqueResult().toString().equals("0");
}
-
+
/**
* @param patientIdentifierId the patientIdentifier id
* @return the patientIdentifier matching the Id
@@ -695,11 +696,11 @@ public class HibernatePatientDAO implements PatientDAO {
*/
@Override
public PatientIdentifier getPatientIdentifier(Integer patientIdentifierId) throws DAOException {
-
+
return (PatientIdentifier) sessionFactory.getCurrentSession().get(PatientIdentifier.class, patientIdentifierId);
-
+
}
-
+
/**
* @param patientIdentifier patientIndentifier to be created or updated
* @return patientIndentifier that was created or updated
@@ -707,23 +708,23 @@ public class HibernatePatientDAO implements PatientDAO {
*/
@Override
public PatientIdentifier savePatientIdentifier(PatientIdentifier patientIdentifier) {
-
+
sessionFactory.getCurrentSession().saveOrUpdate(patientIdentifier);
return patientIdentifier;
-
+
}
-
+
/**
* @see org.openmrs.api.PatientService#purgePatientIdentifier(org.openmrs.PatientIdentifier)
* @see org.openmrs.api.db.PatientDAO#deletePatientIdentifier(org.openmrs.PatientIdentifier)
*/
@Override
public void deletePatientIdentifier(PatientIdentifier patientIdentifier) throws DAOException {
-
+
sessionFactory.getCurrentSession().delete(patientIdentifier);
-
+
}
-
+
/**
* @param query the string to search on
* @return the number of patients matching the given search phrase
@@ -734,16 +735,16 @@ public class HibernatePatientDAO implements PatientDAO {
if (StringUtils.isBlank(query)) {
return 0L;
}
-
+
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Patient.class);
criteria = new PatientSearchCriteria(sessionFactory, criteria).prepareCriteria(query);
-
+
// Using Hibernate projections did NOT work here, the resulting queries could not be executed due to
// missing group-by clauses. Hence the poor man's implementation of counting search results.
//
return (long) criteria.list().size();
}
-
+
/**
* @param query the string to search on
* @param includeVoided true/false whether or not to included voided patients
@@ -755,16 +756,16 @@ public class HibernatePatientDAO implements PatientDAO {
if (StringUtils.isBlank(query)) {
return 0L;
}
-
+
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Patient.class);
criteria = new PatientSearchCriteria(sessionFactory, criteria).prepareCriteria(query, includeVoided);
-
+
// Using Hibernate projections did NOT work here, the resulting queries could not be executed due to
// missing group-by clauses. Hence the poor man's implementation of counting search results.
//
return (long) criteria.list().size();
}
-
+
/**
* @see org.openmrs..api.db.PatientDAO#getAllergies(org.openmrs.Patient)
*/
@@ -776,7 +777,7 @@ public class HibernatePatientDAO implements PatientDAO {
criteria.add(Restrictions.eq("voided", false));
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.db.PatientDAO#getAllergyStatus(org.openmrs.Patient)
*/
@@ -787,7 +788,7 @@ public class HibernatePatientDAO implements PatientDAO {
return (String) sessionFactory.getCurrentSession().createSQLQuery(
"select allergy_status from patient where patient_id = :patientId").setInteger("patientId", patient.getPatientId()).uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PatientDAO#saveAllergies(org.openmrs.Patient,
* org.openmrsallergyapi.Allergies)
@@ -800,14 +801,14 @@ public class HibernatePatientDAO implements PatientDAO {
.setInteger("patientId", patient.getPatientId())
.setString("allergyStatus", allergies.getAllergyStatus())
.executeUpdate();
-
+
for (Allergy allergy : allergies) {
sessionFactory.getCurrentSession().save(allergy);
}
-
+
return allergies;
}
-
+
/**
* @see org.openmrs.PatientDAO#getAllergy(Integer)
*/
@@ -816,7 +817,7 @@ public class HibernatePatientDAO implements PatientDAO {
return (Allergy) sessionFactory.getCurrentSession().createQuery("from Allergy a where a.allergyId = :allergyId")
.setInteger("allergyId", allergyId).uniqueResult();
}
-
+
/**
* @see org.openmrs.PatientDAO#getAllergyByUuid(String)
*/
diff --git a/api/src/main/java/org/openmrs/api/db/hibernate/HibernatePersonDAO.java b/api/src/main/java/org/openmrs/api/db/hibernate/HibernatePersonDAO.java
index 6a91a2b..ea8a5d6 100644
--- a/api/src/main/java/org/openmrs/api/db/hibernate/HibernatePersonDAO.java
+++ b/api/src/main/java/org/openmrs/api/db/hibernate/HibernatePersonDAO.java
@@ -48,29 +48,31 @@ import org.openmrs.util.OpenmrsConstants;
* PersonService ps = Context.getPersonService();
* ps.getPeople("name", false);
* </code>
- *
+ *
* @see org.openmrs.api.db.PersonDAO
* @see org.openmrs.api.PersonService
* @see org.openmrs.api.context.Context
*/
public class HibernatePersonDAO implements PersonDAO {
-
+
protected final static Log log = LogFactory.getLog(HibernatePersonDAO.class);
-
+ public static final String START_DATE = "startDate";
+ public static final String END_DATE = "endDate";
+
/**
* Hibernate session factory
*/
private SessionFactory sessionFactory;
-
+
/**
* Set session factory
- *
+ *
* @param sessionFactory
*/
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
-
+
/**
* @see org.openmrs.api.PersonService#getSimilarPeople(java.lang.String, java.lang.Integer,
* java.lang.String, java.lang.String)
@@ -82,16 +84,16 @@ public class HibernatePersonDAO implements PersonDAO {
if (birthyear == null) {
birthyear = 0;
}
-
+
Set<Person> people = new LinkedHashSet<Person>();
-
+
name = name.replaceAll(" ", " ");
name = name.replace(", ", " ");
String[] names = name.split(" ");
-
+
StringBuilder q = new StringBuilder(
"select p from Person p left join p.names as pname where p.personVoided = false and pname.voided = false and ");
-
+
if (names.length == 1) {
q.append("(").append(" soundex(pname.givenName) = soundex(:n1)").append(
" or soundex(pname.middleName) = soundex(:n1)").append(" or soundex(pname.familyName) = soundex(:n1) ")
@@ -132,12 +134,12 @@ public class HibernatePersonDAO implements PersonDAO {
" when soundex(pname.familyName2) = soundex(:n3) then 3").append(" else 0").append(" end").append(
") >= 5");
} else {
-
+
// This is simply an alternative method of name matching which scales better
// for large names, although it is hard to imagine getting names with more than
// six or so tokens. This can be easily updated to attain more desirable
// results; it is just a working alternative to throwing an exception.
-
+
q.append("(").append(" case").append(" when pname.givenName is null then 0");
for (int i = 0; i < names.length; i++) {
q.append(" when soundex(pname.givenName) = soundex(:n").append(i + 1).append(") then 1");
@@ -158,14 +160,14 @@ public class HibernatePersonDAO implements PersonDAO {
q.append(" when soundex(pname.familyName2) = soundex(:n").append(i + 1).append(") then 1");
}
// if most of the names have at least a hit somewhere
- q.append(" else 0").append(" end").append(") >= ").append((int) (names.length * .75));
+ q.append(" else 0").append(" end").append(") >= ").append((int) (names.length * .75));
}
-
+
String birthdayMatch = " (year(p.birthdate) between " + (birthyear - 1) + " and " + (birthyear + 1)
+ " or p.birthdate is null) ";
-
+
String genderMatch = " (p.gender = :gender or p.gender = '') ";
-
+
if (birthyear != 0 && gender != null) {
q.append(" and (" + birthdayMatch + "and " + genderMatch + ") ");
} else if (birthyear != 0) {
@@ -173,26 +175,26 @@ public class HibernatePersonDAO implements PersonDAO {
} else if (gender != null) {
q.append(" and " + genderMatch);
}
-
+
q.append(" order by pname.givenName asc,").append(" pname.middleName asc,").append(" pname.familyName asc,").append(
" pname.familyName2 asc");
-
+
String qStr = q.toString();
Query query = sessionFactory.getCurrentSession().createQuery(qStr);
-
+
for (int nameIndex = 0; nameIndex < names.length; nameIndex++) {
query.setString("n" + (nameIndex + 1), names[nameIndex]);
}
-
+
if (qStr.contains(":gender")) {
query.setString("gender", gender);
}
-
+
people.addAll(query.list());
-
+
return people;
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getPeople(java.lang.String, java.lang.Boolean)
* @should get no one by null
@@ -237,14 +239,14 @@ public class HibernatePersonDAO implements PersonDAO {
if (searchString == null) {
return new ArrayList<Person>();
}
-
+
PersonSearchCriteria personSearchCriteria = new PersonSearchCriteria();
-
+
searchString = searchString.replace(", ", " ");
String[] values = searchString.split(" ");
-
+
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Person.class);
-
+
personSearchCriteria.addAliasForName(criteria);
personSearchCriteria.addAliasForAttribute(criteria);
if (voided == null || voided == false) {
@@ -253,10 +255,10 @@ public class HibernatePersonDAO implements PersonDAO {
if (dead != null) {
criteria.add(Restrictions.eq("dead", dead));
}
-
+
Disjunction disjunction = Restrictions.disjunction();
MatchMode matchMode = personSearchCriteria.getAttributeMatchMode();
-
+
for (String value : values) {
if (value != null && value.length() > 0) {
disjunction.add(personSearchCriteria.prepareCriterionForName(value, voided)).add(
@@ -264,24 +266,24 @@ public class HibernatePersonDAO implements PersonDAO {
}
}
criteria.add(disjunction);
-
+
criteria.addOrder(Order.asc("personId"));
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.setMaxResults(getMaximumSearchResults());
-
+
// TODO - remove
log.debug(criteria.toString());
-
+
return criteria.list();
}
-
+
public List<Person> getPeople(String searchString, Boolean dead) {
return getPeople(searchString, dead, null);
}
-
+
/**
* Fetch the max results value from the global properties table
- *
+ *
* @return Integer value for the person search max results global property
*/
public static Integer getMaximumSearchResults() {
@@ -295,10 +297,10 @@ public class HibernatePersonDAO implements PersonDAO {
+ "to a valid integer. Returning the default "
+ OpenmrsConstants.GLOBAL_PROPERTY_PERSON_SEARCH_MAX_RESULTS_DEFAULT_VALUE);
}
-
+
return OpenmrsConstants.GLOBAL_PROPERTY_PERSON_SEARCH_MAX_RESULTS_DEFAULT_VALUE;
}
-
+
/**
* @see org.openmrs.api.PersonService#getPerson(java.lang.Integer)
* @see org.openmrs.api.db.PersonDAO#getPerson(java.lang.Integer)
@@ -306,7 +308,7 @@ public class HibernatePersonDAO implements PersonDAO {
public Person getPerson(Integer personId) {
return (Person) sessionFactory.getCurrentSession().get(Person.class, personId);
}
-
+
/**
* @see org.openmrs.api.PersonService#deletePersonAttributeType(org.openmrs.PersonAttributeType)
* @see org.openmrs.api.db.PersonDAO#deletePersonAttributeType(org.openmrs.PersonAttributeType)
@@ -314,7 +316,7 @@ public class HibernatePersonDAO implements PersonDAO {
public void deletePersonAttributeType(PersonAttributeType type) {
sessionFactory.getCurrentSession().delete(type);
}
-
+
/**
* @see org.openmrs.api.PersonService#savePersonAttributeType(org.openmrs.PersonAttributeType)
* @see org.openmrs.api.db.PersonDAO#savePersonAttributeType(org.openmrs.PersonAttributeType)
@@ -323,7 +325,7 @@ public class HibernatePersonDAO implements PersonDAO {
sessionFactory.getCurrentSession().saveOrUpdate(type);
return type;
}
-
+
/**
* @see org.openmrs.api.PersonService#getPersonAttributeType(java.lang.Integer)
* @see org.openmrs.api.db.PersonDAO#getPersonAttributeType(java.lang.Integer)
@@ -331,7 +333,7 @@ public class HibernatePersonDAO implements PersonDAO {
public PersonAttributeType getPersonAttributeType(Integer typeId) {
return (PersonAttributeType) sessionFactory.getCurrentSession().get(PersonAttributeType.class, typeId);
}
-
+
/**
* @see org.openmrs.api.PersonService#getPersonAttribute(java.lang.Integer)
* @see org.openmrs.api.db.PersonDAO#getPersonAttribute(java.lang.Integer)
@@ -339,7 +341,7 @@ public class HibernatePersonDAO implements PersonDAO {
public PersonAttribute getPersonAttribute(Integer id) {
return (PersonAttribute) sessionFactory.getCurrentSession().get(PersonAttribute.class, id);
}
-
+
/**
* @see org.openmrs.api.PersonService#getAllPersonAttributeTypes(boolean)
* @see org.openmrs.api.db.PersonDAO#getAllPersonAttributeTypes(boolean)
@@ -347,16 +349,16 @@ public class HibernatePersonDAO implements PersonDAO {
@SuppressWarnings("unchecked")
public List<PersonAttributeType> getAllPersonAttributeTypes(boolean includeRetired) throws DAOException {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PersonAttributeType.class, "r");
-
+
if (!includeRetired) {
criteria.add(Restrictions.eq("retired", false));
}
-
+
criteria.addOrder(Order.asc("sortWeight"));
-
+
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getPersonAttributeTypes(java.lang.String, java.lang.String,
* java.lang.Integer, java.lang.Boolean)
@@ -366,26 +368,26 @@ public class HibernatePersonDAO implements PersonDAO {
public List<PersonAttributeType> getPersonAttributeTypes(String exactName, String format, Integer foreignKey,
Boolean searchable) throws DAOException {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PersonAttributeType.class, "r");
-
+
if (exactName != null) {
criteria.add(Restrictions.eq("name", exactName));
}
-
+
if (format != null) {
criteria.add(Restrictions.eq("format", format));
}
-
+
if (foreignKey != null) {
criteria.add(Restrictions.eq("foreignKey", foreignKey));
}
-
+
if (searchable != null) {
criteria.add(Restrictions.eq("searchable", searchable));
}
-
+
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.PersonService#getRelationship(java.lang.Integer)
* @see org.openmrs.api.db.PersonDAO#getRelationship(java.lang.Integer)
@@ -393,10 +395,10 @@ public class HibernatePersonDAO implements PersonDAO {
public Relationship getRelationship(Integer relationshipId) throws DAOException {
Relationship relationship = (Relationship) sessionFactory.getCurrentSession()
.get(Relationship.class, relationshipId);
-
+
return relationship;
}
-
+
/**
* @see org.openmrs.api.PersonService#getAllRelationships(boolean)
* @see org.openmrs.api.db.PersonDAO#getAllRelationships(boolean)
@@ -404,14 +406,14 @@ public class HibernatePersonDAO implements PersonDAO {
@SuppressWarnings("unchecked")
public List<Relationship> getAllRelationships(boolean includeVoided) throws DAOException {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Relationship.class, "r");
-
+
if (!includeVoided) {
criteria.add(Restrictions.eq("voided", false));
}
-
+
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.PersonService#getRelationships(org.openmrs.Person, org.openmrs.Person,
* org.openmrs.RelationshipType)
@@ -421,7 +423,7 @@ public class HibernatePersonDAO implements PersonDAO {
@SuppressWarnings("unchecked")
public List<Relationship> getRelationships(Person fromPerson, Person toPerson, RelationshipType relType) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Relationship.class, "r");
-
+
if (fromPerson != null) {
criteria.add(Restrictions.eq("personA", fromPerson));
}
@@ -431,12 +433,12 @@ public class HibernatePersonDAO implements PersonDAO {
if (relType != null) {
criteria.add(Restrictions.eq("relationshipType", relType));
}
-
+
criteria.add(Restrictions.eq("voided", false));
-
+
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.PersonService#getRelationships(org.openmrs.Person, org.openmrs.Person,
* org.openmrs.RelationshipType, java.util.Date, java.util.Date)
@@ -447,7 +449,7 @@ public class HibernatePersonDAO implements PersonDAO {
public List<Relationship> getRelationships(Person fromPerson, Person toPerson, RelationshipType relType,
Date startEffectiveDate, Date endEffectiveDate) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Relationship.class, "r");
-
+
if (fromPerson != null) {
criteria.add(Restrictions.eq("personA", fromPerson));
}
@@ -459,25 +461,25 @@ public class HibernatePersonDAO implements PersonDAO {
}
if (startEffectiveDate != null) {
criteria.add(Restrictions.disjunction().add(
- Restrictions.and(Restrictions.le("startDate", startEffectiveDate), Restrictions.ge("endDate",
+ Restrictions.and(Restrictions.le(START_DATE, startEffectiveDate), Restrictions.ge(END_DATE,
startEffectiveDate))).add(
- Restrictions.and(Restrictions.le("startDate", startEffectiveDate), Restrictions.isNull("endDate"))).add(
- Restrictions.and(Restrictions.isNull("startDate"), Restrictions.ge("endDate", startEffectiveDate))).add(
- Restrictions.and(Restrictions.isNull("startDate"), Restrictions.isNull("endDate"))));
+ Restrictions.and(Restrictions.le(START_DATE, startEffectiveDate), Restrictions.isNull(END_DATE))).add(
+ Restrictions.and(Restrictions.isNull(START_DATE), Restrictions.ge(END_DATE, startEffectiveDate))).add(
+ Restrictions.and(Restrictions.isNull(START_DATE), Restrictions.isNull(END_DATE))));
}
if (endEffectiveDate != null) {
criteria.add(Restrictions.disjunction().add(
- Restrictions.and(Restrictions.le("startDate", endEffectiveDate), Restrictions
- .ge("endDate", endEffectiveDate))).add(
- Restrictions.and(Restrictions.le("startDate", endEffectiveDate), Restrictions.isNull("endDate"))).add(
- Restrictions.and(Restrictions.isNull("startDate"), Restrictions.ge("endDate", endEffectiveDate))).add(
- Restrictions.and(Restrictions.isNull("startDate"), Restrictions.isNull("endDate"))));
+ Restrictions.and(Restrictions.le(START_DATE, endEffectiveDate), Restrictions
+ .ge(END_DATE, endEffectiveDate))).add(
+ Restrictions.and(Restrictions.le(START_DATE, endEffectiveDate), Restrictions.isNull(END_DATE))).add(
+ Restrictions.and(Restrictions.isNull(START_DATE), Restrictions.ge(END_DATE, endEffectiveDate))).add(
+ Restrictions.and(Restrictions.isNull(START_DATE), Restrictions.isNull(END_DATE))));
}
criteria.add(Restrictions.eq("voided", false));
-
+
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.PersonService#getRelationshipType(java.lang.Integer)
* @see org.openmrs.api.db.PersonDAO#getRelationshipType(java.lang.Integer)
@@ -485,28 +487,28 @@ public class HibernatePersonDAO implements PersonDAO {
public RelationshipType getRelationshipType(Integer relationshipTypeId) throws DAOException {
RelationshipType relationshipType = (RelationshipType) sessionFactory.getCurrentSession().get(
RelationshipType.class, relationshipTypeId);
-
+
return relationshipType;
}
-
+
/**
* @see org.openmrs.api.PersonService#getRelationshipTypes(java.lang.String, java.lang.Boolean)
* @see org.openmrs.api.db.PersonDAO#getRelationshipTypes(java.lang.String, java.lang.Boolean)
*/
@SuppressWarnings("unchecked")
public List<RelationshipType> getRelationshipTypes(String relationshipTypeName, Boolean preferred) throws DAOException {
-
+
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(RelationshipType.class);
criteria.add(Restrictions.sqlRestriction("CONCAT(a_Is_To_B, CONCAT('/', b_Is_To_A)) like (?)", relationshipTypeName,
new StringType()));
-
+
if (preferred != null) {
criteria.add(Restrictions.eq("preferred", preferred));
}
-
+
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.PersonService#saveRelationshipType(org.openmrs.RelationshipType)
* @see org.openmrs.api.db.PersonDAO#saveRelationshipType(org.openmrs.RelationshipType)
@@ -515,7 +517,7 @@ public class HibernatePersonDAO implements PersonDAO {
sessionFactory.getCurrentSession().saveOrUpdate(relationshipType);
return relationshipType;
}
-
+
/**
* @see org.openmrs.api.PersonService#deleteRelationshipType(org.openmrs.RelationshipType)
* @see org.openmrs.api.db.PersonDAO#deleteRelationshipType(org.openmrs.RelationshipType)
@@ -523,7 +525,7 @@ public class HibernatePersonDAO implements PersonDAO {
public void deleteRelationshipType(RelationshipType relationshipType) throws DAOException {
sessionFactory.getCurrentSession().delete(relationshipType);
}
-
+
/**
* @see org.openmrs.api.PersonService#purgePerson(org.openmrs.Person)
* @see org.openmrs.api.db.PersonDAO#deletePerson(org.openmrs.Person)
@@ -531,7 +533,7 @@ public class HibernatePersonDAO implements PersonDAO {
public void deletePerson(Person person) throws DAOException {
HibernatePersonDAO.deletePersonAndAttributes(sessionFactory, person);
}
-
+
/**
* @see org.openmrs.api.PersonService#savePerson(org.openmrs.Person)
* @see org.openmrs.api.db.PersonDAO#savePerson(org.openmrs.Person)
@@ -540,7 +542,7 @@ public class HibernatePersonDAO implements PersonDAO {
sessionFactory.getCurrentSession().saveOrUpdate(person);
return person;
}
-
+
/**
* @see org.openmrs.api.PersonService#saveRelationship(org.openmrs.Relationship)
* @see org.openmrs.api.db.PersonDAO#saveRelationship(org.openmrs.Relationship)
@@ -549,7 +551,7 @@ public class HibernatePersonDAO implements PersonDAO {
sessionFactory.getCurrentSession().saveOrUpdate(relationship);
return relationship;
}
-
+
/**
* @see org.openmrs.api.PersonService#purgeRelationship(org.openmrs.Relationship)
* @see org.openmrs.api.db.PersonDAO#deleteRelationship(org.openmrs.Relationship)
@@ -557,11 +559,11 @@ public class HibernatePersonDAO implements PersonDAO {
public void deleteRelationship(Relationship relationship) throws DAOException {
sessionFactory.getCurrentSession().delete(relationship);
}
-
+
/**
* Used by deletePerson, deletePatient, and deleteUser to remove all properties of a person
* before deleting them.
- *
+ *
* @param sessionFactory the session factory from which to pull the current session
* @param person the person to delete
*/
@@ -575,7 +577,7 @@ public class HibernatePersonDAO implements PersonDAO {
}
}
person.setAddresses(null);
-
+
for (PersonAttribute attribute : person.getAttributes()) {
if (attribute.getDateCreated() == null) {
sessionFactory.getCurrentSession().evict(attribute);
@@ -584,7 +586,7 @@ public class HibernatePersonDAO implements PersonDAO {
}
}
person.setAttributes(null);
-
+
for (PersonName name : person.getNames()) {
if (name.getDateCreated() == null) {
sessionFactory.getCurrentSession().evict(name);
@@ -593,11 +595,11 @@ public class HibernatePersonDAO implements PersonDAO {
}
}
person.setNames(null);
-
+
// finally, just tell hibernate to delete our object
sessionFactory.getCurrentSession().delete(person);
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getPersonAttributeTypeByUuid(java.lang.String)
*/
@@ -605,7 +607,7 @@ public class HibernatePersonDAO implements PersonDAO {
return (PersonAttributeType) sessionFactory.getCurrentSession().createQuery(
"from PersonAttributeType pat where pat.uuid = :uuid").setString("uuid", uuid).uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getSavedPersonAttributeTypeName(org.openmrs.PersonAttributeType)
*/
@@ -615,7 +617,7 @@ public class HibernatePersonDAO implements PersonDAO {
sql.setInteger("personAttributeTypeId", personAttributeType.getId());
return (String) sql.uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getPersonByUuid(java.lang.String)
*/
@@ -623,12 +625,12 @@ public class HibernatePersonDAO implements PersonDAO {
return (Person) sessionFactory.getCurrentSession().createQuery("from Person p where p.uuid = :uuid").setString(
"uuid", uuid).uniqueResult();
}
-
+
public PersonAddress getPersonAddressByUuid(String uuid) {
return (PersonAddress) sessionFactory.getCurrentSession().createQuery("from PersonAddress p where p.uuid = :uuid")
.setString("uuid", uuid).uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#savePersonMergeLog(PersonMergeLog)
*/
@@ -637,7 +639,7 @@ public class HibernatePersonDAO implements PersonDAO {
sessionFactory.getCurrentSession().saveOrUpdate(personMergeLog);
return personMergeLog;
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getPersonMergeLog(java.lang.Integer)
*/
@@ -645,7 +647,7 @@ public class HibernatePersonDAO implements PersonDAO {
public PersonMergeLog getPersonMergeLog(Integer id) throws DAOException {
return (PersonMergeLog) sessionFactory.getCurrentSession().get(PersonMergeLog.class, id);
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getPersonMergeLogByUuid(String)
*/
@@ -654,7 +656,7 @@ public class HibernatePersonDAO implements PersonDAO {
return (PersonMergeLog) sessionFactory.getCurrentSession().createQuery("from PersonMergeLog p where p.uuid = :uuid")
.setString("uuid", uuid).uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getWinningPersonMergeLogs(org.openmrs.Person)
*/
@@ -664,7 +666,7 @@ public class HibernatePersonDAO implements PersonDAO {
return (List<PersonMergeLog>) sessionFactory.getCurrentSession().createQuery(
"from PersonMergeLog p where p.winner.id = :winnerId").setInteger("winnerId", person.getId()).list();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getLosingPersonMergeLogs(org.openmrs.Person)
*/
@@ -673,7 +675,7 @@ public class HibernatePersonDAO implements PersonDAO {
return (PersonMergeLog) sessionFactory.getCurrentSession().createQuery(
"from PersonMergeLog p where p.loser.id = :loserId").setInteger("loserId", person.getId()).uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getAllPersonMergeLogs()
*/
@@ -682,12 +684,12 @@ public class HibernatePersonDAO implements PersonDAO {
public List<PersonMergeLog> getAllPersonMergeLogs() throws DAOException {
return (List<PersonMergeLog>) sessionFactory.getCurrentSession().createQuery("from PersonMergeLog p").list();
}
-
+
public PersonAttribute getPersonAttributeByUuid(String uuid) {
return (PersonAttribute) sessionFactory.getCurrentSession().createQuery(
"from PersonAttribute p where p.uuid = :uuid").setString("uuid", uuid).uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getPersonName(Integer)
*/
@@ -695,7 +697,7 @@ public class HibernatePersonDAO implements PersonDAO {
public PersonName getPersonName(Integer personNameId) {
return (PersonName) sessionFactory.getCurrentSession().get(PersonName.class, personNameId);
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getPersonNameByUuid(String)
*/
@@ -703,7 +705,7 @@ public class HibernatePersonDAO implements PersonDAO {
return (PersonName) sessionFactory.getCurrentSession().createQuery("from PersonName p where p.uuid = :uuid")
.setString("uuid", uuid).uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getRelationshipByUuid(java.lang.String)
*/
@@ -711,7 +713,7 @@ public class HibernatePersonDAO implements PersonDAO {
return (Relationship) sessionFactory.getCurrentSession().createQuery("from Relationship r where r.uuid = :uuid")
.setString("uuid", uuid).uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getRelationshipTypeByUuid(java.lang.String)
*/
@@ -719,7 +721,7 @@ public class HibernatePersonDAO implements PersonDAO {
return (RelationshipType) sessionFactory.getCurrentSession().createQuery(
"from RelationshipType rt where rt.uuid = :uuid").setString("uuid", uuid).uniqueResult();
}
-
+
/**
* @see org.openmrs.api.db.PersonDAO#getAllRelationshipTypes(boolean)
*/
@@ -727,14 +729,14 @@ public class HibernatePersonDAO implements PersonDAO {
public List<RelationshipType> getAllRelationshipTypes(boolean includeRetired) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(RelationshipType.class);
criteria.addOrder(Order.asc("weight"));
-
+
if (!includeRetired) {
criteria.add(Restrictions.eq("retired", false));
}
-
+
return criteria.list();
}
-
+
/**
* @see org.openmrs.api.PersonService#savePersonName(org.openmrs.PersonName)
* @see org.openmrs.api.db.PersonDAO#savePersonName(org.openmrs.PersonName)
@@ -743,7 +745,7 @@ public class HibernatePersonDAO implements PersonDAO {
sessionFactory.getCurrentSession().saveOrUpdate(personName);
return personName;
}
-
+
/**
* @see org.openmrs.api.PersonService#savePersonAddress(org.openmrs.PersonAddress)
* @see org.openmrs.api.db.PersonDAO#savePersonAddress(org.openmrs.PersonAddress)
@@ -752,5 +754,5 @@ public class HibernatePersonDAO implements PersonDAO {
sessionFactory.getCurrentSession().saveOrUpdate(personAddress);
return personAddress;
}
-
+
}
diff --git a/api/src/main/java/org/openmrs/hl7/impl/HL7ServiceImpl.java b/api/src/main/java/org/openmrs/hl7/impl/HL7ServiceImpl.java
index 2003351..8761bb3 100644
--- a/api/src/main/java/org/openmrs/hl7/impl/HL7ServiceImpl.java
+++ b/api/src/main/java/org/openmrs/hl7/impl/HL7ServiceImpl.java
@@ -81,17 +81,17 @@ import ca.uhn.hl7v2.parser.GenericParser;
*/
@Transactional
public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
-
+
private final Log log = LogFactory.getLog(this.getClass());
-
+
private static HL7ServiceImpl instance;
-
+
protected HL7DAO dao;
-
+
private GenericParser parser;
-
+
private MessageTypeRouter router;
-
+
/**
* Private constructor to only support on singleton instance.
*
@@ -99,7 +99,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
*/
private HL7ServiceImpl() {
}
-
+
/**
* Singleton Factory method
*
@@ -111,14 +111,14 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
return instance;
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#setHL7DAO(org.openmrs.hl7.db.HL7DAO)
*/
public void setHL7DAO(HL7DAO dao) {
this.dao = dao;
}
-
+
/**
* Used by spring to inject the parser
*
@@ -127,7 +127,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public void setParser(GenericParser parser) {
this.parser = parser;
}
-
+
/**
* Used by spring to inject the router
*
@@ -136,7 +136,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public void setRouter(MessageTypeRouter router) {
this.router = router;
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#saveHL7Source(org.openmrs.hl7.HL7Source)
*/
@@ -147,24 +147,24 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
if (hl7Source.getDateCreated() == null) {
hl7Source.setDateCreated(new Date());
}
-
+
return dao.saveHL7Source(hl7Source);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#purgeHL7Source(org.openmrs.hl7.HL7Source)
*/
public void purgeHL7Source(HL7Source hl7Source) throws APIException {
dao.deleteHL7Source(hl7Source);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#retireHL7Source(org.openmrs.hl7.HL7Source)
*/
public HL7Source retireHL7Source(HL7Source hl7Source) throws APIException {
throw new APIException("general.not.yet.implemented", (Object[]) null);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7Source(java.lang.Integer)
*/
@@ -172,7 +172,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public HL7Source getHL7Source(Integer hl7SourceId) {
return dao.getHL7Source(hl7SourceId);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getAllHL7Sources()
*/
@@ -180,7 +180,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public List<HL7Source> getAllHL7Sources() throws APIException {
return dao.getAllHL7Sources();
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7SourceByName(java.lang.String)
*/
@@ -188,7 +188,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public HL7Source getHL7SourceByName(String name) throws APIException {
return dao.getHL7SourceByName(name);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getAllHL7InQueues()
*/
@@ -196,7 +196,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public List<HL7InQueue> getAllHL7InQueues() throws APIException {
return dao.getAllHL7InQueues();
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7InQueueBatch(int, int, int, String)
*/
@@ -205,7 +205,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public List<HL7InQueue> getHL7InQueueBatch(int start, int length, int messageState, String query) throws APIException {
return dao.getHL7Batch(HL7InQueue.class, start, length, messageState, query);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7InErrorBatch(int, int, java.lang.String)
*/
@@ -214,7 +214,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public List<HL7InError> getHL7InErrorBatch(int start, int length, String query) throws APIException {
return dao.getHL7Batch(HL7InError.class, start, length, null, query);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7InArchiveBatch(int, int, int, String)
*/
@@ -224,7 +224,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
throws APIException {
return dao.getHL7Batch(HL7InArchive.class, start, length, messageState, query);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#countHL7InQueue(int, java.lang.String)
*/
@@ -233,7 +233,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public Integer countHL7InQueue(int messageState, String query) throws APIException {
return OpenmrsUtil.convertToInteger(dao.countHL7s(HL7InQueue.class, messageState, query));
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#countHL7InError(java.lang.String)
*/
@@ -242,7 +242,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public Integer countHL7InError(String query) throws APIException {
return OpenmrsUtil.convertToInteger(dao.countHL7s(HL7InError.class, null, query));
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#countHL7InArchive(int, java.lang.String)
*/
@@ -251,14 +251,14 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public Integer countHL7InArchive(int messageState, String query) throws APIException {
return OpenmrsUtil.convertToInteger(dao.countHL7s(HL7InArchive.class, messageState, query));
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#purgeHL7InQueue(org.openmrs.hl7.HL7InQueue)
*/
public void purgeHL7InQueue(HL7InQueue hl7InQueue) {
dao.deleteHL7InQueue(hl7InQueue);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#saveHL7InQueue(org.openmrs.hl7.HL7InQueue)
*/
@@ -266,14 +266,14 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
if (hl7InQueue.getDateCreated() == null) {
hl7InQueue.setDateCreated(new Date());
}
-
+
if (hl7InQueue.getMessageState() == null) {
hl7InQueue.setMessageState(HL7Constants.HL7_STATUS_PENDING);
}
-
+
return dao.saveHL7InQueue(hl7InQueue);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7InQueue(java.lang.Integer)
*/
@@ -281,13 +281,13 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public HL7InQueue getHL7InQueue(Integer hl7InQueueId) {
return dao.getHL7InQueue(hl7InQueueId);
}
-
+
@Override
@Transactional(readOnly = true)
public HL7InQueue getHL7InQueueByUuid(String uuid) throws APIException {
return dao.getHL7InQueueByUuid(uuid);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getNextHL7InQueue()
*/
@@ -295,7 +295,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public HL7InQueue getNextHL7InQueue() {
return dao.getNextHL7InQueue();
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7InArchiveByState(java.lang.Integer)
*/
@@ -303,7 +303,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public List<HL7InArchive> getHL7InArchiveByState(Integer state) throws APIException {
return dao.getHL7InArchiveByState(state);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7InQueueByState(java.lang.Integer)
*/
@@ -311,7 +311,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public List<HL7InQueue> getHL7InQueueByState(Integer state) throws APIException {
return dao.getHL7InQueueByState(state);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getAllHL7InArchives()
*/
@@ -319,7 +319,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public List<HL7InArchive> getAllHL7InArchives() throws APIException {
return dao.getAllHL7InArchives();
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#purgeHL7InArchive(org.openmrs.hl7.HL7InArchive)
*/
@@ -328,7 +328,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
dao.deleteHL7InArchive(hl7InArchive);
}
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#saveHL7InArchive(org.openmrs.hl7.HL7InArchive)
*/
@@ -338,7 +338,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
return dao.saveHL7InArchive(hl7InArchive);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7InArchive(java.lang.Integer)
*/
@@ -346,14 +346,14 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public HL7InArchive getHL7InArchive(Integer hl7InArchiveId) {
return dao.getHL7InArchive(hl7InArchiveId);
}
-
+
/**
* get a list of archives to be migrated to the filesystem
*/
private List<HL7InArchive> getHL7InArchivesToMigrate() {
return dao.getHL7InArchivesToMigrate();
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getAllHL7InErrors()
*/
@@ -361,14 +361,14 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public List<HL7InError> getAllHL7InErrors() throws APIException {
return dao.getAllHL7InErrors();
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#purgeHL7InError(org.openmrs.hl7.HL7InError)
*/
public void purgeHL7InError(HL7InError hl7InError) throws APIException {
dao.deleteHL7InError(hl7InError);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#saveHL7InError(org.openmrs.hl7.HL7InError)
*/
@@ -378,7 +378,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
return dao.saveHL7InError(hl7InError);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7InError(java.lang.Integer)
*/
@@ -386,7 +386,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
public HL7InError getHL7InError(Integer hl7InErrorId) {
return dao.getHL7InError(hl7InErrorId);
}
-
+
@Override
@Transactional(readOnly = true)
public HL7InError getHL7InErrorByUuid(String uuid) throws APIException {
@@ -394,6 +394,15 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
/**
+ * @param idNum idNumber
+ * @param famName familyName
+ * @param givName givenName
+ */
+ public void userNotFound(String idNum, String famName, String givName) {
+ String errorMsg = "Error resolving user with id '" + idNum + "' family name '" + famName
+ + "' and given name '" + givName + "'";
+ }
+ /**
* @param xcn HL7 component of data type XCN (extended composite ID number and name for persons)
* (see HL7 2.5 manual Ch.2A.86)
* @return Internal ID # of the specified user, or null if that user can't be found or is
@@ -404,11 +413,11 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
String idNumber = xcn.getIDNumber().getValue();
String familyName = xcn.getFamilyName().getSurname().getValue();
String givenName = xcn.getGivenName().getValue();
-
+
// unused
// String assigningAuthority = xcn.getAssigningAuthority()
// .getUniversalID().getValue();
-
+
/*
* if ("null".equals(familyName)) familyName = null; if
* ("null".equals(givenName)) givenName = null; if
@@ -430,8 +439,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
try {
List<User> users = Context.getUserService().getUsersByName(givenName,familyName,true);
if( users == null) {
- log.error("Error resolving user with id '" + idNumber + "' family name '" + familyName
- + "' and given name '" + givenName + "': User not found");
+ log.error(userNotFound(idNumber, familyName, givenName) + "User not found.");
return null;
}
else if( users.size() == 1){
@@ -439,19 +447,17 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
else{
//Return null if that user ambiguous
- log.error("Error resolving user with id '" + idNumber + "' family name '" + familyName
- + "' and given name '" + givenName + "': Found " + users.size() + " ambiguous users.");
+ log.error(userNotFound(idNumber, familyName, givenName) + ": Found " + users.size() + " ambiguous users.");
return null;
}
}
catch (Exception e) {
- log.error("Error resolving user with id '" + idNumber + "' family name '" + familyName
- + "' and given name '" + givenName + "'", e);
+ log.error(userNotFound(idNumber, familyName, givenName), e);
return null;
}
}
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#resolvePersonId(ca.uhn.hl7v2.model.v25.datatype.XCN)
*/
@@ -460,7 +466,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
String idNumber = xcn.getIDNumber().getValue();
String familyName = xcn.getFamilyName().getSurname().getValue();
String givenName = xcn.getGivenName().getValue();
-
+
if (idNumber != null && idNumber.length() > 0) {
try {
Person person = Context.getPersonService().getPerson(Integer.valueOf(idNumber));
@@ -483,7 +489,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
}
}
-
+
/**
* @param pl HL7 component of data type PL (person location) (see Ch 2.A.53)
* @return internal identifier of the specified location, or null if it is not found or
@@ -511,7 +517,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
+ "' as a location.location_id", ex);
}
}
-
+
// Treat the 4th component "Facility" as location.name
try {
Location l = Context.getLocationService().getLocation(facility);
@@ -525,7 +531,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
return null;
}
}
-
+
/**
* @param pid A PID segment of an hl7 message
* @return The internal id number of the Patient described by the PID segment, or null of the
@@ -540,7 +546,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
return null;
}
-
+
/**
* @param identifiers CX identifier list from an identifier (either PID or NK1)
* @return The internal id number of the Patient based on one of the given identifiers, or null
@@ -552,25 +558,25 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
// TODO: Properly handle assigning authority. If specified it's
// currently treated as PatientIdentifierType.name
// TODO: Throw exceptions instead of returning null in some cases
-
+
// give up if no identifiers exist
if (identifiers.length < 1) {
throw new HL7Exception("Missing patient identifier in PID segment");
}
-
+
// TODO other potential identifying characteristics in PID we could use
// to identify the patient
// XPN[] patientName = pid.getPersonName();
// String gender = pid.getAdministrativeSex().getValue();
// TS dateOfBirth = pid.getDateTimeOfBirth();
-
+
// Take the first uniquely matching identifier
for (CX identifier : identifiers) {
String hl7PersonId = identifier.getIDNumber().getValue();
// TODO if 1st component is blank, check 2nd and 3rd of assigning
// authority
String assigningAuthority = identifier.getAssigningAuthority().getNamespaceID().getValue();
-
+
if (StringUtils.isNotBlank(assigningAuthority)) {
// Assigning authority defined
try {
@@ -647,26 +653,26 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
}
}
-
+
return null;
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#garbageCollect()
*/
public void garbageCollect() {
dao.garbageCollect();
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#processHL7InQueue(org.openmrs.hl7.HL7InQueue)
*/
public HL7InQueue processHL7InQueue(HL7InQueue hl7InQueue) throws HL7Exception {
-
+
if (hl7InQueue == null) {
throw new HL7Exception("hl7InQueue argument cannot be null");
}
-
+
// mark this queue object as processing so that it isn't processed twice
if (OpenmrsUtil.nullSafeEquals(HL7Constants.HL7_STATUS_PROCESSING, hl7InQueue.getMessageState())) {
throw new HL7Exception("The hl7InQueue message with id: " + hl7InQueue.getHL7InQueueId()
@@ -674,12 +680,12 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
} else {
hl7InQueue.setMessageState(HL7Constants.HL7_STATUS_PROCESSING);
}
-
+
if (log.isDebugEnabled()) {
log.debug("Processing HL7 inbound queue (id=" + hl7InQueue.getHL7InQueueId() + ",key="
+ hl7InQueue.getHL7SourceKey() + ")");
}
-
+
// Parse the HL7 into an HL7Message or abort with failure
String hl7Message = hl7InQueue.getHL7Data();
try {
@@ -687,18 +693,18 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
// NOT making a direct call here so that AOP can happen around this
// method
Message parsedMessage = Context.getHL7Service().parseHL7String(hl7Message);
-
+
// Send the parsed message to our receiver routine for processing
// into db
// NOT making a direct call here so that AOP can happen around this
// method
Context.getHL7Service().processHL7Message(parsedMessage);
-
+
// Move HL7 inbound queue entry into the archive before exiting
log.debug("Archiving HL7 inbound queue entry");
-
+
Context.getHL7Service().saveHL7InArchive(new HL7InArchive(hl7InQueue));
-
+
log.debug("Removing HL7 message from inbound queue");
Context.getHL7Service().purgeHL7InQueue(hl7InQueue);
}
@@ -719,16 +725,16 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
if (!skipError) {
setFatalError(hl7InQueue, "Trouble parsing HL7 message (" + hl7InQueue.getHL7SourceKey() + ")", e);
}
-
+
}
catch (Exception e) {
setFatalError(hl7InQueue, "Exception while attempting to process HL7 In Queue (" + hl7InQueue.getHL7SourceKey()
+ ")", e);
}
-
+
return hl7InQueue;
}
-
+
/**
* Convenience method to respond to fatal errors by moving the queue entry into an error bin
* prior to aborting
@@ -746,14 +752,14 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
Context.getHL7Service().purgeHL7InQueue(hl7InQueue);
log.info(error, cause);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#parseHL7String(String)
*/
public Message parseHL7String(String hl7Message) throws HL7Exception {
// Any pre-parsing for HL7 messages would go here
// or a module can use AOP to pre-parse the message
-
+
// First, try and parse the message
Message message;
try {
@@ -765,10 +771,10 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
catch (ca.uhn.hl7v2.HL7Exception e) {
throw new HL7Exception("Error parsing message", e);
}
-
+
return message;
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getHL7InArchiveByUuid(java.lang.String)
*/
@@ -780,14 +786,14 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
return dao.getHL7InArchiveByUuid(uuid);
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#processHL7Message(ca.uhn.hl7v2.model.Message)
*/
public Message processHL7Message(Message message) throws HL7Exception {
// Any post-parsing (pre-routing) processing would go here
// or a module can use AOP to do the post-parsing
-
+
Message response;
try {
if (!router.canProcess(message)) {
@@ -799,10 +805,10 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
catch (ApplicationException e) {
throw new HL7Exception("Error while processing HL7 message: " + message.getName(), e);
}
-
+
return response;
}
-
+
/**
* Sets the given handlers as router applications that are available to HAPI when it is parsing
* an hl7 message.<br>
@@ -820,14 +826,14 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
if (!messageName.contains("_")) {
throw new APIException("Hl7Service.invalid.messageName", (Object[]) null);
}
-
+
String messageType = messageName.split("_")[0];
String triggerEvent = messageName.split("_")[1];
-
+
router.registerApplication(messageType, triggerEvent, entry.getValue());
}
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#createPersonFromNK1(ca.uhn.hl7v2.model.v25.segment.NK1)
*/
@@ -835,9 +841,9 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
// NOTE: following block (with minor modifications) stolen from
// ADTA28Handler
// TODO: generalize this for use with both PID and NK1 segments
-
+
Person person = new Person();
-
+
// UUID
CX[] identifiers = nk1.getNextOfKinAssociatedPartySIdentifiers();
String uuid = getUuidFromIdentifiers(identifiers);
@@ -845,18 +851,18 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
throw new HL7Exception("Non-unique UUID '" + uuid + "' for new person");
}
person.setUuid(uuid);
-
+
// Patient Identifiers
List<PatientIdentifier> goodIdentifiers = new ArrayList<PatientIdentifier>();
for (CX id : identifiers) {
-
+
String assigningAuthority = id.getAssigningAuthority().getNamespaceID().getValue();
String hl7PatientId = id.getIDNumber().getValue();
-
+
log.debug("identifier has id=" + hl7PatientId + " assigningAuthority=" + assigningAuthority);
-
+
if (assigningAuthority != null && assigningAuthority.length() > 0) {
-
+
try {
PatientIdentifierType pit = Context.getPatientService().getPatientIdentifierTypeByName(
assigningAuthority);
@@ -869,14 +875,14 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
PatientIdentifier pi = new PatientIdentifier();
pi.setIdentifierType(pit);
pi.setIdentifier(hl7PatientId);
-
+
// Get default location
Location location = Context.getLocationService().getDefaultLocation();
if (location == null) {
throw new HL7Exception("Cannot find default location");
}
pi.setLocation(location);
-
+
try {
PatientIdentifierValidator.validateIdentifier(pi);
goodIdentifiers.add(pi);
@@ -884,7 +890,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
catch (PatientIdentifierException ex) {
log.warn("Patient identifier in NK1 is invalid: " + pi, ex);
}
-
+
}
catch (Exception e) {
log.error("Uncaught error parsing/creating patient identifier '" + hl7PatientId
@@ -900,12 +906,12 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
if (goodIdentifiers.size() == 1) {
goodIdentifiers.get(0).setPreferred(true);
}
-
+
// cast the person as a Patient and add identifiers
person = new Patient(person);
((Patient) person).addIdentifiers(goodIdentifiers);
}
-
+
// Person names
for (XPN patientNameX : nk1.getNKName()) {
PersonName name = new PersonName();
@@ -914,7 +920,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
name.setMiddleName(patientNameX.getSecondAndFurtherGivenNamesOrInitialsThereof().getValue());
person.addName(name);
}
-
+
// Gender (checks for null, but not for 'M' or 'F')
String gender = nk1.getAdministrativeSex().getValue();
if (gender == null) {
@@ -925,35 +931,35 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
throw new HL7Exception("Unrecognized gender: " + gender);
}
person.setGender(gender);
-
+
// Date of Birth
TS dateOfBirth = nk1.getDateTimeOfBirth();
if (dateOfBirth == null || dateOfBirth.getTime() == null || dateOfBirth.getTime().getValue() == null) {
throw new HL7Exception("Missing birth date in an NK1 segment");
}
person.setBirthdate(HL7Util.parseHL7Timestamp(dateOfBirth.getTime().getValue()));
-
+
// Estimated birthdate?
ID precisionTemp = dateOfBirth.getDegreeOfPrecision();
if (precisionTemp != null && precisionTemp.getValue() != null) {
String precision = precisionTemp.getValue().toUpperCase();
log.debug("The birthdate is estimated: " + precision);
-
+
if ("Y".equals(precision) || "L".equals(precision)) {
person.setBirthdateEstimated(true);
}
}
-
+
// save the new person or patient
if (person instanceof Patient) {
Context.getPatientService().savePatient((Patient) person);
} else {
Context.getPersonService().savePerson(person);
}
-
+
return person;
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#getUuidFromIdentifiers(ca.uhn.hl7v2.model.v25.datatype.CX[])
*/
@@ -974,7 +980,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
// returns null if not found
return uuid;
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#loadHL7InArchiveData(List)
*/
@@ -983,7 +989,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
loadHL7InArchiveData(archive);
}
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#loadHL7InArchiveData(HL7InArchive)
*/
@@ -992,12 +998,12 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
if (archive == null) {
return;
}
-
+
// quit early if the message is not migrated or already loaded
if (!OpenmrsUtil.nullSafeEquals(archive.getMessageState(), HL7Constants.HL7_STATUS_MIGRATED) || archive.isLoaded()) {
return;
}
-
+
try {
archive.setHL7Data(OpenmrsUtil.getFileAsString(new File(new URI(archive.getHL7Data()))));
archive.setLoaded(true);
@@ -1009,27 +1015,27 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
throw new APIException("Hl7Service.unable.convert.archive", new Object[] { archive.getHL7Data() }, e);
}
}
-
+
/**
* @see org.openmrs.hl7.HL7Service#migrateHl7InArchivesToFileSystem(Map)
*/
public void migrateHl7InArchivesToFileSystem(Map<String, Integer> progressStatusMap) throws APIException {
int numberTransferred = 0;
int numberOfFailedTransfers = 0;
-
+
// HL7Constants.HL7_STATUS_ARCHIVED indicates the HL7 has been archived to the filesystem
List<HL7InArchive> hl7InArchives = getHL7InArchivesToMigrate();
-
+
// while we still we have any archives to be processed, process them
while (Hl7InArchivesMigrateThread.isActive() && Hl7InArchivesMigrateThread.getTransferStatus() == Status.RUNNING
&& hl7InArchives != null && hl7InArchives.size() > 0) {
-
+
Iterator<HL7InArchive> iterator = hl7InArchives.iterator();
-
+
while (Hl7InArchivesMigrateThread.isActive() && Hl7InArchivesMigrateThread.getTransferStatus() == Status.RUNNING
&& iterator.hasNext()) {
HL7InArchive archive = iterator.next();
-
+
try {
migrateHL7InArchive(archive);
progressStatusMap.put(HL7Constants.NUMBER_TRANSFERRED_KEY, numberTransferred++);
@@ -1038,16 +1044,16 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
progressStatusMap.put(HL7Constants.NUMBER_OF_FAILED_TRANSFERS_KEY, numberOfFailedTransfers++);
}
}
-
+
// fetch more archives to be processed
hl7InArchives = getHL7InArchivesToMigrate();
}
-
+
if (log.isDebugEnabled()) {
log.debug("Transfer of HL7 archives has completed or has been stopped");
}
}
-
+
/**
* moves data to the filesystem from an HL7InArchive
*
@@ -1058,11 +1064,11 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
if (archive == null) {
throw new APIException("Hl7Service.migrate.null.archive", (Object[]) null);
}
-
+
if (!OpenmrsUtil.nullSafeEquals(archive.getMessageState(), HL7Constants.HL7_STATUS_PROCESSED)) {
throw new APIException("Hl7Service.migrate.archive.state", (Object[]) null);
}
-
+
try {
URI uri = writeHL7InArchiveToFileSystem(archive);
archive.setHL7Data(uri.toString());
@@ -1072,71 +1078,71 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
catch (APIException e) {
throw new APIException("Hl7Service.migrate.archive", null, e);
}
-
+
}
-
+
/**
* writes a given hl7 archive to the file system
*
* @param hl7InArchive the hl7 archive to write to the file system
*/
private URI writeHL7InArchiveToFileSystem(HL7InArchive hl7InArchive) throws APIException {
-
+
PrintWriter writer = null;
File destinationDir = HL7Util.getHl7ArchivesDirectory();
try {
// number formatter used to format month and day with zero padding
DecimalFormat df = new DecimalFormat("00");
-
+
//write the archive to a separate file while grouping them according to
//the year, month and date of month when they were stored in the archives table
Calendar calendar = Calendar.getInstance(Context.getLocale());
calendar.setTime(hl7InArchive.getDateCreated());
-
+
//resolve the year folder from the date of creation of the archive
File yearDir = new File(destinationDir, Integer.toString(calendar.get(Calendar.YEAR)));
if (!yearDir.isDirectory()) {
yearDir.mkdirs();
}
-
+
//resolve the appropriate month folder
File monthDir = new File(yearDir, df.format(calendar.get(Calendar.MONTH) + 1));
if (!monthDir.isDirectory()) {
monthDir.mkdirs();
}
-
+
//resolve the appropriate day of month folder
File dayDir = new File(monthDir, df.format(calendar.get(Calendar.DAY_OF_MONTH)));
if (!dayDir.isDirectory()) {
dayDir.mkdirs();
}
-
+
//use the uuid, source id and source key(if present) to generate the file name
File fileToWriteTo = new File(dayDir, hl7InArchive.getUuid()
+ (StringUtils.isBlank(hl7InArchive.getHL7SourceKey()) ? "" : "_" + hl7InArchive.getHL7SourceKey())
+ ".txt");
-
+
//write the hl7 data to the file
writer = new PrintWriter(fileToWriteTo);
writer.write(hl7InArchive.getHL7Data());
-
+
//check if there was an error while writing to the current file
if (writer.checkError()) {
log.warn("An Error occured while writing hl7 archive with id '" + hl7InArchive.getHL7InArchiveId()
+ "' to the file system");
throw new APIException("Hl7Service.write.no.error", (Object[]) null);
}
-
+
// hand back the URI for the file
return fileToWriteTo.toURI();
-
+
}
catch (FileNotFoundException e) {
log
.warn("Failed to write hl7 archive with id '" + hl7InArchive.getHL7InArchiveId()
+ "' to the file system ", e);
throw new APIException("Hl7Service.write.error", null, e);
-
+
}
finally {
if (writer != null) {
@@ -1144,7 +1150,7 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
}
}
-
+
@Override
@Transactional(readOnly = true)
public HL7QueueItem getHl7QueueItemByUuid(String uuid) throws APIException {
@@ -1165,5 +1171,5 @@ public class HL7ServiceImpl extends BaseOpenmrsService implements HL7Service {
}
return null;
}
-
+
}
diff --git a/api/src/main/java/org/openmrs/messagesource/impl/MutableResourceBundleMessageSource.java b/api/src/main/java/org/openmrs/messagesource/impl/MutableResourceBundleMessageSource.java
index 46a4d2f..5dcabc4 100644
--- a/api/src/main/java/org/openmrs/messagesource/impl/MutableResourceBundleMessageSource.java
+++ b/api/src/main/java/org/openmrs/messagesource/impl/MutableResourceBundleMessageSource.java
@@ -42,19 +42,19 @@ import org.springframework.core.io.support.ResourcePatternResolver;
public class MutableResourceBundleMessageSource extends ReloadableResourceBundleMessageSource implements MutableMessageSource {
private Log log = LogFactory.getLog(getClass());
-
+
/**
* Local reference to basenames used to search for properties files.
*/
private String[] basenames = new String[0];
-
+
private int cacheMilliseconds = -1;
-
+
private long lastCached = System.currentTimeMillis();
-
+
/** Cached list of available locales. */
private Collection<Locale> locales;
-
+
/**
* @see org.openmrs.messagesource.MessageSourceService#getLocales()
*/
@@ -64,16 +64,16 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
locales = findLocales();
lastCached = now;
}
-
+
return locales;
}
-
+
@Override
public void setCacheSeconds(int cacheSeconds) {
this.cacheMilliseconds = cacheSeconds * 1000;
super.setCacheSeconds(cacheSeconds);
}
-
+
/**
* This method looks at the current property files and deduces what locales are available from
* those
@@ -83,22 +83,22 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
*/
private Collection<Locale> findLocales() {
Collection<Locale> foundLocales = new HashSet<Locale>();
-
+
for (Resource propertiesFile : findPropertiesFiles()) {
String filename = propertiesFile.getFilename();
-
+
Locale parsedLocale = parseLocaleFrom(filename);
-
+
foundLocales.add(parsedLocale);
-
+
}
-
+
if (foundLocales.size() == 0) {
log.warn("no locales found.");
}
return foundLocales;
}
-
+
/**
* Utility method for deriving a locale from a filename, presumed to have an embedded locale
* specification near the end. For instance messages_it.properties if the filename is
@@ -109,13 +109,13 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
*/
private Locale parseLocaleFrom(String filename) {
Locale parsedLocale = null;
-
+
// trim off leading basename
filename = filename.substring("messages".length());
-
+
// trim off extension
String localespec = filename.substring(0, filename.indexOf('.'));
-
+
if ("".equals(localespec)) {
parsedLocale = Locale.getDefault();
} else {
@@ -124,7 +124,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
}
return parsedLocale;
}
-
+
/**
* Returns all available messages.
*
@@ -132,7 +132,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
*/
public Collection<PresentationMessage> getPresentations() {
Collection<PresentationMessage> presentations = new Vector<PresentationMessage>();
-
+
for (Resource propertiesFile : findPropertiesFiles()) {
Locale currentLocale = parseLocaleFrom(propertiesFile.getFilename());
Properties props = new Properties();
@@ -145,12 +145,12 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
}
catch (Exception e) {
// skip over errors in loading a single file
- log.error("Unable to load properties from file: " + propertiesFile.getFilename());
+ log.error("Unable to load properties from file: " + propertiesFile.getFilename(), e);
}
}
return presentations;
}
-
+
/**
* Override to obtain a local reference to the basenames.
*
@@ -161,7 +161,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
super.setBasename(basename);
this.basenames = new String[] { basename };
}
-
+
/**
* Override to obtain a local reference to the basenames.
*
@@ -174,7 +174,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
} else {
this.basenames = Arrays.copyOf(basenames, basenames.length);
}
-
+
//add module file urls to basenames used for locating message properties files
Collection<Module> modules = ModuleFactory.getStartedModules();
if (!modules.isEmpty()) {
@@ -185,13 +185,13 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
names[index] = "jar:file:" + module.getFile().getAbsolutePath() + "!/messages";
index++;
}
-
+
basenames = names;
}
-
+
super.setBasenames(basenames);
}
-
+
/**
* @see org.openmrs.messagesource.MutableMessageSource#addPresentation(org.openmrs.messagesource.PresentationMessage)
*/
@@ -202,7 +202,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
try {
OpenmrsUtil.loadProperties(props, propertyFile.getInputStream());
props.setProperty(message.getCode(), message.getMessage());
-
+
//TODO properties files are now in api jar files which cannot be modified. TRUNK-4097
//We should therefore remove this method implementation or stop claiming that we are a mutable resource
//OpenmrsUtil.storeProperties(props, propertyFile.getInputStream(), "OpenMRS Application Messages");
@@ -212,7 +212,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
}
}
}
-
+
/**
* @see org.openmrs.messagesource.MutableMessageSource#removePresentation(org.openmrs.messagesource.PresentationMessage)
*/
@@ -223,7 +223,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
try {
OpenmrsUtil.loadProperties(props, propertyFile.getInputStream());
props.remove(message.getCode());
-
+
//TODO properties files are now in api jar files which cannot be modified. TRUNK-4097
//We should therefore remove this method implementation or stop claiming that we are a mutable resource
//OpenmrsUtil.storeProperties(props, propertyFile, PROPERTIES_FILE_COMMENT);
@@ -233,7 +233,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
}
}
}
-
+
/**
* Convenience method to scan the available properties files, looking for the one that has a
* definition for the given code.
@@ -244,7 +244,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
private Resource findPropertiesFileFor(String code) {
Properties props = new Properties();
Resource foundFile = null;
-
+
for (Resource propertiesFile : findPropertiesFiles()) {
props.clear();
try {
@@ -260,7 +260,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
}
return foundFile;
}
-
+
/**
* Searches the filesystem for message properties files. ABKTODO: consider caching this, rather
* than searching every time
@@ -282,17 +282,17 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
}
return propertiesFiles;
}
-
+
/**
* @see org.openmrs.messagesource.MutableMessageSource#merge(MutableMessageSource, boolean)
*/
public void merge(MutableMessageSource fromSource, boolean overwrite) {
-
+
// collect all existing properties
Resource[] propertiesFiles = findPropertiesFiles();
Map<Locale, List<Resource>> localeToFilesMap = new HashMap<Locale, List<Resource>>();
Map<Resource, Properties> fileToPropertiesMap = new HashMap<Resource, Properties>();
-
+
for (Resource propertiesFile : propertiesFiles) {
Properties props = new Properties();
Locale propsLocale = parseLocaleFrom(propertiesFile.getFilename());
@@ -302,7 +302,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
localeToFilesMap.put(propsLocale, propList);
}
propList.add(propertiesFile);
-
+
try {
OpenmrsUtil.loadProperties(props, propertiesFile.getInputStream());
fileToPropertiesMap.put(propertiesFile, props);
@@ -312,18 +312,18 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
log.error("Unable to load properties from file: " + propertiesFile.getFilename(), e);
}
}
-
+
// merge in the new properties
for (PresentationMessage message : fromSource.getPresentations()) {
Locale messageLocale = message.getLocale();
-
+
List<Resource> filelist = localeToFilesMap.get(messageLocale);
if (filelist != null) {
Properties propertyDestination = null;
boolean propExists = false;
for (Resource propertiesFile : filelist) {
Properties possibleDestination = fileToPropertiesMap.get(propertiesFile);
-
+
if (possibleDestination.containsKey(message.getCode())) {
propertyDestination = possibleDestination;
propExists = true;
@@ -335,15 +335,15 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
if ((propExists && overwrite) || !propExists) {
propertyDestination.put(message.getCode(), message.getMessage());
}
-
+
} else {
// no properties files for this locale
}
-
+
message.getCode();
}
}
-
+
/**
* @see org.openmrs.messagesource.MutableMessageSource#getPresentation(java.lang.String,
* java.util.Locale)
@@ -352,7 +352,7 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
// TODO Auto-generated method stub
return null;
}
-
+
/**
* @see org.openmrs.messagesource.MutableMessageSource#getPresentationsInLocale(java.util.Locale)
*/
@@ -360,5 +360,5 @@ public class MutableResourceBundleMessageSource extends ReloadableResourceBundle
// TODO Auto-generated method stub
return null;
}
-
+
}
diff --git a/api/src/main/java/org/openmrs/util/OpenmrsUtil.java b/api/src/main/java/org/openmrs/util/OpenmrsUtil.java
index 33c990a..f796418 100644
--- a/api/src/main/java/org/openmrs/util/OpenmrsUtil.java
+++ b/api/src/main/java/org/openmrs/util/OpenmrsUtil.java
@@ -118,28 +118,28 @@ import org.w3c.dom.DocumentType;
* Utility methods used in openmrs
*/
public class OpenmrsUtil {
-
+
private static Log log = LogFactory.getLog(OpenmrsUtil.class);
-
+
private static Map<Locale, SimpleDateFormat> dateFormatCache = new HashMap<Locale, SimpleDateFormat>();
-
+
private static Map<Locale, SimpleDateFormat> timeFormatCache = new HashMap<Locale, SimpleDateFormat>();
-
+
/**
* Compares origList to newList returning map of differences
- *
+ *
* @param origList
* @param newList
* @return [List toAdd, List toDelete] with respect to origList
*/
public static <E extends Object> Collection<Collection<E>> compareLists(Collection<E> origList, Collection<E> newList) {
// TODO finish function
-
+
Collection<Collection<E>> returnList = new Vector<Collection<E>>();
-
+
Collection<E> toAdd = new LinkedList<E>();
Collection<E> toDel = new LinkedList<E>();
-
+
// loop over the new list.
for (E currentNewListObj : newList) {
// loop over the original list
@@ -156,22 +156,22 @@ public class OpenmrsUtil {
if (!foundInList) {
toAdd.add(currentNewListObj);
}
-
+
// all found new objects were removed from the orig list,
// leaving only objects needing to be removed
toDel = origList;
-
+
}
-
+
returnList.add(toAdd);
returnList.add(toDel);
-
+
return returnList;
}
-
+
public static boolean isStringInArray(String str, String[] arr) {
boolean retVal = false;
-
+
if (str != null && arr != null) {
for (int i = 0; i < arr.length; i++) {
if (str.equals(arr[i])) {
@@ -181,38 +181,38 @@ public class OpenmrsUtil {
}
return retVal;
}
-
+
public static Boolean isInNormalNumericRange(Float value, ConceptNumeric concept) {
if (concept.getHiNormal() == null || concept.getLowNormal() == null) {
return false;
}
return (value <= concept.getHiNormal() && value >= concept.getLowNormal());
}
-
+
public static Boolean isInCriticalNumericRange(Float value, ConceptNumeric concept) {
if (concept.getHiCritical() == null || concept.getLowCritical() == null) {
return false;
}
return (value <= concept.getHiCritical() && value >= concept.getLowCritical());
}
-
+
public static Boolean isInAbsoluteNumericRange(Float value, ConceptNumeric concept) {
if (concept.getHiAbsolute() == null || concept.getLowAbsolute() == null) {
return false;
}
return (value <= concept.getHiAbsolute() && value >= concept.getLowAbsolute());
}
-
+
public static Boolean isValidNumericValue(Float value, ConceptNumeric concept) {
if (concept.getHiAbsolute() == null || concept.getLowAbsolute() == null) {
return true;
}
return (value <= concept.getHiAbsolute() && value >= concept.getLowAbsolute());
}
-
+
/**
* Return a string representation of the given file
- *
+ *
* @param file
* @return String file contents
* @throws IOException
@@ -230,10 +230,10 @@ public class OpenmrsUtil {
reader.close();
return fileData.toString();
}
-
+
/**
* Return a byte array representation of the given file
- *
+ *
* @param file
* @return byte[] file contents
* @throws IOException
@@ -259,14 +259,14 @@ public class OpenmrsUtil {
}
}
}
-
+
return null;
}
-
+
/**
* Copy file from inputStream onto the outputStream inputStream is not closed in this method
* outputStream /is/ closed at completion of this method
- *
+ *
* @param inputStream Stream to copy from
* @param outputStream Stream/location to copy to
* @throws IOException thrown if an error occurs during read/write
@@ -280,10 +280,10 @@ public class OpenmrsUtil {
catch (Exception e) { /* pass */
}
}
-
+
return;
}
-
+
InputStream in = null;
OutputStream out = null;
try {
@@ -310,9 +310,9 @@ public class OpenmrsUtil {
catch (Exception e) { /* pass */
}
}
-
+
}
-
+
/**
* Get mime type of the given file
*
@@ -323,10 +323,10 @@ public class OpenmrsUtil {
MimetypesFileTypeMap mimeMap = new MimetypesFileTypeMap();
return mimeMap.getContentType(file);
}
-
+
/**
* Look for a file named <code>filename</code> in folder
- *
+ *
* @param folder
* @param filename
* @return true/false whether filename exists in folder
@@ -338,7 +338,7 @@ public class OpenmrsUtil {
if (!folder.isDirectory()) {
return false;
}
-
+
for (File f : folder.listFiles()) {
if (f.getName().equals(filename)) {
return true;
@@ -346,28 +346,28 @@ public class OpenmrsUtil {
}
return false;
}
-
+
/**
* These are the privileges that are required by OpenMRS. This looks for privileges marked as
* {@link AddOnStartup} to know which privs, upon startup or loading of a module, to insert into
* the database if they do not exist already. These privileges are not allowed to be deleted.
* They are marked as 'locked' in the administration screens.
- *
+ *
* @return privileges core to the system
* @see PrivilegeConstants
* @see Context#checkCoreDataset()
*/
public static Map<String, String> getCorePrivileges() {
Map<String, String> corePrivileges = new HashMap<String, String>();
-
+
// TODO getCorePrivileges() is called so so many times that getClassesWithAnnotation() better do some catching.
Set<Class<?>> classes = OpenmrsClassScanner.getInstance().getClassesWithAnnotation(HasAddOnStartupPrivileges.class);
-
+
for (Class cls : classes) {
Field[] flds = cls.getDeclaredFields();
for (Field fld : flds) {
String fieldValue = null;
-
+
AddOnStartup privilegeAnnotation = fld.getAnnotation(AddOnStartup.class);
if (null == privilegeAnnotation) {
continue;
@@ -375,7 +375,7 @@ public class OpenmrsUtil {
if (!privilegeAnnotation.core()) {
continue;
}
-
+
try {
fieldValue = (String) fld.get(null);
}
@@ -385,28 +385,28 @@ public class OpenmrsUtil {
corePrivileges.put(fieldValue, privilegeAnnotation.description());
}
}
-
+
// always add the module core privileges back on
for (org.openmrs.Privilege privilege : ModuleFactory.getPrivileges()) {
corePrivileges.put(privilege.getPrivilege(), privilege.getDescription());
}
-
+
return corePrivileges;
}
-
+
/**
* All roles returned by this method are inserted into the database if they do not exist
* already. These roles are also forbidden to be deleted from the administration screens.
- *
+ *
* @return roles that are core to the system
*/
public static Map<String, String> getCoreRoles() {
Map<String, String> roles = new HashMap<String, String>();
-
+
Field[] flds = RoleConstants.class.getDeclaredFields();
for (Field fld : flds) {
String fieldValue = null;
-
+
AddOnStartup roleAnnotation = fld.getAnnotation(AddOnStartup.class);
if (null == roleAnnotation) {
continue;
@@ -414,7 +414,7 @@ public class OpenmrsUtil {
if (!roleAnnotation.core()) {
continue;
}
-
+
try {
fieldValue = (String) fld.get(null);
}
@@ -423,47 +423,47 @@ public class OpenmrsUtil {
}
roles.put(fieldValue, roleAnnotation.description());
}
-
+
return roles;
}
-
+
/**
* Initialize global settings Find and load modules
- *
+ *
* @param p properties from runtime configuration
*/
public static void startup(Properties p) {
-
+
// Override global OpenMRS constants if specified by the user
-
+
// Allow for "demo" mode where patient data is obscured
String val = p.getProperty("obscure_patients", null);
if (val != null && "true".equalsIgnoreCase(val)) {
OpenmrsConstants.OBSCURE_PATIENTS = true;
}
-
+
val = p.getProperty("obscure_patients.family_name", null);
if (val != null) {
OpenmrsConstants.OBSCURE_PATIENTS_FAMILY_NAME = val;
}
-
+
val = p.getProperty("obscure_patients.given_name", null);
if (val != null) {
OpenmrsConstants.OBSCURE_PATIENTS_GIVEN_NAME = val;
}
-
+
val = p.getProperty("obscure_patients.middle_name", null);
if (val != null) {
OpenmrsConstants.OBSCURE_PATIENTS_MIDDLE_NAME = val;
}
-
+
// Override the default "openmrs" database name
val = p.getProperty("connection.database_name", null);
if (val == null) {
// the database name wasn't supplied explicitly, guess it
// from the connection string
val = p.getProperty("connection.url", null);
-
+
if (val != null) {
try {
int endIndex = val.lastIndexOf("?");
@@ -480,20 +480,20 @@ public class OpenmrsUtil {
}
}
}
-
+
// set the business database name
val = p.getProperty("connection.database_business_name", null);
if (val == null) {
val = OpenmrsConstants.DATABASE_NAME;
}
OpenmrsConstants.DATABASE_BUSINESS_NAME = val;
-
+
// set global log level
applyLogLevels();
-
+
setupLogAppenders();
}
-
+
/**
* Set the org.openmrs log4j logger's level if global property log.level.openmrs (
* OpenmrsConstants.GLOBAL_PROPERTY_LOG_LEVEL ) exists. Valid values for global property are
@@ -502,7 +502,7 @@ public class OpenmrsUtil {
public static void applyLogLevels() {
AdministrationService adminService = Context.getAdministrationService();
String logLevel = adminService.getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_LOG_LEVEL, "");
-
+
String[] levels = logLevel.split(",");
for (String level : levels) {
String[] classAndLevel = level.split(":");
@@ -513,15 +513,15 @@ public class OpenmrsUtil {
}
}
}
-
+
/**
* Setup root level log appenders.
- *
+ *
* @since 1.9.2
*/
public static void setupLogAppenders() {
Logger rootLogger = Logger.getRootLogger();
-
+
FileAppender fileAppender = null;
@SuppressWarnings("rawtypes")
Enumeration appenders = rootLogger.getAllAppenders();
@@ -532,11 +532,11 @@ public class OpenmrsUtil {
break;
}
}
-
+
String logLayout = Context.getAdministrationService().getGlobalProperty(OpenmrsConstants.GP_LOG_LAYOUT,
"%p - %C{1}.%M(%L) |%d{ISO8601}| %m%n");
PatternLayout patternLayout = new PatternLayout(logLayout);
-
+
String logLocation = null;
try {
logLocation = OpenmrsUtil.getOpenmrsLogLocation();
@@ -554,25 +554,25 @@ public class OpenmrsUtil {
log.error("Error while setting an OpenMRS log file to " + logLocation, e);
}
}
-
+
/**
* Set the log4j log level for class <code>logClass</code> to <code>logLevel</code>.
- *
+ *
* @param logClass optional string giving the class level to change. Defaults to
* OpenmrsConstants.LOG_CLASS_DEFAULT . Should be something like org.openmrs.___
* @param logLevel one of OpenmrsConstants.LOG_LEVEL_*
*/
public static void applyLogLevel(String logClass, String logLevel) {
-
+
if (logLevel != null) {
-
+
// the default log level is org.openmrs
if (StringUtils.isEmpty(logClass)) {
logClass = OpenmrsConstants.LOG_CLASS_DEFAULT;
}
-
+
Logger logger = Logger.getLogger(logClass);
-
+
logLevel = logLevel.toLowerCase();
if (OpenmrsConstants.LOG_LEVEL_TRACE.equals(logLevel)) {
logger.setLevel(Level.TRACE);
@@ -592,11 +592,11 @@ public class OpenmrsUtil {
}
}
}
-
+
/**
* Takes a String like "size=compact|order=date" and returns a Map&lt;String,String&gt; from the keys
* to the values.
- *
+ *
* @param paramList <code>String</code> with a list of parameters
* @return Map&lt;String, String&gt; of the parameters passed
*/
@@ -626,7 +626,7 @@ public class OpenmrsUtil {
}
return (d1 instanceof Date && d2 instanceof Date) ? compare((Date) d1, (Date) d2) == 0 : d1.equals(d2);
}
-
+
/**
* Compares two java.util.Date objects, but handles java.sql.Timestamp (which is not directly
* comparable to a date) by dropping its nanosecond value.
@@ -643,7 +643,7 @@ public class OpenmrsUtil {
}
return d1.compareTo(d2);
}
-
+
/**
* Compares two Date/Timestamp objects, treating null as the earliest possible date.
*/
@@ -659,7 +659,7 @@ public class OpenmrsUtil {
return compare(d1, d2);
}
}
-
+
/**
* Compares two Date/Timestamp objects, treating null as the earliest possible date.
*/
@@ -675,7 +675,7 @@ public class OpenmrsUtil {
return compare(d1, d2);
}
}
-
+
public static <E extends Comparable<E>> int compareWithNullAsLowest(E c1, E c2) {
if (c1 == null && c2 == null) {
return 0;
@@ -688,7 +688,7 @@ public class OpenmrsUtil {
return c1.compareTo(c2);
}
}
-
+
public static <E extends Comparable<E>> int compareWithNullAsGreatest(E c1, E c2) {
if (c1 == null && c2 == null) {
return 0;
@@ -701,10 +701,10 @@ public class OpenmrsUtil {
return c1.compareTo(c2);
}
}
-
+
/**
* Converts a collection to a String with a specified separator between all elements
- *
+ *
* @param c Collection to be joined
* @param separator string to put between all elements
* @return a String representing the toString() of all elements in c, separated by separator
@@ -713,7 +713,7 @@ public class OpenmrsUtil {
if (c == null) {
return "";
}
-
+
StringBuilder ret = new StringBuilder();
for (Iterator<E> i = c.iterator(); i.hasNext();) {
ret.append(i.next());
@@ -723,14 +723,14 @@ public class OpenmrsUtil {
}
return ret.toString();
}
-
+
public static Set<Concept> conceptSetHelper(String descriptor) {
Set<Concept> ret = new HashSet<Concept>();
if (descriptor == null || descriptor.length() == 0) {
return ret;
}
ConceptService cs = Context.getConceptService();
-
+
for (StringTokenizer st = new StringTokenizer(descriptor, "|"); st.hasMoreTokens();) {
String s = st.nextToken().trim();
boolean isSet = s.startsWith("set:");
@@ -758,10 +758,10 @@ public class OpenmrsUtil {
}
return ret;
}
-
+
/**
* Parses and loads a delimited list of concept ids or names
- *
+ *
* @param delimitedString the delimited list of concept ids or names
* @param delimiter the delimiter, e.g. ","
* @return the list of concepts
@@ -769,27 +769,27 @@ public class OpenmrsUtil {
*/
public static List<Concept> delimitedStringToConceptList(String delimitedString, String delimiter) {
List<Concept> ret = null;
-
+
if (delimitedString != null) {
String[] tokens = delimitedString.split(delimiter);
for (String token : tokens) {
Integer conceptId = null;
-
+
try {
conceptId = Integer.valueOf(token);
}
catch (NumberFormatException nfe) {
conceptId = null;
}
-
+
Concept c = null;
-
+
if (conceptId != null) {
c = Context.getConceptService().getConcept(conceptId);
} else {
c = Context.getConceptService().getConceptByName(token);
}
-
+
if (c != null) {
if (ret == null) {
ret = new ArrayList<Concept>();
@@ -798,18 +798,18 @@ public class OpenmrsUtil {
}
}
}
-
+
return ret;
}
-
+
public static Map<String, Concept> delimitedStringToConceptMap(String delimitedString, String delimiter) {
Map<String, Concept> ret = null;
-
+
if (delimitedString != null) {
String[] tokens = delimitedString.split(delimiter);
for (String token : tokens) {
Concept c = Context.getConceptService().getConcept(token);
-
+
if (c != null) {
if (ret == null) {
ret = new HashMap<String, Concept>();
@@ -818,10 +818,10 @@ public class OpenmrsUtil {
}
}
}
-
+
return ret;
}
-
+
// TODO: properly handle duplicates
public static List<Concept> conceptListHelper(String descriptor) {
List<Concept> ret = new ArrayList<Concept>();
@@ -829,7 +829,7 @@ public class OpenmrsUtil {
return ret;
}
ConceptService cs = Context.getConceptService();
-
+
for (StringTokenizer st = new StringTokenizer(descriptor, "|"); st.hasMoreTokens();) {
String s = st.nextToken().trim();
boolean isSet = s.startsWith("set:");
@@ -857,11 +857,11 @@ public class OpenmrsUtil {
}
return ret;
}
-
+
/**
* Gets the date having the last millisecond of a given day. Meaning that the hours, seconds,
* and milliseconds are the latest possible for that day.
- *
+ *
* @param day the day.
* @return the date with the last millisecond of the day.
*/
@@ -872,14 +872,14 @@ public class OpenmrsUtil {
calender.set(Calendar.MINUTE, 59);
calender.set(Calendar.SECOND, 59);
calender.set(Calendar.MILLISECOND, 999);
-
+
return calender.getTime();
}
-
+
/**
* Return a date that is the same day as the passed in date, but the hours and seconds are the
* earliest possible for that day.
- *
+ *
* @param date date to adjust
* @return a date that is the first possible time in the day
* @since 1.9
@@ -888,24 +888,24 @@ public class OpenmrsUtil {
if (date == null) {
return null;
}
-
+
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
-
+
return c.getTime();
}
-
+
public static Date safeDate(Date d1) {
return new Date(d1.getTime());
}
-
+
/**
* Recursively deletes files in the given <code>dir</code> folder
- *
+ *
* @param dir File directory to delete
* @return true/false whether the delete was completed successfully
* @throws IOException if <code>dir</code> is not a directory
@@ -914,44 +914,44 @@ public class OpenmrsUtil {
if (!dir.exists() || !dir.isDirectory()) {
throw new IOException("Could not delete directory '" + dir.getAbsolutePath() + "' (not a directory)");
}
-
+
if (log.isDebugEnabled()) {
log.debug("Deleting directory " + dir.getAbsolutePath());
}
-
+
File[] fileList = dir.listFiles();
for (File f : fileList) {
if (f.isDirectory()) {
deleteDirectory(f);
}
boolean success = f.delete();
-
+
if (log.isDebugEnabled()) {
log.debug(" deleting " + f.getName() + " : " + (success ? "ok" : "failed"));
}
-
+
if (!success) {
f.deleteOnExit();
}
}
-
+
boolean success = dir.delete();
-
+
if (!success) {
log.warn(" ...could not remove directory: " + dir.getAbsolutePath());
dir.deleteOnExit();
}
-
+
if (success && log.isDebugEnabled()) {
log.debug(" ...and directory itself");
}
-
+
return success;
}
-
+
/**
* Utility method to convert local URL to a File object.
- *
+ *
* @param url an URL
* @return file object for given URL or <code>null</code> if URL is not local
* @should return null given null parameter
@@ -962,7 +962,7 @@ public class OpenmrsUtil {
}
return new File(url.getFile().replaceAll("%20", " "));
}
-
+
/**
* Opens input stream for given resource. This method behaves differently for different URL
* types:
@@ -974,7 +974,7 @@ public class OpenmrsUtil {
* API.</li>
* </ul>
* It is not recommended to use this method for big resources within JAR files.
- *
+ *
* @param url resource URL
* @return input stream for given resource
* @throws IOException if any I/O error has occurred
@@ -1021,23 +1021,24 @@ public class OpenmrsUtil {
jarFile.close();
}
}
-
+
/**
* <pre>
- * Returns the application data directory. Searches for the value first
+ * Returns the application data directory. Searches for the value first
* in the "OPENMRS_APPLICATION_DATA_DIRECTORY" system property and "application_data_directory" runtime property, then in the servlet
* init parameter "application.data.directory." If not found, returns:
* a) "{user.home}/.OpenMRS" on UNIX-based systems
* b) "{user.home}\Application Data\OpenMRS" on Windows
- *
+ *
* </pre>
- *
+ *
* @return The path to the directory on the file system that will hold miscellaneous data about
* the application (runtime properties, modules, etc)
*/
public static String getApplicationDataDirectory() {
String filepath = null;
-
+ String openmrsFolder = "OpenMRS";
+
String systemProperty = System.getProperty(OpenmrsConstants.KEY_OPENMRS_APPLICATION_DATA_DIRECTORY);
//System and runtime property take precedence
if (StringUtils.isNotBlank(systemProperty)) {
@@ -1049,41 +1050,41 @@ public class OpenmrsUtil {
filepath = runtimeProperty;
}
}
-
+
if (filepath == null) {
if (OpenmrsConstants.UNIX_BASED_OPERATING_SYSTEM) {
filepath = System.getProperty("user.home") + File.separator + ".OpenMRS";
if (!canWrite(new File(filepath))) {
log.warn("Unable to write to users home dir, fallback to: "
+ OpenmrsConstants.APPLICATION_DATA_DIRECTORY_FALLBACK_UNIX);
- filepath = OpenmrsConstants.APPLICATION_DATA_DIRECTORY_FALLBACK_UNIX + File.separator + "OpenMRS";
+ filepath = OpenmrsConstants.APPLICATION_DATA_DIRECTORY_FALLBACK_UNIX + File.separator + openmrsFolder;
}
} else {
filepath = System.getProperty("user.home") + File.separator + "Application Data" + File.separator
- + "OpenMRS";
+ + openmrsFolder;
if (!canWrite(new File(filepath))) {
log.warn("Unable to write to users home dir, fallback to: "
+ OpenmrsConstants.APPLICATION_DATA_DIRECTORY_FALLBACK_WIN);
- filepath = OpenmrsConstants.APPLICATION_DATA_DIRECTORY_FALLBACK_WIN + File.separator + "OpenMRS";
+ filepath = OpenmrsConstants.APPLICATION_DATA_DIRECTORY_FALLBACK_WIN + File.separator + openmrsFolder;
}
}
-
+
filepath = filepath + File.separator;
}
-
+
File folder = new File(filepath);
if (!folder.exists()) {
folder.mkdirs();
}
-
+
return filepath;
}
-
+
/**
* Can be used to override default application data directory.
* <p>
* Note that it will not override application data directory provided as a system property.
- *
+ *
* @param path
* @since 1.11
*/
@@ -1095,48 +1096,48 @@ public class OpenmrsUtil {
System.setProperty(OpenmrsConstants.KEY_OPENMRS_APPLICATION_DATA_DIRECTORY, path);
}
}
-
+
/**
* Checks if we can write to a given folder.
- *
+ *
* @param folder the directory to check.
* @return true if we can write to it, else false.
*/
private static boolean canWrite(File folder) {
try {
- //We need to first create the folder if it does not exist,
+ //We need to first create the folder if it does not exist,
//else File.canWrite() will return false even when we
//have the necessary permissions.
if (!folder.exists()) {
folder.mkdirs();
}
-
+
return folder.canWrite();
}
catch (SecurityException ex) {
//all we wanted to know is whether we have permissions
}
-
+
return false;
}
-
+
/**
* Returns the location of the OpenMRS log file.
- *
+ *
* @return the path to the OpenMRS log file
* @since 1.9.2
*/
public static String getOpenmrsLogLocation() {
String logPathGP = Context.getAdministrationService().getGlobalProperty(OpenmrsConstants.GP_LOG_LOCATION, "");
File logPath = OpenmrsUtil.getDirectoryInApplicationDataDirectory(logPathGP);
-
+
File logFile = new File(logPath, "openmrs.log");
return logFile.getPath();
}
-
+
/**
* Checks whether the current JVM version is at least Java 6.
- *
+ *
* @throws ApplicationContextException if the current JVM version is earlier than Java 6
*/
public static void validateJavaVersion() {
@@ -1145,41 +1146,41 @@ public class OpenmrsUtil {
throw new APIException("OpenMRS requires Java 6, but is running under " + JdkVersion.getJavaVersion());
}
}
-
+
/**
* Find the given folderName in the application data directory. Or, treat folderName like an
* absolute url to a directory
- *
+ *
* @param folderName
* @return folder capable of storing information
*/
public static File getDirectoryInApplicationDataDirectory(String folderName) throws APIException {
// try to load the repository folder straight away.
File folder = new File(folderName);
-
+
// if the property wasn't a full path already, assume it was intended to
// be a folder in the
// application directory
if (!folder.isAbsolute()) {
folder = new File(OpenmrsUtil.getApplicationDataDirectory(), folderName);
}
-
+
// now create the directory folder if it doesn't exist
if (!folder.exists()) {
log.warn("'" + folder.getAbsolutePath() + "' doesn't exist. Creating directories now.");
folder.mkdirs();
}
-
+
if (!folder.isDirectory()) {
throw new APIException("should.be.directory", new Object[] { folder.getAbsolutePath() });
}
-
+
return folder;
}
-
+
/**
* Save the given xml document to the given outfile
- *
+ *
* @param doc Document to be saved
* @param outFile file pointer to the location the xml file is to be saved to
*/
@@ -1190,13 +1191,13 @@ public class OpenmrsUtil {
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-
+
DocumentType doctype = doc.getDoctype();
if (doctype != null) {
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctype.getPublicId());
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctype.getSystemId());
}
-
+
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(outStream);
transformer.transform(source, result);
@@ -1218,7 +1219,7 @@ public class OpenmrsUtil {
}
}
}
-
+
public static List<Integer> delimitedStringToIntegerList(String delimitedString, String delimiter) {
List<Integer> ret = new ArrayList<Integer>();
String[] tokens = delimitedString.split(delimiter);
@@ -1232,10 +1233,10 @@ public class OpenmrsUtil {
}
return ret;
}
-
+
/**
* Tests if the given String starts with any of the specified prefixes
- *
+ *
* @param str the string to test
* @param prefixes an array of prefixes to test against
* @return true if the String starts with any of the specified prefixes, otherwise false.
@@ -1246,10 +1247,10 @@ public class OpenmrsUtil {
return true;
}
}
-
+
return false;
}
-
+
public static boolean isConceptInList(Concept concept, List<Concept> list) {
boolean ret = false;
if (concept != null && list != null) {
@@ -1260,13 +1261,13 @@ public class OpenmrsUtil {
}
}
}
-
+
return ret;
}
-
+
public static Date fromDateHelper(Date comparisonDate, Integer withinLastDays, Integer withinLastMonths,
Integer untilDaysAgo, Integer untilMonthsAgo, Date sinceDate, Date untilDate) {
-
+
Date ret = null;
if (withinLastDays != null || withinLastMonths != null) {
Calendar gc = Calendar.getInstance();
@@ -1284,10 +1285,10 @@ public class OpenmrsUtil {
}
return ret;
}
-
+
public static Date toDateHelper(Date comparisonDate, Integer withinLastDays, Integer withinLastMonths,
Integer untilDaysAgo, Integer untilMonthsAgo, Date sinceDate, Date untilDate) {
-
+
Date ret = null;
if (untilDaysAgo != null || untilMonthsAgo != null) {
Calendar gc = Calendar.getInstance();
@@ -1305,7 +1306,7 @@ public class OpenmrsUtil {
}
return ret;
}
-
+
/**
* @param collection
* @param elements
@@ -1319,7 +1320,7 @@ public class OpenmrsUtil {
}
return false;
}
-
+
/**
* Allows easy manipulation of a Map&lt;?, Set&gt;
*/
@@ -1331,7 +1332,7 @@ public class OpenmrsUtil {
}
set.add(obj);
}
-
+
public static <K, V> void addToListMap(Map<K, List<V>> map, K key, V obj) {
List<V> list = map.get(key);
if (list == null) {
@@ -1340,11 +1341,11 @@ public class OpenmrsUtil {
}
list.add(obj);
}
-
+
/**
* Get the current user's date format Will look similar to "mm-dd-yyyy". Depends on user's
* locale.
- *
+ *
* @return a simple date format
* @should return a pattern with four y characters in it
* @should not allow the returned SimpleDateFormat to be modified
@@ -1354,12 +1355,12 @@ public class OpenmrsUtil {
if (dateFormatCache.containsKey(locale)) {
return (SimpleDateFormat) dateFormatCache.get(locale).clone();
}
-
+
// note that we are using the custom OpenmrsDateFormat class here which prevents erroneous parsing of 2-digit years
SimpleDateFormat sdf = new OpenmrsDateFormat(
(SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, locale), locale);
String pattern = sdf.toPattern();
-
+
if (!pattern.contains("yyyy")) {
// otherwise, change the pattern to be a four digit year
pattern = pattern.replaceFirst("yy", "yyyy");
@@ -1375,15 +1376,15 @@ public class OpenmrsUtil {
pattern = pattern.replaceFirst("d", "dd");
sdf.applyPattern(pattern);
}
-
+
dateFormatCache.put(locale, sdf);
-
+
return (SimpleDateFormat) sdf.clone();
}
-
+
/**
* Get the current user's time format Will look similar to "hh:mm a". Depends on user's locale.
- *
+ *
* @return a simple time format
* @should return a pattern with two h characters in it
* @should not allow the returned SimpleDateFormat to be modified
@@ -1393,25 +1394,25 @@ public class OpenmrsUtil {
if (timeFormatCache.containsKey(locale)) {
return (SimpleDateFormat) timeFormatCache.get(locale).clone();
}
-
+
SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.SHORT, locale);
String pattern = sdf.toPattern();
-
+
if (!(pattern.contains("hh") || pattern.contains("HH"))) {
// otherwise, change the pattern to be a two digit hour
pattern = pattern.replaceFirst("h", "hh").replaceFirst("H", "HH");
sdf.applyPattern(pattern);
}
-
+
timeFormatCache.put(locale, sdf);
-
+
return (SimpleDateFormat) sdf.clone();
}
-
+
/**
* Get the current user's datetime format Will look similar to "mm-dd-yyyy hh:mm a". Depends on
* user's locale.
- *
+ *
* @return a simple date format
* @should return a pattern with four y characters and two h characters in it
* @should not allow the returned SimpleDateFormat to be modified
@@ -1420,19 +1421,19 @@ public class OpenmrsUtil {
public static SimpleDateFormat getDateTimeFormat(Locale locale) {
SimpleDateFormat dateFormat;
SimpleDateFormat timeFormat;
-
+
dateFormat = getDateFormat(locale);
timeFormat = getTimeFormat(locale);
-
+
String pattern = dateFormat.toPattern() + " " + timeFormat.toPattern();
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.applyPattern(pattern);
return sdf;
}
-
+
/**
* Takes a String (e.g. a user-entered one) and parses it into an object of the specified class
- *
+ *
* @param string
* @param clazz
* @return Object of type <code>clazz</code> with the data from <code>string</code>
@@ -1522,14 +1523,14 @@ public class OpenmrsUtil {
throw new IllegalArgumentException(ex);
}
}
-
+
/**
* Loops over the collection to check to see if the given object is in that collection. This
* method <i>only</i> uses the .equals() method for comparison. This should be used in the
* patient/person objects on their collections. Their collections are SortedSets which use the
* compareTo method for equality as well. The compareTo method is currently optimized for
* sorting, not for equality. A null <code>obj</code> will return false
- *
+ *
* @param objects collection to loop over
* @param obj Object to look for in the <code>objects</code>
* @return true/false whether the given object is found
@@ -1540,20 +1541,20 @@ public class OpenmrsUtil {
if (obj == null || objects == null) {
return false;
}
-
+
for (Object o : objects) {
if (o != null && o.equals(obj)) {
return true;
}
}
-
+
return false;
}
-
+
/**
* Gets an out File object. If date is not provided, the current timestamp is used. If user is
* not provided, the user id is not put into the filename. Assumes dir is already created
- *
+ *
* @param dir directory to make the random filename in
* @param date optional Date object used for the name
* @param user optional User creating this file object
@@ -1565,41 +1566,41 @@ public class OpenmrsUtil {
do {
// format to print date in filenmae
DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd-HHmm-ssSSS");
-
+
// use current date if none provided
if (date == null) {
date = new Date();
}
-
+
StringBuilder filename = new StringBuilder();
-
+
// the start of the filename is the time so we can do some sorting
filename.append(dateFormat.format(date));
-
+
// insert the user id if they provided it
if (user != null) {
filename.append("-");
filename.append(user.getUserId());
filename.append("-");
}
-
+
// the end of the filename is a randome number between 0 and 10000
filename.append(gen.nextInt() * 10000);
filename.append(".xml");
-
+
outFile = new File(dir, filename.toString());
-
+
// set to null to avoid very minimal possiblity of an infinite loop
date = null;
-
+
} while (outFile.exists());
-
+
return outFile;
}
-
+
/**
* Creates a relatively acceptable unique string of the give size
- *
+ *
* @return unique string
*/
public static String generateUid(Integer size) {
@@ -1619,21 +1620,21 @@ public class OpenmrsUtil {
}
return sb.toString();
}
-
+
/**
* Creates a uid of length 20
- *
+ *
* @see #generateUid(Integer)
*/
public static String generateUid() {
return generateUid(20);
}
-
+
/**
* Convenience method to replace Properties.store(), which isn't UTF-8 compliant <br>
* NOTE: In Java 6, you will be able to pass the load() and store() methods a UTF-8
* Reader/Writer object as an argument, making this method unnecessary.
- *
+ *
* @param properties
* @param file
* @param comment
@@ -1658,12 +1659,12 @@ public class OpenmrsUtil {
}
}
}
-
+
/**
* Convenience method to replace Properties.store(), which isn't UTF-8 compliant NOTE: In Java
* 6, you will be able to pass the load() and store() methods a UTF-8 Reader/Writer object as an
* argument.
- *
+ *
* @param properties
* @param outStream
* @param comment (which appears in comments in properties file)
@@ -1682,16 +1683,16 @@ public class OpenmrsUtil {
catch (IOException ioex) {
log.error("IO exception encountered trying to append to properties file" + ioex);
}
-
+
}
-
+
/**
* This method is a replacement for Properties.load(InputStream) so that we can load in utf-8
* characters. Currently the load method expects the inputStream to point to a latin1 encoded
* file. <br>
* NOTE: In Java 6, you will be able to pass the load() and store() methods a UTF-8
* Reader/Writer object as an argument, making this method unnecessary.
- *
+ *
* @param props the properties object to write into
* @param input the input stream to read from
*/
@@ -1721,10 +1722,10 @@ public class OpenmrsUtil {
}
}
}
-
+
/**
* Convenience method used to load properties from the given file.
- *
+ *
* @param props the properties object to be loaded into
* @param propertyFile the properties file to read
*/
@@ -1736,10 +1737,10 @@ public class OpenmrsUtil {
log.error("Unable to find properties file" + fnfe);
}
}
-
+
/**
* Utility method for getting the translation for the passed code
- *
+ *
* @param code the message key to lookup
* @param args the replacement values for the translation string
* @return the message, or if not found, the code
@@ -1762,7 +1763,7 @@ public class OpenmrsUtil {
}
return code;
}
-
+
/**
* Utility to check the validity of a password for a certain {@link User}. Passwords must be
* non-null. Their required strength is configured via global properties:
@@ -1804,7 +1805,7 @@ public class OpenmrsUtil {
* <th>null</th>
* </tr>
* </table>
- *
+ *
* @param username user name of the user with password to validated
* @param password string that will be validated
* @param systemId system id of the user with password to be validated
@@ -1835,7 +1836,7 @@ public class OpenmrsUtil {
* @should still work without an open session
*/
public static void validatePassword(String username, String password, String systemId) throws PasswordException {
-
+
// default values for all of the global properties
String userGp = "true";
String lengthGp = "8";
@@ -1844,7 +1845,7 @@ public class OpenmrsUtil {
String nonDigitGp = "true";
String regexGp = null;
AdministrationService svc = null;
-
+
try {
svc = Context.getAdministrationService();
}
@@ -1853,7 +1854,7 @@ public class OpenmrsUtil {
// defaults
log.debug("Unable to get global properties", apiEx);
}
-
+
if (svc != null && Context.isSessionOpen()) {
// (the session won't be open here to allow for the unit test to
// fake not having the admin service available)
@@ -1864,15 +1865,15 @@ public class OpenmrsUtil {
nonDigitGp = svc.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_REQUIRES_NON_DIGIT, nonDigitGp);
regexGp = svc.getGlobalProperty(OpenmrsConstants.GP_PASSWORD_CUSTOM_REGEX, regexGp);
}
-
+
if (password == null) {
throw new WeakPasswordException();
}
-
+
if ("true".equals(userGp) && (password.equals(username) || password.equals(systemId))) {
throw new WeakPasswordException();
}
-
+
if (StringUtils.isNotEmpty(lengthGp)) {
try {
int minLength = Integer.parseInt(lengthGp);
@@ -1886,19 +1887,19 @@ public class OpenmrsUtil {
+ "> must be an Integer");
}
}
-
+
if ("true".equals(caseGp) && !containsUpperAndLowerCase(password)) {
throw new InvalidCharactersPasswordException(getMessage("error.password.requireMixedCase"));
}
-
+
if ("true".equals(digitGp) && !containsDigit(password)) {
throw new InvalidCharactersPasswordException(getMessage("error.password.requireNumber"));
}
-
+
if ("true".equals(nonDigitGp) && containsOnlyDigits(password)) {
throw new InvalidCharactersPasswordException(getMessage("error.password.requireLetter"));
}
-
+
if (StringUtils.isNotEmpty(regexGp)) {
try {
Pattern pattern = Pattern.compile(regexGp);
@@ -1913,7 +1914,7 @@ public class OpenmrsUtil {
}
}
}
-
+
/**
* @param test the string to test
* @return true if the passed string contains both upper and lower case characters
@@ -1929,7 +1930,7 @@ public class OpenmrsUtil {
}
return false;
}
-
+
/**
* @param test the string to test
* @return true if the passed string contains only numeric characters
@@ -1946,7 +1947,7 @@ public class OpenmrsUtil {
}
return StringUtils.isNotEmpty(test);
}
-
+
/**
* @param test the string to test
* @return true if the passed string contains any numeric characters
@@ -1963,10 +1964,10 @@ public class OpenmrsUtil {
}
return false;
}
-
+
/**
* A null-safe and exception safe way to close an inputstream or an outputstream
- *
+ *
* @param closableStream an InputStream or OutputStream to close
*/
public static void closeStream(Closeable closableStream) {
@@ -1979,12 +1980,12 @@ public class OpenmrsUtil {
}
}
}
-
+
/**
* Convert a stack trace into a shortened version for easier viewing and data storage, excluding
* those lines we are least concerned with; should average about 60% reduction in stack trace
* length
- *
+ *
* @param stackTrace original stack trace from an error
* @return shortened stack trace
* @should return null if stackTrace is null
@@ -1995,11 +1996,11 @@ public class OpenmrsUtil {
if (stackTrace == null) {
return null;
}
-
+
List<String> results = new ArrayList<String>();
final Pattern exclude = Pattern.compile("(org.springframework.|java.lang.reflect.Method.invoke|sun.reflect.)");
boolean found = false;
-
+
for (String line : stackTrace.split("\n")) {
Matcher m = exclude.matcher(line);
if (m.find()) {
@@ -2012,10 +2013,10 @@ public class OpenmrsUtil {
results.add(line);
}
}
-
+
return StringUtils.join(results, "\n");
}
-
+
/**
* <pre>
* Finds and loads the runtime properties file for a specific OpenMRS application.
@@ -2024,7 +2025,7 @@ public class OpenmrsUtil {
* 2) an environment variable called "{APPLICATIONNAME}_RUNTIME_PROPERTIES_FILE"
* 3) {openmrs_app_dir}/{applicationName}_runtime.properties // openmrs_app_dir is typically {user_home}/.OpenMRS
* </pre>
- *
+ *
* @see #getApplicationDataDirectory()
* @param applicationName (defaults to "openmrs") the name of the running OpenMRS application,
* e.g. if you have deployed OpenMRS as a web application you would give the deployed
@@ -2047,13 +2048,13 @@ public class OpenmrsUtil {
catch (FileNotFoundException e) {
log.warn("Unable to find a runtime properties file at " + new File(pathName).getAbsolutePath());
}
-
+
try {
if (propertyStream == null) {
throw new IOException("Could not find a runtime properties file named " + pathName
+ " in the OpenMRS application data directory, or the current directory");
}
-
+
Properties props = new Properties();
OpenmrsUtil.loadProperties(props, propertyStream);
propertyStream.close();
@@ -2067,20 +2068,20 @@ public class OpenmrsUtil {
return null;
}
}
-
+
/**
* Checks whether the system is running in test mode
- *
+ *
* @return boolean
*/
-
+
public static boolean isTestMode() {
return "true".equalsIgnoreCase(System.getProperty("FUNCTIONAL_TEST_MODE"));
}
-
+
/**
* Gets the full path and name of the runtime properties file.
- *
+ *
* @param applicationName (defaults to "openmrs") the name of the running OpenMRS application,
* e.g. if you have deployed OpenMRS as a web application you would give the deployed
* context path here
@@ -2091,10 +2092,10 @@ public class OpenmrsUtil {
if (applicationName == null) {
applicationName = "openmrs";
}
-
+
String defaultFileName = applicationName + "-runtime.properties";
String fileNameInTestMode = getRuntimePropertiesFileNameInTestMode();
-
+
// first look in the current directory (that java was started from)
String pathName = fileNameInTestMode != null ? fileNameInTestMode : defaultFileName;
log.debug("Attempting to look for properties file in current directory: " + pathName);
@@ -2103,7 +2104,7 @@ public class OpenmrsUtil {
} else {
log.warn("Unable to find a runtime properties file at " + new File(pathName).getAbsolutePath());
}
-
+
// next look from environment variable
String envVarName = applicationName.toUpperCase() + "_RUNTIME_PROPERTIES_FILE";
String envFileName = System.getenv(envVarName);
@@ -2121,7 +2122,7 @@ public class OpenmrsUtil {
log.debug("Available environment variables are named: " + System.getenv().keySet());
}
}
-
+
// next look in the OpenMRS application data directory
File file = new File(getApplicationDataDirectory(), pathName);
pathName = file.getAbsolutePath();
@@ -2131,10 +2132,10 @@ public class OpenmrsUtil {
} else {
log.warn("Unable to find properties file: " + pathName);
}
-
+
return null;
}
-
+
public static String getRuntimePropertiesFileNameInTestMode() {
String filename = null;
if (isTestMode()) {
@@ -2143,19 +2144,19 @@ public class OpenmrsUtil {
}
return filename;
}
-
+
/**
* Gets OpenMRS version name under test mode.
- *
+ *
* @return String openmrs version number
*/
public static String getOpenMRSVersionInTestMode() {
return System.getProperty("OPENMRS_VERSION", "openmrs");
}
-
+
/**
* Performs a case insensitive Comparison of two strings taking care of null values
- *
+ *
* @param s1 the string to compare
* @param s2 the string to compare
* @return true if strings are equal (ignoring case)
@@ -2169,14 +2170,14 @@ public class OpenmrsUtil {
} else if (s2 == null) {
return false;
}
-
+
return s1.equalsIgnoreCase(s2);
}
-
+
/**
* This method converts the given Long value to an Integer. If the Long value will not fit in an
* Integer an exception is thrown
- *
+ *
* @param longValue the value to convert
* @return the long value in integer form.
* @throws IllegalArgumentException if the long value does not fit into an integer
@@ -2187,11 +2188,11 @@ public class OpenmrsUtil {
}
return longValue.intValue();
}
-
+
/**
* Checks if the passed in date's day of the year is the one that comes immediately before that
* of the current date
- *
+ *
* @param date the date to check
* @since 1.9
* @return true if the date comes immediately before the current date otherwise false
@@ -2200,13 +2201,13 @@ public class OpenmrsUtil {
if (date == null) {
return false;
}
-
+
Calendar c1 = Calendar.getInstance();
c1.add(Calendar.DAY_OF_YEAR, -1); // yesterday
-
+
Calendar c2 = Calendar.getInstance();
c2.setTime(date);
-
+
return (c1.get(Calendar.ERA) == c2.get(Calendar.ERA) && c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) && c1
.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR));
}
diff --git a/api/src/main/java/org/openmrs/util/Security.java b/api/src/main/java/org/openmrs/util/Security.java
index 828e107..f41b41d 100644
--- a/api/src/main/java/org/openmrs/util/Security.java
+++ b/api/src/main/java/org/openmrs/util/Security.java
@@ -33,17 +33,17 @@ import org.springframework.util.StringUtils;
* OpenMRS's security class deals with the hashing of passwords.
*/
public class Security {
-
+
/**
- * Defined encoding to avoid using default platform charset
+ * Defined encoding to avoid using default platform charset
*/
private static final String encoding = "UTF-8";
-
+
/**
* encryption settings
*/
public static Log log = LogFactory.getLog(Security.class);
-
+
/**
* Compare the given hash and the given string-to-hash to see if they are equal. The
* string-to-hash is usually of the form password + salt. <br>
@@ -63,13 +63,23 @@ public class Security {
if (hashedPassword == null || passwordToHash == null) {
throw new APIException("password.cannot.be.null", (Object[]) null);
}
-
+
return hashedPassword.equals(encodeString(passwordToHash))
|| hashedPassword.equals(encodeStringSHA1(passwordToHash))
|| hashedPassword.equals(incorrectlyEncodeString(passwordToHash));
}
/**
+ * This method is called when password cannot be encoded
+ * @param algo algorithm used for encoding
+ * @return the error message string with algorithm type used
+ */
+ public static String passwordEncodeFail(String algo) {
+ String errorMessage = "Can't encode password because the given algorithm: " + algo + "was not found! (fail)";
+ return errorMessage;
+ }
+
+ /**
* This method will hash <code>strToEncode</code> using the preferred algorithm. Currently,
* OpenMRS's preferred algorithm is hard coded to be SHA-512.
*
@@ -87,7 +97,7 @@ public class Security {
}
catch (NoSuchAlgorithmException e) {
// Yikes! Can't encode password...what to do?
- log.error("Can't encode password because the given algorithm: " + algorithm + "was not found! (fail)", e);
+ log.error(passwordEncodeFail(algorithm), e);
throw new APIException("system.cannot.find.password.encryption.algorithm", null, e);
}
catch (UnsupportedEncodingException e) {
@@ -95,7 +105,7 @@ public class Security {
}
return hexString(md.digest(input));
}
-
+
/**
* This method will hash <code>strToEncode</code> using the old SHA-1 algorithm.
*
@@ -112,7 +122,7 @@ public class Security {
}
catch (NoSuchAlgorithmException e) {
// Yikes! Can't encode password...what to do?
- log.error("Can't encode password because the given algorithm: " + algorithm + "was not found! (fail)", e);
+ log.error(passwordEncodeFail(algorithm), e);
throw new APIException("system.cannot.find.encryption.algorithm", null, e);
}
catch (UnsupportedEncodingException e) {
@@ -120,7 +130,7 @@ public class Security {
}
return hexString(md.digest(input));
}
-
+
/**
* Convenience method to convert a byte array to a string
*
@@ -139,10 +149,10 @@ public class Security {
buf.append(hexChars[high]);
buf.append(hexChars[low]);
}
-
+
return buf.toString();
}
-
+
/**
* This method will hash <code>strToEncode</code> using SHA-1 and the incorrect hashing method
* that sometimes dropped out leading zeros.
@@ -160,7 +170,7 @@ public class Security {
}
catch (NoSuchAlgorithmException e) {
// Yikes! Can't encode password...what to do?
- log.error("Can't encode password because the given algorithm: " + algorithm + "was not found! (fail)", e);
+ log.error(passwordEncodeFail(algorithm), e);
throw new APIException("system.cannot.find.encryption.algorithm", null, e);
}
catch (UnsupportedEncodingException e) {
@@ -168,7 +178,7 @@ public class Security {
}
return incorrectHexString(md.digest(input));
}
-
+
/**
* This method used to be the simple hexString method, however, as pointed out in ticket
* http://dev.openmrs.org/ticket/1178, it was not working correctly. Authenticated still needs
@@ -189,7 +199,7 @@ public class Security {
}
return new String(s);
}
-
+
/**
* This method will generate a random string
*
@@ -199,7 +209,7 @@ public class Security {
Random rng = new Random();
return encodeString(Long.toString(System.currentTimeMillis()) + Long.toString(rng.nextLong()));
}
-
+
/**
* encrypt text to a string with specific initVector and secretKey; rarely used except in
* testing and where specifically necessary
@@ -216,7 +226,7 @@ public class Security {
IvParameterSpec initVectorSpec = new IvParameterSpec(initVector);
SecretKeySpec secret = new SecretKeySpec(secretKey, OpenmrsConstants.ENCRYPTION_KEY_SPEC);
byte[] encrypted;
-
+
try {
Cipher cipher = Cipher.getInstance(OpenmrsConstants.ENCRYPTION_CIPHER_CONFIGURATION);
cipher.init(Cipher.ENCRYPT_MODE, secret, initVectorSpec);
@@ -228,10 +238,10 @@ public class Security {
catch (UnsupportedEncodingException e) {
throw new APIException("system.cannot.find.encoding", new Object[] { encoding }, e);
}
-
+
return Base64.encode(encrypted);
}
-
+
/**
* encrypt text using stored initVector and securityKey
*
@@ -243,7 +253,7 @@ public class Security {
public static String encrypt(String text) {
return Security.encrypt(text, Security.getSavedInitVector(), Security.getSavedSecretKey());
}
-
+
/**
* decrypt text to a string with specific initVector and secretKey; rarely used except in
* testing and where specifically necessary
@@ -260,7 +270,7 @@ public class Security {
IvParameterSpec initVectorSpec = new IvParameterSpec(initVector);
SecretKeySpec secret = new SecretKeySpec(secretKey, OpenmrsConstants.ENCRYPTION_KEY_SPEC);
String decrypted = null;
-
+
try {
Cipher cipher = Cipher.getInstance(OpenmrsConstants.ENCRYPTION_CIPHER_CONFIGURATION);
cipher.init(Cipher.DECRYPT_MODE, secret, initVectorSpec);
@@ -273,10 +283,10 @@ public class Security {
catch (UnsupportedEncodingException e) {
throw new APIException("system.cannot.find.encoding", new Object[] { encoding }, e);
}
-
+
return decrypted;
}
-
+
/**
* decrypt text using stored initVector and securityKey
*
@@ -288,7 +298,7 @@ public class Security {
public static String decrypt(String text) {
return Security.decrypt(text, Security.getSavedInitVector(), Security.getSavedSecretKey());
}
-
+
/**
* retrieve the stored init vector from runtime properties
*
@@ -298,14 +308,14 @@ public class Security {
public static byte[] getSavedInitVector() {
String initVectorText = Context.getRuntimeProperties().getProperty(
OpenmrsConstants.ENCRYPTION_VECTOR_RUNTIME_PROPERTY, OpenmrsConstants.ENCRYPTION_VECTOR_DEFAULT);
-
+
if (StringUtils.hasText(initVectorText)) {
return Base64.decode(initVectorText);
}
-
+
throw new APIException("no.encryption.initialization.vector.found", (Object[]) null);
}
-
+
/**
* generate a new cipher initialization vector; should only be called once in order to not
* invalidate all encrypted data
@@ -317,15 +327,15 @@ public class Security {
// initialize the init vector with 16 random bytes
byte[] initVector = new byte[16];
new SecureRandom().nextBytes(initVector);
-
+
// TODO get the following (better) method working
// Cipher cipher = Cipher.getInstance(CIPHER_CONFIGURATION);
// AlgorithmParameters params = cipher.getParameters();
// byte[] initVector = params.getParameterSpec(IvParameterSpec.class).getIV();
-
+
return initVector;
}
-
+
/**
* retrieve the secret key from runtime properties
*
@@ -335,14 +345,14 @@ public class Security {
public static byte[] getSavedSecretKey() {
String keyText = Context.getRuntimeProperties().getProperty(OpenmrsConstants.ENCRYPTION_KEY_RUNTIME_PROPERTY,
OpenmrsConstants.ENCRYPTION_KEY_DEFAULT);
-
+
if (StringUtils.hasText(keyText)) {
return Base64.decode(keyText);
}
-
+
throw new APIException("no.encryption.secret.key.found", (Object[]) null);
}
-
+
/**
* generate a new secret key; should only be called once in order to not invalidate all
* encrypted data
@@ -360,11 +370,11 @@ public class Security {
throw new APIException("could.not.generate.cipher.key", null, e);
}
kgen.init(128); // 192 and 256 bits may not be available
-
+
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
-
+
return skey.getEncoded();
}
-
+
}
diff --git a/api/src/main/java/org/openmrs/validator/ObsValidator.java b/api/src/main/java/org/openmrs/validator/ObsValidator.java
index f94a671..3793980 100644
--- a/api/src/main/java/org/openmrs/validator/ObsValidator.java
+++ b/api/src/main/java/org/openmrs/validator/ObsValidator.java
@@ -30,14 +30,15 @@ import org.springframework.validation.Validator;
* <li>checks for no recursion in the obs grouping.
* <li>Makes sure the obs has at least one value (if not an obs grouping)</li>
* </ul>
- *
+ *
* @see org.openmrs.Obs
*/
@Handler(supports = { Obs.class }, order = 50)
public class ObsValidator implements Validator {
-
+
public final static int VALUE_TEXT_MAX_LENGTH = 1000;
-
+ public final static String GROUP_MEMBERS = "groupMembers";
+
/**
* @see org.springframework.validation.Validator#supports(java.lang.Class)
* @should support Obs class
@@ -46,7 +47,7 @@ public class ObsValidator implements Validator {
public boolean supports(Class c) {
return Obs.class.isAssignableFrom(c);
}
-
+
/**
* @see org.springframework.validation.Validator#validate(java.lang.Object,
* org.springframework.validation.Errors)
@@ -81,7 +82,7 @@ public class ObsValidator implements Validator {
ValidateUtil.validateFieldLengths(errors, obj.getClass(), "accessionNumber", "valueModifier", "valueComplex",
"comment", "voidReason");
}
-
+
/**
* Checks whether obs has all required values, and also checks to make sure that no obs group
* contains any of its ancestors
@@ -99,41 +100,41 @@ public class ObsValidator implements Validator {
if (obs.getObsDatetime() == null) {
errors.rejectValue("obsDatetime", "error.null");
}
-
+
// if this is an obs group (i.e., parent) make sure that it has no values (other than valueGroupId) set
if (obs.hasGroupMembers()) {
if (obs.getValueCoded() != null) {
errors.rejectValue("valueCoded", "error.not.null");
}
-
+
if (obs.getValueDrug() != null) {
errors.rejectValue("valueDrug", "error.not.null");
}
-
+
if (obs.getValueDatetime() != null) {
errors.rejectValue("valueDatetime", "error.not.null");
}
-
+
if (obs.getValueNumeric() != null) {
errors.rejectValue("valueNumeric", "error.not.null");
}
-
+
if (obs.getValueModifier() != null) {
errors.rejectValue("valueModifier", "error.not.null");
}
-
+
if (obs.getValueText() != null) {
errors.rejectValue("valueText", "error.not.null");
}
-
+
if (obs.getValueBoolean() != null) {
errors.rejectValue("valueBoolean", "error.not.null");
}
-
+
if (obs.getValueComplex() != null) {
errors.rejectValue("valueComplex", "error.not.null");
}
-
+
}
// if this is NOT an obs group, make sure that it has at least one value set (not counting obsGroupId)
else if (obs.getValueBoolean() == null && obs.getValueCoded() == null && obs.getValueCodedName() == null
@@ -142,7 +143,7 @@ public class ObsValidator implements Validator {
&& obs.getComplexData() == null) {
errors.reject("error.noValue");
}
-
+
// make sure there is a concept associated with the obs
Concept c = obs.getConcept();
if (c == null) {
@@ -156,82 +157,82 @@ public class ObsValidator implements Validator {
if (atRootNode) {
errors.rejectValue("valueBoolean", "error.null");
} else {
- errors.rejectValue("groupMembers", "Obs.error.inGroupMember");
+ errors.rejectValue(GROUP_MEMBERS, "Obs.error.inGroupMember");
}
} else if (dt.isCoded() && obs.getValueCoded() == null) {
if (atRootNode) {
errors.rejectValue("valueCoded", "error.null");
} else {
- errors.rejectValue("groupMembers", "Obs.error.inGroupMember");
+ errors.rejectValue(GROUP_MEMBERS, "Obs.error.inGroupMember");
}
} else if ((dt.isDateTime() || dt.isDate() || dt.isTime()) && obs.getValueDatetime() == null) {
if (atRootNode) {
errors.rejectValue("valueDatetime", "error.null");
} else {
- errors.rejectValue("groupMembers", "Obs.error.inGroupMember");
+ errors.rejectValue(GROUP_MEMBERS, "Obs.error.inGroupMember");
}
} else if (dt.isNumeric() && obs.getValueNumeric() == null) {
if (atRootNode) {
errors.rejectValue("valueNumeric", "error.null");
} else {
- errors.rejectValue("groupMembers", "Obs.error.inGroupMember");
+ errors.rejectValue(GROUP_MEMBERS, "Obs.error.inGroupMember");
}
} else if (dt.isNumeric()) {
ConceptNumeric cn = Context.getConceptService().getConceptNumeric(c.getConceptId());
- // If the concept numeric is not precise, the value cannot be a float, so raise an error
+ // If the concept numeric is not precise, the value cannot be a float, so raise an error
if (!cn.isAllowDecimal() && Math.ceil(obs.getValueNumeric()) != obs.getValueNumeric()) {
if (atRootNode) {
errors.rejectValue("valueNumeric", "error.precision");
} else {
- errors.rejectValue("groupMembers", "Obs.error.inGroupMember");
+ errors.rejectValue(GROUP_MEMBERS, "Obs.error.inGroupMember");
}
}
- // If the number is higher than the absolute range, raise an error
+ // If the number is higher than the absolute range, raise an error
if (cn.getHiAbsolute() != null && cn.getHiAbsolute() < obs.getValueNumeric()) {
if (atRootNode) {
errors.rejectValue("valueNumeric", "error.outOfRange.high");
} else {
- errors.rejectValue("groupMembers", "Obs.error.inGroupMember");
+ errors.rejectValue(GROUP_MEMBERS, "Obs.error.inGroupMember");
}
}
- // If the number is lower than the absolute range, raise an error as well
+ // If the number is lower than the absolute range, raise an error as well
if (cn.getLowAbsolute() != null && cn.getLowAbsolute() > obs.getValueNumeric()) {
if (atRootNode) {
errors.rejectValue("valueNumeric", "error.outOfRange.low");
} else {
- errors.rejectValue("groupMembers", "Obs.error.inGroupMember");
+ errors.rejectValue(GROUP_MEMBERS, "Obs.error.inGroupMember");
}
}
} else if (dt.isText() && obs.getValueText() == null) {
if (atRootNode) {
errors.rejectValue("valueText", "error.null");
} else {
- errors.rejectValue("groupMembers", "Obs.error.inGroupMember");
+ errors.rejectValue(GROUP_MEMBERS, "Obs.error.inGroupMember");
}
}
-
+
//If valueText is longer than the maxlength, raise an error as well.
if (dt.isText() && obs.getValueText() != null && obs.getValueText().length() > VALUE_TEXT_MAX_LENGTH) {
if (atRootNode) {
errors.rejectValue("valueText", "error.exceededMaxLengthOfField");
} else {
- errors.rejectValue("groupMembers", "Obs.error.inGroupMember");
+ errors.rejectValue(GROUP_MEMBERS, "Obs.error.inGroupMember");
}
}
} else { // dt is null
errors.rejectValue("concept", "must have a datatype");
}
}
-
+
// If an obs fails validation, don't bother checking its children
if (errors.hasErrors()) {
return;
}
-
+
if (ancestors.contains(obs)) {
- errors.rejectValue("groupMembers", "Obs.error.groupContainsItself");
+ errors.rejectValue(GROUP_MEMBERS, "Obs.error.groupContainsItself");
}
-
+
if (obs.isObsGrouping()) {
ancestors.add(obs);
for (Obs child : obs.getGroupMembers()) {
@@ -239,7 +240,7 @@ public class ObsValidator implements Validator {
}
ancestors.remove(ancestors.size() - 1);
}
-
+
if (obs.getValueCoded() != null && obs.getValueDrug() != null && obs.getValueDrug().getConcept() != null) {
Concept trueConcept = Context.getConceptService().getTrueConcept();
Concept falseConcept = Context.getConceptService().getFalseConcept();
@@ -250,5 +251,5 @@ public class ObsValidator implements Validator {
}
}
}
-
+
}
diff --git a/web/src/main/java/org/openmrs/module/web/WebModuleUtil.java b/web/src/main/java/org/openmrs/module/web/WebModuleUtil.java
index bf5de68..04f34b3 100644
--- a/web/src/main/java/org/openmrs/module/web/WebModuleUtil.java
+++ b/web/src/main/java/org/openmrs/module/web/WebModuleUtil.java
@@ -75,25 +75,25 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class WebModuleUtil {
-
+
private static Log log = LogFactory.getLog(WebModuleUtil.class);
-
+
private static DispatcherServlet dispatcherServlet = null;
-
+
private static StaticDispatcherServlet staticDispatcherServlet = null;
-
+
// caches all of the modules' mapped servlets
private static Map<String, HttpServlet> moduleServlets = Collections.synchronizedMap(new HashMap<String, HttpServlet>());
-
+
// caches all of the module loaded filters and filter-mappings
private static Map<Module, Collection<Filter>> moduleFilters = Collections
.synchronizedMap(new HashMap<Module, Collection<Filter>>());
-
+
private static Map<String, Filter> moduleFiltersByName = Collections.synchronizedMap(new HashMap<String, Filter>());
-
+
private static List<ModuleFilterMapping> moduleFilterMappings = Collections
.synchronizedList(new Vector<ModuleFilterMapping>());
-
+
/**
* Performs the webapp specific startup needs for modules Normal startup is done in
* {@link ModuleFactory#startModule(Module)} If delayContextRefresh is true, the spring context
@@ -111,30 +111,30 @@ public class WebModuleUtil {
* @return boolean whether or not the spring context need to be refreshed
*/
public static boolean startModule(Module mod, ServletContext servletContext, boolean delayContextRefresh) {
-
+
if (log.isDebugEnabled()) {
log.debug("trying to start module " + mod);
}
-
+
// only try and start this module if the api started it without a
// problem.
if (ModuleFactory.isModuleStarted(mod) && !mod.hasStartupError()) {
-
+
String realPath = getRealPath(servletContext);
-
+
if (realPath == null) {
realPath = System.getProperty("user.dir");
}
-
+
File webInf = new File(realPath + "/WEB-INF".replace("/", File.separator));
if (!webInf.exists()) {
webInf.mkdir();
}
-
+
// flag to tell whether we added any xml/dwr/etc changes that necessitate a refresh
// of the web application context
boolean moduleNeedsContextRefresh = false;
-
+
// copy the html files into the webapp (from /web/module/ in the module)
// also looks for a spring context file. If found, schedules spring to be restarted
JarFile jarFile = null;
@@ -144,7 +144,7 @@ public class WebModuleUtil {
File modFile = mod.getFile();
jarFile = new JarFile(modFile);
Enumeration<JarEntry> entries = jarFile.entries();
-
+
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
@@ -152,9 +152,9 @@ public class WebModuleUtil {
if (name.startsWith("web/module/")) {
// trim out the starting path of "web/module/"
String filepath = name.substring(11);
-
+
StringBuffer absPath = new StringBuffer(realPath + "/WEB-INF");
-
+
// If this is within the tag file directory, copy it into /WEB-INF/tags/module/moduleId/...
if (filepath.startsWith("tags/")) {
filepath = filepath.substring(5);
@@ -164,14 +164,14 @@ public class WebModuleUtil {
else {
absPath.append("/view/module/");
}
-
+
// if a module id has a . in it, we should treat that as a /, i.e. files in the module
// ui.springmvc should go in folder names like .../ui/springmvc/...
absPath.append(mod.getModuleIdAsPath() + "/" + filepath);
if (log.isDebugEnabled()) {
log.debug("Moving file from: " + name + " to " + absPath);
}
-
+
// get the output file
File outFile = new File(absPath.toString().replace("/", File.separator));
if (entry.isDirectory()) {
@@ -184,16 +184,16 @@ public class WebModuleUtil {
if (!parentDir.exists()) {
parentDir.mkdirs();
}
-
+
//if (outFile.getName().endsWith(".jsp") == false)
// outFile = new File(absPath.replace("/", File.separator) + MODULE_NON_JSP_EXTENSION);
-
+
// copy the contents over to the webapp for non directories
outStream = new FileOutputStream(outFile, false);
inStream = jarFile.getInputStream(entry);
OpenmrsUtil.copyFile(inStream, outStream);
}
- } else if (name.equals("moduleApplicationContext.xml") || name.equals("webModuleApplicationContext.xml")) {
+ } else if ("moduleApplicationContext.xml".equals(name) || "webModuleApplicationContext.xml".equals(name)) {
moduleNeedsContextRefresh = true;
} else if (name.equals(mod.getModuleId() + "Context.xml")) {
String msg = "DEPRECATED: '" + name
@@ -231,43 +231,43 @@ public class WebModuleUtil {
}
}
}
-
+
// find and add the dwr code to the dwr-modules.xml file (if defined)
InputStream inputStream = null;
try {
Document config = mod.getConfig();
Element root = config.getDocumentElement();
if (root.getElementsByTagName("dwr").getLength() > 0) {
-
+
// get the dwr-module.xml file that we're appending our code to
File f = new File(realPath + "/WEB-INF/dwr-modules.xml".replace("/", File.separator));
-
+
// testing if file exists
if (!f.exists()) {
// if it does not -> needs to be created
createDwrModulesXml(realPath);
}
-
+
inputStream = new FileInputStream(f);
Document dwrmodulexml = getDWRModuleXML(inputStream, realPath);
Element outputRoot = dwrmodulexml.getDocumentElement();
-
+
// loop over all of the children of the "dwr" tag
Node node = root.getElementsByTagName("dwr").item(0);
Node current = node.getFirstChild();
-
+
while (current != null) {
if ("allow".equals(current.getNodeName()) || "signatures".equals(current.getNodeName())
|| "init".equals(current.getNodeName())) {
((Element) current).setAttribute("moduleId", mod.getModuleId());
outputRoot.appendChild(dwrmodulexml.importNode(current, true));
}
-
+
current = current.getNextSibling();
}
-
+
moduleNeedsContextRefresh = true;
-
+
// save the dwr-modules.xml file.
OpenmrsUtil.saveDocument(dwrmodulexml, f);
}
@@ -285,30 +285,30 @@ public class WebModuleUtil {
}
}
}
-
+
// mark to delete the entire module web directory on exit
// this will usually only be used when an improper shutdown has occurred.
String folderPath = realPath + "/WEB-INF/view/module/" + mod.getModuleIdAsPath();
File outFile = new File(folderPath.replace("/", File.separator));
outFile.deleteOnExit();
-
+
// additional checks on module needing a context refresh
if (moduleNeedsContextRefresh == false && mod.getAdvicePoints() != null && mod.getAdvicePoints().size() > 0) {
-
+
// AOP advice points are only loaded during the context refresh now.
// if the context hasn't been marked to be refreshed yet, mark it
// now if this module defines some advice
moduleNeedsContextRefresh = true;
-
+
}
-
+
// refresh the spring web context to get the just-created xml
// files into it (if we copied an xml file)
if (moduleNeedsContextRefresh && delayContextRefresh == false) {
if (log.isDebugEnabled()) {
log.debug("Refreshing context for module" + mod);
}
-
+
try {
refreshWAC(servletContext, false, mod);
log.debug("Done Refreshing WAC");
@@ -316,11 +316,11 @@ public class WebModuleUtil {
catch (Exception e) {
String msg = "Unable to refresh the WebApplicationContext";
mod.setStartupErrorMessage(msg, e);
-
+
if (log.isWarnEnabled()) {
log.warn(msg + " for module: " + mod.getModuleId(), e);
}
-
+
try {
stopModule(mod, servletContext, true);
ModuleFactory.stopModule(mod, true, true); //remove jar from classloader play
@@ -331,47 +331,47 @@ public class WebModuleUtil {
log.warn("Error while stopping a module that had an error on refreshWAC", e2);
}
}
-
+
// try starting the application context again
refreshWAC(servletContext, false, mod);
-
+
notifySuperUsersAboutModuleFailure(mod);
}
-
+
}
-
+
if (!delayContextRefresh && ModuleFactory.isModuleStarted(mod)) {
// only loading the servlets/filters if spring is refreshed because one
// might depend on files being available in spring
// if the caller wanted to delay the refresh then they are responsible for
// calling these two methods on the module
-
+
// find and cache the module's servlets
//(only if the module started successfully previously)
log.debug("Loading servlets and filters for module: " + mod);
loadServlets(mod, servletContext);
loadFilters(mod, servletContext);
}
-
+
// return true if the module needs a context refresh and we didn't do it here
return (moduleNeedsContextRefresh && delayContextRefresh == true);
-
+
}
-
+
// we aren't processing this module, so a context refresh is not necessary
return false;
}
-
+
/** Stops all tasks started by given module
* @param mod
*/
private static void stopTasks(Module mod) {
-
+
SchedulerService schedulerService = Context.getSchedulerService();
-
+
String modulePackageName = mod.getPackageName();
for (TaskDefinition task : schedulerService.getRegisteredTasks()) {
-
+
String taskClass = task.getTaskClass();
if (isModulePackageNameInTaskClass(modulePackageName, taskClass)) {
try {
@@ -383,7 +383,7 @@ public class WebModuleUtil {
}
}
}
-
+
/**
* Checks if module package name is in task class name
* @param modulePackageName the package name of module
@@ -398,7 +398,7 @@ public class WebModuleUtil {
return modulePackageName.length() <= taskClass.length()
&& taskClass.matches(Pattern.quote(modulePackageName) + "(\\..*)+");
}
-
+
/**
* Send an Alert to all super users that the given module did not start successfully.
*
@@ -409,7 +409,7 @@ public class WebModuleUtil {
// Add the privileges necessary for notifySuperUsers
Context.addProxyPrivilege(PrivilegeConstants.MANAGE_ALERTS);
Context.addProxyPrivilege(PrivilegeConstants.GET_USERS);
-
+
// Send an alert to all administrators
Context.getAlertService().notifySuperUsers("Module.startupError.notification.message", null, mod.getName());
}
@@ -419,7 +419,7 @@ public class WebModuleUtil {
Context.removeProxyPrivilege(PrivilegeConstants.MANAGE_ALERTS);
}
}
-
+
/**
* This method will find and cache this module's servlets (so that it doesn't have to look them
* up every time)
@@ -430,7 +430,7 @@ public class WebModuleUtil {
public static void loadServlets(Module mod, ServletContext servletContext) {
Element rootNode = mod.getConfig().getDocumentElement();
NodeList servletTags = rootNode.getElementsByTagName("servlet");
-
+
for (int i = 0; i < servletTags.getLength(); i++) {
Node node = servletTags.item(i);
NodeList childNodes = node.getChildNodes();
@@ -450,7 +450,7 @@ public class WebModuleUtil {
+ "' and '" + className + "' for module " + mod.getName());
continue;
}
-
+
HttpServlet httpServlet = null;
try {
httpServlet = (HttpServlet) ModuleFactory.getModuleClassLoader(mod).loadClass(className).newInstance();
@@ -467,7 +467,7 @@ public class WebModuleUtil {
log.warn("Class cannot be instantiated for servlet " + name + " for module " + mod.getName(), e);
continue;
}
-
+
try {
log.debug("Initializing " + name + " servlet. - " + httpServlet + ".");
ServletConfig servletConfig = new ModuleServlet.SimpleServletConfig(name, servletContext);
@@ -477,7 +477,7 @@ public class WebModuleUtil {
log.warn("Unable to initialize servlet: ", e);
throw new ModuleException("Unable to initialize servlet: " + httpServlet, mod.getModuleId(), e);
}
-
+
// don't allow modules to overwrite servlets of other modules.
HttpServlet otherServletUsingSameName = moduleServlets.get(name);
if (otherServletUsingSameName != null) {
@@ -490,12 +490,12 @@ public class WebModuleUtil {
+ ") will not work or the other one will not. Please consult the developers of these two"
+ " modules to sort this out.");
}
-
+
log.debug("Caching the " + name + " servlet.");
moduleServlets.put(name, httpServlet);
}
}
-
+
/**
* Remove all of the servlets defined for this module
*
@@ -504,7 +504,7 @@ public class WebModuleUtil {
public static void unloadServlets(Module mod) {
Element rootNode = mod.getConfig().getDocumentElement();
NodeList servletTags = rootNode.getElementsByTagName("servlet");
-
+
for (int i = 0; i < servletTags.getLength(); i++) {
Node node = servletTags.item(i);
NodeList childNodes = node.getChildNodes();
@@ -522,7 +522,7 @@ public class WebModuleUtil {
}
}
}
-
+
/**
* This method will initialize and store this module's filters
*
@@ -530,7 +530,7 @@ public class WebModuleUtil {
* @param servletContext - The servletContext within which this method is called
*/
public static void loadFilters(Module module, ServletContext servletContext) {
-
+
// Load Filters
Map<String, Filter> filters = new HashMap<String, Filter>();
try {
@@ -554,13 +554,13 @@ public class WebModuleUtil {
moduleFilters.put(module, filters.values());
moduleFiltersByName.putAll(filters);
log.debug("Module: " + module.getModuleId() + " successfully loaded " + filters.size() + " filters.");
-
+
// Load Filter Mappings
List<ModuleFilterMapping> modMappings = ModuleFilterMapping.retrieveFilterMappings(module);
moduleFilterMappings.addAll(modMappings);
log.debug("Module: " + module.getModuleId() + " successfully loaded " + modMappings.size() + " filter mappings.");
}
-
+
/**
* This method will destroy and remove all filters that were registered by the passed
* {@link Module}
@@ -568,7 +568,7 @@ public class WebModuleUtil {
* @param module - The Module for which you want to remove and destroy filters.
*/
public static void unloadFilters(Module module) {
-
+
// Unload Filter Mappings
for (java.util.Iterator<ModuleFilterMapping> mapIter = moduleFilterMappings.iterator(); mapIter.hasNext();) {
ModuleFilterMapping mapping = mapIter.next();
@@ -577,7 +577,7 @@ public class WebModuleUtil {
log.debug("Removed ModuleFilterMapping: " + mapping);
}
}
-
+
// unload Filters
Collection<Filter> filters = moduleFilters.get(module);
if (filters != null) {
@@ -591,7 +591,7 @@ public class WebModuleUtil {
}
log.debug("Module: " + module.getModuleId() + " successfully unloaded " + filters.size() + " filters.");
moduleFilters.remove(module);
-
+
for (Iterator<String> i = moduleFiltersByName.keySet().iterator(); i.hasNext();) {
String filterName = i.next();
Filter filterVal = moduleFiltersByName.get(filterName);
@@ -601,7 +601,7 @@ public class WebModuleUtil {
}
}
}
-
+
/**
* This method will return all Filters that have been registered a module
*
@@ -610,7 +610,7 @@ public class WebModuleUtil {
public static Collection<Filter> getFilters() {
return moduleFiltersByName.values();
}
-
+
/**
* This method will return all Filter Mappings that have been registered by a module
*
@@ -620,7 +620,7 @@ public class WebModuleUtil {
public static Collection<ModuleFilterMapping> getFilterMappings() {
return moduleFilterMappings;
}
-
+
/**
* Return List of Filters that have been loaded through Modules that have mappings that pass for
* the passed request
@@ -629,12 +629,12 @@ public class WebModuleUtil {
* @return List of all {@link Filter}s that have filter mappings that match the passed request
*/
public static List<Filter> getFiltersForRequest(ServletRequest request) {
-
+
List<Filter> filters = new Vector<Filter>();
if (request != null) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String requestPath = httpRequest.getRequestURI();
-
+
if (requestPath != null) {
if (requestPath.startsWith(httpRequest.getContextPath())) {
requestPath = requestPath.substring(httpRequest.getContextPath().length());
@@ -654,7 +654,7 @@ public class WebModuleUtil {
}
return filters;
}
-
+
/**
* @param inputStream
* @param realPath
@@ -666,7 +666,7 @@ public class WebModuleUtil {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new EntityResolver() {
-
+
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
// When asked to resolve external entities (such as a DTD) we return an InputSource
@@ -674,28 +674,28 @@ public class WebModuleUtil {
return new InputSource(new StringReader(""));
}
});
-
+
dwrmodulexml = db.parse(inputStream);
}
catch (Exception e) {
throw new ModuleException("Error parsing dwr-modules.xml file", e);
}
-
+
return dwrmodulexml;
}
-
+
/**
* Reverses all activities done by startModule(org.openmrs.module.Module) Normal stop/shutdown
* is done by ModuleFactory
*/
public static void shutdownModules(ServletContext servletContext) {
-
+
String realPath = getRealPath(servletContext);
-
+
// clear the module messages
String messagesPath = realPath + "/WEB-INF/";
File folder = new File(messagesPath.replace("/", File.separator));
-
+
if (folder.exists()) {
Properties emptyProperties = new Properties();
for (File f : folder.listFiles()) {
@@ -704,14 +704,14 @@ public class WebModuleUtil {
}
}
}
-
+
// call web shutdown for each module
for (Module mod : ModuleFactory.getLoadedModules()) {
stopModule(mod, servletContext, true);
}
-
+
}
-
+
/**
* Reverses all visible activities done by startModule(org.openmrs.module.Module)
*
@@ -721,7 +721,7 @@ public class WebModuleUtil {
public static void stopModule(Module mod, ServletContext servletContext) {
stopModule(mod, servletContext, false);
}
-
+
/**
* Reverses all visible activities done by startModule(org.openmrs.module.Module)
*
@@ -730,19 +730,19 @@ public class WebModuleUtil {
* @param skipRefresh
*/
public static void stopModule(Module mod, ServletContext servletContext, boolean skipRefresh) {
-
+
String moduleId = mod.getModuleId();
String modulePackage = mod.getPackageName();
-
+
// stop all dependent modules
for (Module dependentModule : ModuleFactory.getStartedModules()) {
if (!dependentModule.equals(mod) && dependentModule.getRequiredModules().contains(modulePackage)) {
stopModule(dependentModule, servletContext, skipRefresh);
}
}
-
+
String realPath = getRealPath(servletContext);
-
+
// delete the web files from the webapp
String absPath = realPath + "/WEB-INF/view/module/" + moduleId;
File moduleWebFolder = new File(absPath.replace("/", File.separator));
@@ -754,18 +754,18 @@ public class WebModuleUtil {
log.warn("Couldn't delete: " + moduleWebFolder.getAbsolutePath(), io);
}
}
-
+
// (not) deleting module message properties
-
+
// remove the module's servlets
unloadServlets(mod);
-
+
// remove the module's filters and filter mappings
unloadFilters(mod);
-
+
// stop all tasks associated with mod
stopTasks(mod);
-
+
// remove this module's entries in the dwr xml file
InputStream inputStream = null;
try {
@@ -773,20 +773,20 @@ public class WebModuleUtil {
Element root = config.getDocumentElement();
// if they defined any xml element
if (root.getElementsByTagName("dwr").getLength() > 0) {
-
+
// get the dwr-module.xml file that we're appending our code to
File f = new File(realPath + "/WEB-INF/dwr-modules.xml".replace("/", File.separator));
-
+
// testing if file exists
if (!f.exists()) {
// if it does not -> needs to be created
createDwrModulesXml(realPath);
}
-
+
inputStream = new FileInputStream(f);
Document dwrmodulexml = getDWRModuleXML(inputStream, realPath);
Element outputRoot = dwrmodulexml.getDocumentElement();
-
+
// loop over all of the children of the "dwr" tag
// and remove all "allow" and "signature" tags that have the
// same moduleId attr as the module being stopped
@@ -806,7 +806,7 @@ public class WebModuleUtil {
i++;
}
}
-
+
// save the dwr-modules.xml file.
OpenmrsUtil.saveDocument(dwrmodulexml, f);
}
@@ -824,7 +824,7 @@ public class WebModuleUtil {
}
}
}
-
+
if (skipRefresh == false) {
//try {
// if (dispatcherServlet != null)
@@ -833,12 +833,12 @@ public class WebModuleUtil {
//catch (ServletException se) {
// log.warn("Unable to reinitialize webapplicationcontext for dispatcherservlet for module: " + mod.getName(), se);
//}
-
+
refreshWAC(servletContext, false, null);
}
-
+
}
-
+
/**
* Stops, closes, and refreshes the Spring context for the given <code>servletContext</code>
*
@@ -854,25 +854,25 @@ public class WebModuleUtil {
if (log.isDebugEnabled()) {
log.debug("Refreshing web applciation Context of class: " + wac.getClass().getName());
}
-
+
if (dispatcherServlet != null) {
dispatcherServlet.stopAndCloseApplicationContext();
}
-
+
if (staticDispatcherServlet != null) {
staticDispatcherServlet.stopAndCloseApplicationContext();
}
-
+
XmlWebApplicationContext newAppContext = (XmlWebApplicationContext) ModuleUtil.refreshApplicationContext(wac,
isOpenmrsStartup, startedModule);
-
+
try {
// must "refresh" the spring dispatcherservlet as well to add in
//the new handlerMappings
if (dispatcherServlet != null) {
dispatcherServlet.reInitFrameworkServlet();
}
-
+
if (staticDispatcherServlet != null) {
staticDispatcherServlet.refreshApplicationContext();
}
@@ -880,10 +880,10 @@ public class WebModuleUtil {
catch (ServletException se) {
log.warn("Caught a servlet exception while refreshing the dispatcher servlet", se);
}
-
+
return newAppContext;
}
-
+
/**
* Save the dispatcher servlet for use later (reinitializing things)
*
@@ -893,7 +893,7 @@ public class WebModuleUtil {
log.debug("Setting dispatcher servlet: " + ds);
dispatcherServlet = ds;
}
-
+
/**
* Save the static content dispatcher servlet for use later when refreshing spring
*
@@ -903,7 +903,7 @@ public class WebModuleUtil {
log.debug("Setting dispatcher servlet for static content: " + ds);
staticDispatcherServlet = ds;
}
-
+
/**
* Finds the servlet defined by the servlet name
*
@@ -913,7 +913,7 @@ public class WebModuleUtil {
public static HttpServlet getServlet(String servletName) {
return moduleServlets.get(servletName);
}
-
+
/**
* Retrieves a path to a folder that stores web files of a module. <br>
* (path-to-openmrs/WEB-INF/view/module/moduleid)
@@ -928,47 +928,47 @@ public class WebModuleUtil {
if (dispatcherServlet == null) {
throw new ModuleException("Dispatcher servlet must be present in the web environment");
}
-
+
String moduleFolder = "WEB-INF/view/module/";
String realPath = dispatcherServlet.getServletContext().getRealPath("");
String moduleWebFolder;
-
+
//RealPath may contain '/' on Windows when running tests with the mocked servlet context
if (realPath.endsWith(File.separator) || realPath.endsWith("/")) {
moduleWebFolder = realPath + moduleFolder;
} else {
moduleWebFolder = realPath + "/" + moduleFolder;
}
-
+
moduleWebFolder += moduleId;
-
+
return moduleWebFolder.replace("/", File.separator);
}
-
+
public static void createDwrModulesXml(String realPath) {
-
+
try {
-
+
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
-
+
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("dwr");
doc.appendChild(rootElement);
-
+
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(realPath
+ "/WEB-INF/dwr-modules.xml".replace("/", File.separator)));
-
+
// Output to console for testing
// StreamResult result = new StreamResult(System.out);
-
+
transformer.transform(source, result);
-
+
}
catch (ParserConfigurationException pce) {
log.error(pce);
@@ -977,9 +977,9 @@ public class WebModuleUtil {
log.error(tfe);
}
}
-
+
public static String getRealPath(ServletContext servletContext) {
return servletContext.getRealPath("");
}
-
+
}
diff --git a/web/src/main/java/org/openmrs/module/web/filter/ModuleFilterMapping.java b/web/src/main/java/org/openmrs/module/web/filter/ModuleFilterMapping.java
index 123c189..b2588b1 100644
--- a/web/src/main/java/org/openmrs/module/web/filter/ModuleFilterMapping.java
+++ b/web/src/main/java/org/openmrs/module/web/filter/ModuleFilterMapping.java
@@ -27,107 +27,107 @@ import org.w3c.dom.NodeList;
* This class represents the mapping of a Filter to a collection of Servlets and URLs
*/
public class ModuleFilterMapping implements Serializable {
-
+
public static final long serialVersionUID = 1;
-
+
private static Log log = LogFactory.getLog(WebModuleUtil.class);
-
+
// Properties
private Module module;
-
+
private String filterName;
-
+
private List<String> servletNames = new ArrayList<String>();
-
+
private List<String> urlPatterns = new ArrayList<String>();
-
+
/**
* Default constructor, requires a Module
- *
+ *
* @param module - the module to use to construct this ModuleFilterMapping
*/
public ModuleFilterMapping(Module module) {
this.module = module;
}
-
+
/**
* @return - the {@link Module} that registered this FilterDefinition
*/
public Module getModule() {
return module;
}
-
+
/**
* @param module the {@link Module}
*/
public void setModule(Module module) {
this.module = module;
}
-
+
/**
* @return the name of the Filter
*/
public String getFilterName() {
return filterName;
}
-
+
/**
* @param filterName the name of the Filter
*/
public void setFilterName(String filterName) {
this.filterName = filterName;
}
-
+
/**
* @return a List of all Servlet Names mapped to this Filter
*/
public List<String> getServletNames() {
return servletNames;
}
-
+
/**
* @param servletNames a List of all Servlet Names mapped to this filter
*/
public void setServletNames(List<String> servletNames) {
this.servletNames = servletNames;
}
-
+
/**
* Adds a Servlet name to the List of those mapped to this filter
- *
+ *
* @param servletName - The servlet name to add
*/
public void addServletName(String servletName) {
this.servletNames.add(servletName);
}
-
+
/**
* @return - a List of all Url Patterns mapped to this filter
*/
public List<String> getUrlPatterns() {
return urlPatterns;
}
-
+
/**
* @param urlPatterns a List of all Url Patterns mapped to this filter
*/
public void setUrlPatterns(List<String> urlPatterns) {
this.urlPatterns = urlPatterns;
}
-
+
/**
* Adds a Url pattern to the List of those mapped to this filter
- *
+ *
* @param urlPattern - The urlPattern to add
*/
public void addUrlPattern(String urlPattern) {
this.urlPatterns.add(urlPattern);
}
-
+
/**
* Return <code>true</code> if the passed Filter passes one or more filter mappings otherwise,
* return <code>false</code>.
- *
+ *
* @param filterMapping - The {@link ModuleFilterMapping} to check for matching servlets and url
* patterns
* @param requestPath - The URI of the request to check against the {@link ModuleFilterMapping},
@@ -145,12 +145,12 @@ public class ModuleFilterMapping implements Serializable {
* @should return false if no matches are found for this requestPath
*/
public static boolean filterMappingPasses(ModuleFilterMapping filterMapping, String requestPath) {
-
+
// Return false if url is null
if (requestPath == null) {
return false;
}
-
+
for (String patternToCheck : filterMapping.getUrlPatterns()) {
if (urlPatternMatches(patternToCheck, requestPath)) {
return true;
@@ -161,15 +161,15 @@ public class ModuleFilterMapping implements Serializable {
return true;
}
}
-
+
// If none found, return false
return false;
}
-
+
/**
* Return <code>true</code> if the context-relative request path matches the patternToCheck
* otherwise, return <code>false</code>.
- *
+ *
* @param patternToCheck String pattern to check
* @param requestPath to check
* @should return false if the patternToCheck is null
@@ -181,19 +181,19 @@ public class ModuleFilterMapping implements Serializable {
* @should return false if no pattern matches
*/
public static boolean urlPatternMatches(String patternToCheck, String requestPath) {
-
+
// Return false if patternToCheck is null
if (patternToCheck == null) {
return false;
}
-
+
log.debug("Checking URL <" + requestPath + "> against pattern <" + patternToCheck + ">");
-
+
// Match exact or full wildcard
- if (patternToCheck.equals("*") || patternToCheck.equals("/*") || patternToCheck.equals(requestPath)) {
+ if ("*".equals(patternToCheck) || "/*".equals(patternToCheck) || patternToCheck.equals(requestPath)) {
return true;
}
-
+
// Match wildcard
if (patternToCheck.endsWith("/*")) {
int patternLength = patternToCheck.length() - 2;
@@ -206,27 +206,27 @@ public class ModuleFilterMapping implements Serializable {
}
return false;
}
-
+
// Case 3 - Extension Match
if (patternToCheck.startsWith("*.")) {
int slash = requestPath.lastIndexOf('/');
int period = requestPath.lastIndexOf('.');
int reqLen = requestPath.length();
int patLen = patternToCheck.length();
-
+
if (slash >= 0 && period > slash && period != reqLen - 1 && reqLen - period == patLen - 1) {
return (patternToCheck.regionMatches(2, requestPath, period + 1, patLen - 2));
}
}
-
+
// If no match found by here, return false
return false;
}
-
+
/**
* Return <code>true</code> if the specified servlet name matches the filterMapping otherwise
* return <code>false</code>.
- *
+ *
* @param patternToCheck String pattern to check
* @param servletName Servlet Name to check
* @should return false if the patternToCheck is null
@@ -235,27 +235,27 @@ public class ModuleFilterMapping implements Serializable {
* @should return false if no pattern matches
*/
public static boolean servletNameMatches(String patternToCheck, String servletName) {
-
+
// Return false if servletName is null
if (servletName == null) {
return false;
}
-
+
log.debug("Checking servlet <" + servletName + "> against pattern <" + patternToCheck + ">");
-
+
// Match exact or full wildcard
if (("*").equals(patternToCheck) || servletName.equals(patternToCheck)) {
return true;
}
-
+
// If none found, return false
return false;
}
-
+
/**
* Static method to parse through a Module's configuration file and return a List of
* ModuleFilterMapping objects for which there are configuration elements. Expected XML Format:
- *
+ *
* <pre>
* &lt;filter-mapping&gt;
* &lt;filter-name&gt;MyFilterName&lt;/filter-name&gt;
@@ -267,16 +267,16 @@ public class ModuleFilterMapping implements Serializable {
* &lt;servlet-name&gt;The servlet name to match&lt;/servlet-name&gt;
* &lt;/filter-mapping&gt;
* </pre>
- *
+ *
* @param module - The {@link Module} for which you want to retrieve the defined
* {@link ModuleFilterMapping}s
* @return - a List of {@link ModuleFilterMapping}s that are defined for the passed
* {@link Module}
*/
public static List<ModuleFilterMapping> retrieveFilterMappings(Module module) throws ModuleException {
-
+
List<ModuleFilterMapping> mappings = new Vector<ModuleFilterMapping>();
-
+
try {
Element rootNode = module.getConfig().getDocumentElement();
NodeList mappingNodes = rootNode.getElementsByTagName("filter-mapping");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment