/** * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations under * the License. * * The Original Code is OpenELIS code. * * Copyright (C) The Minnesota Department of Health. All Rights Reserved. * * Contributor(s): CIRG, University of Washington, Seattle WA. */ package us.mn.state.health.lims.common.util; import org.apache.commons.validator.GenericValidator; import java.util.HashMap; import java.util.Map; /* * This is an abstract class which represents the configuration properties of the application. The derived * classes will determine how the propertiesValueMap is populated */ public abstract class ConfigurationProperties { public enum LOCALE{ ENGLISH("en_US"), FRENCH("fr-FR"); private String locale; private LOCALE(String locale){ this.locale = locale; } public String getRepresentation(){ return locale; } } private static final Object lockObj = new Object(); private static ConfigurationProperties activeConcreteInstance= null; protected Map<ConfigurationProperties.Property, String> propertiesValueMap = new HashMap<ConfigurationProperties.Property, String>(); //These should all be upper case. As you touch them change them public enum Property{ AmbiguousDateValue, //Are ambiguous dates allowed for DOB. i.e. patient knows age but not actuall DOB AmbiguousDateHolder, //What character should be used as a placeholder when displaying the date. i.e. if 'X' then XX/XX/2000 ReferingLabParentOrg, //Should the parent organization of a lab be entered. i.e. The hospital in which the lab is run FormFieldSet, //internal only PasswordRequirments, //Indicator for what the password complexity requirements are. Should be standardized StringContext, //Determines which equivalent string should be used. i.e. label for accession number can be 'lab number' or 'accession number' StatusRules, //Only used to separate RetroCI rules from others. May be obsolete SiteCode, //Code referring to site SiteName, //Name for site AccessionFormat, //Format of accession number can be one of SITEYEARNUM, YEARNUM OR PROGRAMNUM see AccessionNumberValidatorFactory ReflexAction, //In combination with flags in reflex table determines actual action, should be standardize TrainingInstallation, //Flag to indicate if this is a training instance UseExternalPatientInfo, //If true patient information will be searched for externally PatientSearchURL, //URL of where external patient information will be searched PatientSearchUserName, //User name for accesses to external patient search PatientSearchPassword, //User password for accesses to external patient search labDirectorName, //The name of the lab director languageSwitch, //If true a user can switch between English and French (changes it for everybody) reportResults, //If true results will be reported electronically resultReportingURL, //URL for electronic result reporting malariaSurveillanceReport, //If true malaria surveillance will be reported electronically malariaSurveillanceReportURL,//URL for malaria surveillance reporting malariaCaseReport, //If true send malaria case reports malariaCaseReportURL, //URL for malaria case reports releaseNumber, //The release number buildNumber, //Repository identifier configurationName, //Identifies the configuration i.e. HaitiLNSP or CI IPCI testUsageReportingURL, //URL for test summary reporting testUsageReporting, //If true send test summary report electronically roleRequiredForModifyResults,//If true a separate role is needed to modify reports notesRequiredForModifyResults,//If true a note is required when a result is modified resultTechnicianName, //If true the technicians name is needed for results allowResultRejection, //If true then a technician has the ability to reject an individual test and select a reason for rejection restrictFreeTextRefSiteEntry, //If true then a user cannot enter new referring sites during sample entry and must choose from list provided autoFillTechNameBox, //If true a box will be provided to auto-fill technicians name for all results on page autoFillTechNameUser, //If true the technicians name will be auto-filled with the name of the logged in user AUTOFILL_COLLECTION_DATE, //If true the collection date will be auto-filled with current date failedValidationMarker, //If true results that failed validation will have icon next to them resultsResendTime, //How much time between trying to resend results that failed to reach their destination TRACK_PATIENT_PAYMENT, //If true then patient payment status can be entered ALERT_FOR_INVALID_RESULTS, //If true then technician will get an alert for results outside of the valid range DEFAULT_LANG_LOCALE, //Default language locale DEFAULT_DATE_LOCALE, //Date local CONDENSE_NFS_PANEL, //Flag used for RetroCI to condense NFS panel tests PATIENT_DATA_ON_RESULTS_BY_ROLE,//If true patient data will show on results page only if user has correct permissions USE_PAGE_NUMBERS_ON_REPORTS, //If true page numbers will be used on reports QA_SORT_EVENT_LIST, //If true QA events will be sorted by name ALWAYS_VALIDATE_RESULTS, //If true all results will be validated, otherwise just those outside of valid range and those flagged ADDITIONAL_SITE_INFO, //Extra site info for report header SUBJECT_ON_WORKPLAN, //If true the subject will be on the workplan NEXT_VISIT_DATE_ON_WORKPLAN, //If true the next visit date will be on workplan RESULTS_ON_WORKPLAN, //If true a space will be left for results on the workplan ACCEPT_EXTERNAL_ORDERS, //If true EMR's can make electronic orders to lab SIGNATURES_ON_NONCONFORMITY_REPORTS, //If true a space should be left for signatures on non-conformity reports NONCONFORMITY_RECEPTION_AS_UNIT, //If true then reception will be an option for where a non-conformity was identified NONCONFORMITY_SAMPLE_COLLECTION_AS_UNIT, //If true then sample collection will be an option for where a non-conformity was identified ACCESSION_NUMBER_PREFIX, //If SITEYEARNUM is the format then this is the prefix NOTE_EXTERNAL_ONLY_FOR_VALIDATION, //If true then only validation notes will be on patient report PHONE_FORMAT, //Format of phone number VALIDATE_PHONE_FORMAT, //If true then entered phone numbers will be validated against format ALLOW_DUPLICATE_SUBJECT_NUMBERS, //If true then duplicate subject numbers are allowed VALIDATE_REJECTED_TESTS, //If true then if the technician rejects a test the next step is validation TEST_NAME_AUGMENTED, //If true then in some places the test name will be suffixed with the sample type USE_BILLING_REFERENCE_NUMBER, //If true then the user can enter billing codes for latter reporting BILLING_REFERENCE_NUMBER_LABEL, //The label being used for the billing reference number ORDER_PROGRAM, //Should program be part of an order BANNER_TEXT, //Text on Banner CLOCK_24, //True for 24 hour clock, false for 12 hour clock PATIENT_NATIONALITY, //True if patient nationality should be collected with patient information PATIENT_ID_REQUIRED, //True if patient id is required for new patient PATIENT_SUBJECT_NUMBER_REQUIRED, //True if patient subject number is required for new patient QA_SAMPLE_ID_REQUIRED //True if sample id required from referring lab } public static ConfigurationProperties getInstance(){ synchronized (lockObj) { if (activeConcreteInstance == null) { activeConcreteInstance = new DefaultConfigurationProperties(); } } return activeConcreteInstance; } public String getPropertyValue( Property property ){ loadIfPropertyValueNeeded(property); return GenericValidator.isBlankOrNull(propertiesValueMap.get(property)) ? null : propertiesValueMap.get(property).trim(); } public String getPropertyValueUpperCase( Property property ){ String value = getPropertyValue(property); return value == null ? null : value.toUpperCase(); } public String getPropertyValueLowerCase( Property property ){ String value = getPropertyValue(property); return value == null ? null : value.toLowerCase(); } public static void forceReload(){ activeConcreteInstance = null; } /* * Allowing for lazy loading. */ abstract protected void loadIfPropertyValueNeeded(Property property); public boolean isPropertyValueEqual(Property property, String target) { if( target == null){ return getPropertyValue(property) == null; }else{ return target.equals(getPropertyValue(property)); } } public boolean isCaseInsensitivePropertyValueEqual(Property property, String target) { if( target == null){ return getPropertyValue(property) == null; }else{ return target.toLowerCase().equals(getPropertyValueLowerCase(property)); } } public void setPropertyValue( Property property, String value){ propertiesValueMap.put(property, value); } /** * For testing only to set a controllable singleton * @param activeConcreteInstance */ public static void setActiveConcreteInstance( ConfigurationProperties activeConcreteInstance) { ConfigurationProperties.activeConcreteInstance = activeConcreteInstance; } }