Java tutorial
/** * Copyright (c) 2001-2002. Department of Family Medicine, McMaster University. All Rights Reserved. * This software is published under the GPL GNU General Public License. * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * This software was written for the * Department of Family Medicine * McMaster University * Hamilton * Ontario, Canada */ package oscar.eform.data; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sf.json.JSONArray; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.struts.action.ActionMessages; import org.oscarehr.common.OtherIdManager; import org.oscarehr.common.dao.EFormDataDao; import org.oscarehr.common.model.EFormData; import org.oscarehr.ui.servlet.ImageRenderingServlet; import org.oscarehr.util.DigitalSignatureUtils; import org.oscarehr.util.MiscUtils; import org.oscarehr.util.SpringUtils; import oscar.eform.EFormLoader; import oscar.eform.EFormUtil; import oscar.oscarEncounter.oscarMeasurements.bean.EctMeasurementsDataBeanHandler; import oscar.oscarEncounter.oscarMeasurements.util.WriteNewMeasurements; import oscar.util.StringBuilderUtils; import oscar.util.UtilDateUtilities; public class EForm extends EFormBase { private static EFormDataDao eFormDataDao = (EFormDataDao) SpringUtils.getBean("EFormDataDao"); private static Logger log = MiscUtils.getLogger(); private String appointment_no = "-1"; private HashMap<String, String> sql_params = new HashMap<String, String>(); private String parentAjaxId = null; private String eform_link = null; private HashMap<String, String> fieldValues = new HashMap<String, String>(); private int needValueInForm = 0; private boolean setAP2nd = false; private static final String EFORM_DEMOGRAPHIC = "eform_demographic"; private static final String VAR_NAME = "var_name"; private static final String VAR_VALUE = "var_value"; private static final String REF_FID = "fid"; private static final String REF_VAR_NAME = "ref_var_name"; private static final String REF_VAR_VALUE = "ref_var_value"; private static final String TABLE_NAME = "table_name"; private static final String TABLE_ID = "table_id"; private static final String OTHER_KEY = "other_key"; private static final String OPENER_VALUE = "link$eform"; public EForm() { } public EForm(String fid, String demographicNo) { loadEForm(fid, demographicNo); } public EForm(String fid, String demographicNo, String providerNo) { // used to load an uploaded eform loadEForm(fid, demographicNo); this.providerNo = providerNo; } public EForm(String fdid) { if (!StringUtils.isBlank(fdid) && !"null".equalsIgnoreCase(fdid)) { EFormData eFormData = eFormDataDao.find(new Integer(fdid)); if (eFormData != null) { this.fdid = fdid; this.fid = eFormData.getFormId().toString(); this.providerNo = eFormData.getProviderNo(); this.demographicNo = eFormData.getDemographicId().toString(); this.formName = eFormData.getFormName(); this.formSubject = eFormData.getSubject(); this.formDate = eFormData.getFormDate().toString(); this.formHtml = eFormData.getFormData(); this.showLatestFormOnly = eFormData.isShowLatestFormOnly(); this.patientIndependent = eFormData.isPatientIndependent(); this.roleType = eFormData.getRoleType(); } } else { this.formName = ""; this.formSubject = ""; this.formHtml = "No Such Form in Database"; } } public void loadEForm(String fid, String demographicNo) { HashMap<String, Object> loaded = EFormUtil.loadEForm(fid); this.fid = fid; this.formName = (String) loaded.get("formName"); this.formHtml = (String) loaded.get("formHtml"); this.formSubject = (String) loaded.get("formSubject"); this.formDate = (String) loaded.get("formDate"); this.formFileName = (String) loaded.get("formFileName"); this.formCreator = (String) loaded.get("formCreator"); this.demographicNo = demographicNo; this.showLatestFormOnly = (Boolean) loaded.get("showLatestFormOnly"); this.patientIndependent = (Boolean) loaded.get("patientIndependent"); this.roleType = (String) loaded.get("roleType"); } public String getAppointmentNo() { return this.appointment_no; } public void setAppointmentNo(String appt_no) { this.appointment_no = EFormUtil.blank(appt_no) ? "-1" : appt_no; } public String getEformLink() { return this.eform_link; } public void setEformLink(String el) { this.eform_link = el; } public void setAction(String pAjaxId) { parentAjaxId = pAjaxId; setAction(); } public void setAction() { setAction(false); } public void setAction(boolean unset) { // sets action= in the form StringBuilder html = new StringBuilder(this.formHtml); int index = StringBuilderUtils.indexOfIgnoreCase(html, "<form", 0); int endtag = html.indexOf(">", index + 1); // --remove all previous actions, methods and names from the form tag if (index < 0) return; int pointer, pointer2; while (((pointer = StringBuilderUtils.indexOfIgnoreCase(html, " action=", index)) >= 0) && (pointer < endtag)) { pointer2 = nextSpot(html, pointer + 1); html = html.delete(pointer, pointer2); endtag = html.indexOf(">", index + 1); } while (((pointer = StringBuilderUtils.indexOfIgnoreCase(html, " method=", index)) >= 0) && (pointer < endtag)) { pointer2 = nextSpot(html, pointer + 1); html = html.delete(pointer, pointer2); endtag = html.indexOf(">", index + 1); } pointer = StringBuilderUtils.indexOfIgnoreCase(html, " name=", index); String name = "name=\"saveEForm\" "; if ((pointer >= 0) && (pointer < endtag)) { pointer2 = nextSpot(html, pointer + 1); endtag = html.indexOf(">", index + 1); name = ""; } if (index < 0) return; if (unset) { this.formHtml = html.toString(); return; } index += 5; StringBuilder action = new StringBuilder( "action=\"../eform/addEForm.do?efmfid=" + this.fid + "&efmdemographic_no=" + this.demographicNo + "&efmprovider_no=" + this.providerNo + "&eform_link=" + this.eform_link); if (this.parentAjaxId != null) action.append("&parentAjaxId=" + this.parentAjaxId); action.append("\""); String method = "method=\"POST\""; html.insert(index, " " + action.toString() + " " + name + method); this.formHtml = html.toString(); } // ------------------Saving the Form (inserting value= statements)--------------------- public void setValues(ArrayList<String> names, ArrayList<String> values) { if (names.size() != values.size()) return; StringBuilder html = new StringBuilder(this.formHtml); int pointer = -1; while ((pointer = getFieldIndex(html, pointer + 1)) >= 0) { String fieldHeader = getFieldHeader(html, pointer); String fieldName = EFormUtil.removeQuotes(EFormUtil.getAttribute("name", fieldHeader)); int i; if ((i = names.indexOf(fieldName)) < 0) continue; String val = values.get(i); pointer = nextSpot(html, pointer); html = putValue(val, getFieldType(fieldHeader), pointer, html); } this.formHtml = html.toString(); } // ------------------Saving the Form (inserting fdid$value= statements)--------------------- public void setOpenerValues(ArrayList<String> names, ArrayList<String> values) { StringBuilder html = new StringBuilder(this.formHtml); EFormLoader.getInstance(); String opener = EFormLoader.getOpener(); // default: opener: "oscarOPEN=" int markerLoc = -1; while ((markerLoc = getFieldIndex(html, markerLoc + 1)) >= 0) { String fieldHeader = getFieldHeader(html, markerLoc); if (EFormUtil.blank(EFormUtil.getAttribute(opener, fieldHeader))) continue; String fieldName = EFormUtil.removeQuotes(EFormUtil.getAttribute("name", fieldHeader)); int i; if (EFormUtil.blank(fieldName)) continue; if ((i = names.indexOf(fieldName)) < 0) continue; if (EFormUtil.blank(values.get(i))) continue; // sets up the pointer where to write the value int pointer = nextSpot(html, markerLoc + EFormUtil.getAttributePos(opener, fieldHeader)); int offset = EFormUtil.getAttributePos(OPENER_VALUE, fieldHeader); if (offset >= 0) { //delete current OPENER_VALUE pointer = markerLoc + offset; int valueEnd = nextSpot(html, pointer); html.delete(pointer - 1, valueEnd); } html = putValue(values.get(i), OPENER_VALUE, pointer, html); } formHtml = html.toString(); } // --------------------------Setting APs utilities---------------------------------------- public void setDatabaseAPs() { StringBuilder html = new StringBuilder(this.formHtml); EFormLoader.getInstance(); String marker = EFormLoader.getMarker(); // default: marker: "oscarDB=" for (int i = 0; i < 2; i++) { // run the following twice if "count"-type field is found int markerLoc = -1; while ((markerLoc = getFieldIndex(html, markerLoc + 1)) >= 0) { log.debug("===============START CYCLE==========="); String fieldHeader = getFieldHeader(html, markerLoc); String apName = EFormUtil.getAttribute(marker, fieldHeader); // gets varname from oscarDB=varname String apName0 = EFormUtil.removeQuotes(apName); if (EFormUtil.blank(apName)) { if (!setAP2nd) saveFieldValue(html, markerLoc); continue; } log.debug("AP ==== " + apName); if (setAP2nd && !apName0.startsWith("e$")) continue; // ignore non-e$ oscarDB on 2nd run int needing = needValueInForm; String fieldType = getFieldType(fieldHeader); // textarea, text, hidden etc.. if ((fieldType == null || fieldType.equals("")) || (apName0 == null || apName0.equals(""))) continue; // sets up the pointer where to write the value int pointer = markerLoc + EFormUtil.getAttributePos(marker, fieldHeader) + marker.length() + 1; if (!fieldType.equals("textarea")) { pointer += apName.length(); } EFormLoader.getInstance(); DatabaseAP curAP = EFormLoader.getAP(apName0); if (curAP == null) curAP = getAPExtra(apName0, fieldHeader); if (curAP == null) continue; if (!setAP2nd) { // 1st run html = putValuesFromAP(curAP, fieldType, pointer, html); saveFieldValue(html, markerLoc); } else { // 2nd run if (needing > needValueInForm) html = putValuesFromAP(curAP, fieldType, pointer, html); } log.debug("Marker ==== " + markerLoc); log.debug("FIELD TYPE ====" + fieldType); log.debug("=================End Cycle=============="); } formHtml = html.toString(); if (needValueInForm > 0) setAP2nd = true; else i = 2; } } // Gets all the fields that are "input" (i.e. write-to-database) fields. public void setupInputFields() { String marker = EFormLoader.getInputMarker(); StringBuilder html = new StringBuilder(this.formHtml); int markerLoc; int pointer = 0; while ((markerLoc = StringBuilderUtils.indexOfIgnoreCase(html, marker, pointer)) >= 0) { pointer = (markerLoc + marker.length()); updateFields.add(getFieldName(html, pointer)); } generateInputCode(); } private void generateInputCode() { if (updateFields.size() > 0) { StringBuilder html = new StringBuilder(this.formHtml); int formEndLoc = StringBuilderUtils.indexOfIgnoreCase(html, "</form>", 0); int scriptEndLoc = StringBuilderUtils.indexOfIgnoreCase(html, "</script>", 0); if (formEndLoc < 0) formEndLoc = 1; if (scriptEndLoc < 0) scriptEndLoc = 0; else scriptEndLoc += 9; String fieldValue = ""; for (String field : updateFields) { fieldValue += field + "%"; } html.insert(formEndLoc - 1, "<span id='_oscardodatabaseupdatespan' style='position: absolute;' class='DoNotPrint'><input type='checkbox' name='_oscardodatabaseupdate' onchange='_togglehighlight()' /> Update Fields in Database<br />" + "<input type='button' id='_oscarrefreshfieldsbtn' name='_oscarrefreshfieldsbtn' value='Refresh DB Fields' onclick='_refreshfields()' /></span> " + "<input type='hidden' id='_oscarupdatefields' name='_oscarupdatefields' value='" + fieldValue + "' />" + "<input type='hidden' id='_oscardemographicno' name='_oscardemographicno' value='" + this.demographicNo + "' />" + "<input type='hidden' id='_oscarproviderno' name='_oscarproviderno' value='" + this.providerNo + "' />" + "<input type='hidden' id='_oscarfid' name='_oscarfid' value='" + this.fid + "' />"); this.formHtml = html.insert(scriptEndLoc, "<script type='text/javascript' src='../share/javascript/jquery/jquery-1.4.2.js'></script>" + "<script type='text/javascript' src='../js/eform_highlight.js'></script>") .toString(); } } // --------------------------Setting oscarOPEN behaviours ---------------------------------------- public void setOscarOPEN(String requestURI) { StringBuilder html = new StringBuilder(this.formHtml); EFormLoader.getInstance(); String opener = EFormLoader.getOpener(); // default: opener: "oscarOPEN=" int markerLoc = -1; while ((markerLoc = getFieldIndex(html, markerLoc + 1)) >= 0) { log.debug("=============START OPENER CYCLE==========="); String fieldHeader = getFieldHeader(html, markerLoc); String efmName = EFormUtil.getAttribute(opener, fieldHeader); // gets eform name from oscarOPEN=rname if (EFormUtil.blank(efmName)) continue; String fieldName = EFormUtil.removeQuotes(EFormUtil.getAttribute("name", fieldHeader)); if (EFormUtil.blank(fieldName)) continue; log.debug("OPEN ==== " + efmName); // sets up the pointer where to write the value String fdid = EFormUtil.removeQuotes(EFormUtil.getAttribute(OPENER_VALUE, fieldHeader)); EFormLoader.getInstance(); String onclick = EFormLoader.getOpenEform(requestURI, fdid, EFormUtil.removeQuotes(efmName), fieldName, this); int pointer = EFormUtil.getAttributePos("onclick", fieldHeader); String type = pointer < 0 ? "onclick" : "onclick_append"; if (pointer < 0) { pointer = nextSpot(html, markerLoc + EFormUtil.getAttributePos(opener, fieldHeader)); } else { pointer = nextSpot(html, markerLoc + pointer); } html = putValue(onclick, type, pointer, html); log.debug("Opener ==== " + markerLoc); log.debug("=================End Opener Cycle=============="); } formHtml = html.toString(); } public void setNowDateTime() { this.formTime = UtilDateUtilities.DateToString(UtilDateUtilities.now(), "HH:mm:ss"); this.formDate = UtilDateUtilities.DateToString(UtilDateUtilities.now(), "yyyy-MM-dd"); } public ActionMessages setMeasurements(ArrayList<String> names, ArrayList<String> values) { return (WriteNewMeasurements.addMeasurements(names, values, this.demographicNo, this.providerNo)); } public void setContextPath(String contextPath) { if (EFormUtil.blank(contextPath)) return; String oscarJS = contextPath + "/share/javascript/"; this.formHtml = this.formHtml.replace(jsMarker, oscarJS); } public ArrayList<String> getOpenerNames() { ArrayList<String> openerNames = new ArrayList<String>(); EFormLoader.getInstance(); String opener = EFormLoader.getOpener(); // default: opener: "oscarOPEN=" StringBuilder html = new StringBuilder(this.formHtml); int markerLoc = -1; while ((markerLoc = getFieldIndex(html, markerLoc + 1)) >= 0) { String fieldHeader = getFieldHeader(html, markerLoc); String efmName = EFormUtil.getAttribute(opener, fieldHeader); // gets eform name from oscarOPEN=rname if (EFormUtil.blank(efmName)) continue; String fieldName = EFormUtil.removeQuotes(EFormUtil.getAttribute("name", fieldHeader)); if (!EFormUtil.blank(fieldName)) openerNames.add(fieldName); } return openerNames; } public String getTemplate() { // Get content between "<!-- <template>" & "</template> -->" if (EFormUtil.blank(formHtml)) return ""; String sTemplateBegin = "<template>"; String sTemplateEnd = "</template>"; String sCommentBegin = "<!--", sCommentEnd = "-->"; String text = ""; int templateBegin = -1, templateEnd = -1; boolean searching = true; while (searching) { templateBegin = EFormUtil.findIgnoreCase(sTemplateBegin, formHtml, templateBegin + 1); templateEnd = EFormUtil.findIgnoreCase(sTemplateEnd, formHtml, templateBegin); int commentBegin = formHtml.lastIndexOf(sCommentBegin, templateBegin); int commentEnd = formHtml.indexOf(sCommentEnd, commentBegin); if (templateBegin == -1 || templateEnd == -1 || commentBegin == -1 || commentEnd == -1) { searching = false; } else if (commentEnd > templateEnd) { text += formHtml.substring(templateBegin + sTemplateBegin.length(), templateEnd); } } return text; } // ----------------------------------private // ----------------------------------------- private DatabaseAP getAPExtra(String apName, String fieldHeader) { // --------------------------Process extra attributes for APs -------------------------------- Pattern p = Pattern.compile("\\b[a-z]\\$[^ \\$#]+#[^\n]+"); Matcher m = p.matcher(apName); if (!m.matches()) return null; String module = apName.substring(0, apName.indexOf("$")); String type = apName.substring(apName.indexOf("$") + 1, apName.indexOf("#")); String field = apName.substring(apName.indexOf("#") + 1, apName.length()); DatabaseAP curAP = null; if (module.equals("m")) { log.debug("SWITCHING TO MEASUREMENTS"); Hashtable data = EctMeasurementsDataBeanHandler.getLast(this.demographicNo, type); if (data != null) { curAP = new DatabaseAP(); curAP.setApName(apName); curAP.setApOutput((String) data.get(field)); } } else if (module.equals("e")) { log.debug("SWITCHING TO EFORM_VALUES"); String eform_name = EFormUtil.removeQuotes(EFormUtil.getAttribute("eform$name", fieldHeader)); String var_value = EFormUtil.removeQuotes(EFormUtil.getAttribute("var$value", fieldHeader)); String ref = EFormUtil.removeQuotes(EFormUtil.getAttribute("ref$", fieldHeader, true)); String eform_demographic = this.demographicNo; if (this.patientIndependent) eform_demographic = "%"; String ref_name = null, ref_value = null, ref_fid = fid; if (!EFormUtil.blank(ref) && ref.contains("=")) { ref_name = ref.substring(4, ref.indexOf("=")); ref_value = EFormUtil.removeQuotes(ref.substring(ref.indexOf("=") + 1)); } else { ref_name = EFormUtil.blank(ref) ? "" : ref.substring(4); } if (!EFormUtil.blank(eform_name)) ref_fid = getRefFid(eform_name); if ((!EFormUtil.blank(var_value) && var_value.trim().startsWith("{")) || (!EFormUtil.blank(ref_value) && ref_value.trim().startsWith("{"))) { if (setAP2nd) { // 2nd run, put value in required field var_value = findValueInForm(var_value); ref_value = findValueInForm(ref_value); needValueInForm--; } else { // 1st run, note the need to reference other value in form needValueInForm++; return null; } } if (type.equalsIgnoreCase("count") && var_value == null) type = "countname"; if (!ref_name.equals("")) { type += "_ref"; if (ref_value == null) type += "name"; } EFormLoader.getInstance(); curAP = EFormLoader.getAP("_eform_values_" + type); if (curAP != null) { setSqlParams(EFORM_DEMOGRAPHIC, eform_demographic); setSqlParams(VAR_NAME, field); setSqlParams(REF_VAR_NAME, ref_name); setSqlParams(VAR_VALUE, var_value); setSqlParams(REF_VAR_VALUE, ref_value); setSqlParams(REF_FID, ref_fid); } } else if (module.equals("o")) { log.debug("SWITCHING TO OTHER_ID"); String table_name = "", table_id = ""; EFormLoader.getInstance(); curAP = EFormLoader.getAP("_other_id"); if (type.equalsIgnoreCase("patient")) { table_name = OtherIdManager.DEMOGRAPHIC.toString(); table_id = this.demographicNo; } else if (type.equalsIgnoreCase("appointment")) { table_name = OtherIdManager.APPOINTMENT.toString(); table_id = appointment_no; if (EFormUtil.blank(table_id)) table_id = "-1"; } setSqlParams(OTHER_KEY, field); setSqlParams(TABLE_NAME, table_name); setSqlParams(TABLE_ID, table_id); } return curAP; } private StringBuilder putValue(String value, String type, int pointer, StringBuilder html) { // inserts value= into tag or textarea if (type == null) return html; if (type.equals("onclick") || type.equals("onclick_append")) { if (type.equals("onclick_append")) { if (html.charAt(pointer - 1) == '"') pointer -= 1; if (html.charAt(pointer - 1) != ';') value = ";" + value; } else { value = "onclick=\"" + value + "\""; } html.insert(pointer, " " + value); } else if (type.equals(OPENER_VALUE)) { html.insert(pointer, " " + OPENER_VALUE + "=\"" + value + "\""); } else if (type.equals("text") || type.equals("hidden")) { html.insert(pointer, " value=\"" + value + "\""); } else if (type.equals("textarea")) { pointer = html.indexOf(">", pointer) + 1; int endPointer = html.indexOf("<", pointer); html.delete(pointer, endPointer); html.insert(pointer, value); } else if (type.equals("checkbox")) { html.insert(pointer, " checked"); } else if (type.equals("select")) { int endindex = StringBuilderUtils.indexOfIgnoreCase(html, "</select>", pointer); if (endindex < 0) return html; // if closing tag not found int valueLoc = nextIndex(html, " value=" + value, " value=\"" + value, pointer); if (valueLoc < 0 || valueLoc > endindex) return html; pointer = nextSpot(html, valueLoc + 1); html.insert(pointer, " selected"); } else if (type.equals("radio")) { int endindex = html.indexOf(">", pointer); int valindexS = nextIndex(html, " value=", " value=", pointer); if (valindexS < 0 || valindexS > endindex) return html; // if value= not found in tag valindexS += 7; if (html.charAt(valindexS) == '"') valindexS++; int valindexE = valindexS + value.length(); if (html.substring(valindexS, valindexE).equals(value)) { pointer = nextSpot(html, valindexE); html.insert(pointer, " checked"); } } return html; } private int nextIndex(StringBuilder text, String option1, String option2, int pointer) { // converts text content to lowercase text = new StringBuilder(text.toString().toLowerCase()); option1 = option1.toLowerCase(); option2 = option2.toLowerCase(); // returns the index of option1 or option2 whichever one is closer and exists int index; int option1i = text.indexOf(option1, pointer); int option2i = text.indexOf(option2, pointer); if (option1i < 0) index = option2i; else if (option2i < 0 || option1i < option2i) index = option1i; else index = option2i; return index; } private int nextSpot(StringBuilder text, int pointer) { //nextSport: \n, \r, >, ' ' int end = nextIndex(text, "\n", "\r", pointer); if (end < 0) end = text.length(); int index = text.substring(pointer, end).indexOf('=') + pointer; if (index >= 0) { //deal with cases of quoted values with spaces ("xx xx" / 'xx xx') if (text.charAt(index + 1) == '"') { int close = text.substring(index + 2, end).indexOf("\"") + (index + 2); if (close > 0) return close + 1; } if (text.charAt(index + 1) == '\'') { int close = text.substring(index + 2, end).indexOf("'") + (index + 2); if (close > 0) return close + 1; } pointer = index; } return nextIndex(text, " ", ">", pointer); } private String getFieldType(String fieldHeader) { if (fieldHeader.substring(1, 9).equalsIgnoreCase("textarea")) return "textarea"; if (fieldHeader.substring(1, 7).equalsIgnoreCase("select")) return "select"; return EFormUtil.removeQuotes(EFormUtil.getAttribute("type", fieldHeader)); } /* private String getFieldType(StringBuilder html, int pointer) { // pointer can be any place in the tag - isolates tag and sends back field type int open = html.substring(0, pointer).lastIndexOf("<"); int close = html.substring(pointer).indexOf(">") + pointer + 1; String tag = html.substring(open, close); log.debug("TAG ====" + tag); int start; // <input type="^text"..... int end; // <input type="text^".... if (tag.substring(1, 9).equalsIgnoreCase("textarea")) return "textarea"; if (tag.substring(1, 7).equalsIgnoreCase("select")) return "select"; log.debug("TAG PROCESS ====" + tag.substring(1, 9)); if ((start = tag.toLowerCase().indexOf(" type=")) >= 0) { start += 6; // account for type=... if (tag.charAt(start) == '\"') { // account for type="..." start += 1; end = tag.indexOf("\"", start); } else { int nextSpace = tag.indexOf(" ", start); int nextBracket = tag.indexOf(">", start); if (nextSpace < 0) end = nextBracket; else if ((nextBracket < 0) || (nextSpace < nextBracket)) end = nextSpace; else end = nextBracket; } return tag.substring(start, end).toLowerCase(); } return ""; } * */ private StringBuilder putValuesFromAP(DatabaseAP ap, String type, int pointer, StringBuilder html) { //prepare all sql & output String sql = ap.getApSQL(); String output = ap.getApOutput(); if (!EFormUtil.blank(sql)) { sql = replaceAllFields(sql); log.debug("SQL----" + sql); ArrayList<String> names = DatabaseAP.parserGetNames(output); // a list of ${apName} --> apName sql = DatabaseAP.parserClean(sql); // replaces all other ${apName} expressions with 'apName' if (ap.isJsonOutput()) { JSONArray values = EFormUtil.getJsonValues(names, sql); output = values.toString(); //in case of JsonOutput, return the whole JSONArray and let the javascript deal with it } else { ArrayList<String> values = EFormUtil.getValues(names, sql); if (values.size() != names.size()) { output = ""; } else { for (int i = 0; i < names.size(); i++) { output = DatabaseAP.parserReplace(names.get(i), values.get(i), output); } } } } //put values into according controls if (type.equals("textarea")) { pointer = html.indexOf(">", pointer) + 1; html.insert(pointer, output); } else if (type.equals("select")) { int selectEnd = StringBuilderUtils.indexOfIgnoreCase(html, "</select>", pointer); if (selectEnd >= 0) { int valueLoc = nextIndex(html, " value=" + output, " value=\"" + output, pointer); if (valueLoc < 0 || valueLoc > selectEnd) return html; pointer = nextSpot(html, valueLoc); html = html.insert(pointer, " selected"); } } else { String quote = output.contains("\"") ? "'" : "\""; html.insert(pointer, " value=" + quote + output + quote); } return (html); } public String replaceAllFields(String sql) { sql = DatabaseAP.parserReplace("demographic", demographicNo, sql); sql = DatabaseAP.parserReplace("provider", providerNo, sql); sql = DatabaseAP.parserReplace("appt_no", appointment_no, sql); sql = DatabaseAP.parserReplace(EFORM_DEMOGRAPHIC, getSqlParams(EFORM_DEMOGRAPHIC), sql); sql = DatabaseAP.parserReplace(REF_FID, getSqlParams(REF_FID), sql); sql = DatabaseAP.parserReplace(VAR_NAME, getSqlParams(VAR_NAME), sql); sql = DatabaseAP.parserReplace(VAR_VALUE, getSqlParams(VAR_VALUE), sql); sql = DatabaseAP.parserReplace(REF_VAR_NAME, getSqlParams(REF_VAR_NAME), sql); sql = DatabaseAP.parserReplace(REF_VAR_VALUE, getSqlParams(REF_VAR_VALUE), sql); sql = DatabaseAP.parserReplace(TABLE_NAME, getSqlParams(TABLE_NAME), sql); sql = DatabaseAP.parserReplace(TABLE_ID, getSqlParams(TABLE_ID), sql); sql = DatabaseAP.parserReplace(OTHER_KEY, getSqlParams(OTHER_KEY), sql); return sql; } private String getSqlParams(String key) { if (sql_params.containsKey(key)) { String val = sql_params.get(key); return val == null ? "" : StringEscapeUtils.escapeSql(val); } return ""; } private void setSqlParams(String key, String value) { if (sql_params.containsKey(key)) sql_params.remove(key); sql_params.put(key, value); } private String findValueInForm(String name) { // name format = {xxx} if (EFormUtil.blank(name) || !name.trim().startsWith("{") || !name.trim().endsWith("}")) return name; // extract content from brackets {} name = name.trim().substring(1, name.trim().length() - 1).toLowerCase(); if (EFormUtil.blank(name)) return ""; String value = fieldValues.get(name); return value == null ? "" : value; } private int getFieldIndex(StringBuilder html, int from) { if (html == null) return -1; Pattern p = Pattern.compile("<input|<select|<textarea|<div"); Matcher matcher = p.matcher(html); if (matcher.find(from)) { int start = matcher.start(); //org.oscarehr.util.MiscUtils.getLogger().info("New code shows: " + start); return start; } else { //org.oscarehr.util.MiscUtils.getLogger().info("New code shows: " + -1); return -1; } /* Code too slow, replaced with regex if (html == null) return -1; Integer[] index = new Integer[4]; index[0] = StringBuilderUtils.indexOfIgnoreCase(html, "<input", from); index[1] = StringBuilderUtils.indexOfIgnoreCase(html, "<select", from); index[2] = StringBuilderUtils.indexOfIgnoreCase(html, "<textarea", from); index[3] = StringBuilderUtils.indexOfIgnoreCase(html, "<div", from); ArrayList<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < index.length; i++) if (index[i] >= 0) list.add(index[i]); int min = list.isEmpty() ? -1 : list.get(0); for (int i = 1; i < list.size(); i++) min = min > list.get(i) ? list.get(i) : min; return min; */ } private String getFieldName(StringBuilder html, int pointer) { //pointer can be any place in the tag - isolates tag and sends back field type int open = html.substring(0, pointer).lastIndexOf("<"); int close = html.substring(pointer).indexOf(">") + pointer + 1; String tag = html.substring(open, close); log.debug("TAG ====" + tag); int start; //<input type="^text"..... int end; //<input type="text^".... if ((start = tag.toLowerCase().indexOf(" name=")) >= 0) { start += 6; if (tag.charAt(start) == '"') { start += 1; end = tag.indexOf('"', start); } else if (tag.charAt(start) == '\'') { start += 1; end = tag.indexOf('\'', start); } else { int nextSpace = tag.indexOf(" ", start); int nextBracket = tag.indexOf(">", start); if (nextSpace < 0) end = nextBracket; else if ((nextBracket < 0) || (nextSpace < nextBracket)) end = nextSpace; else end = nextBracket; } return tag.substring(start, end); } else { return ""; } } private String getFieldHeader(String html, int fieldIndex) { StringBuilder sb_html = new StringBuilder(html); return getFieldHeader(sb_html, fieldIndex); } private String getFieldHeader(StringBuilder html, int fieldIndex) { //fieldHeader: <input name=... type=... ... >, <select name=... ...>, etc. if (html == null || fieldIndex < 0) return ""; if (html.charAt(fieldIndex) != '<') return ""; // field header must be "<...>" // look for char '>' which is NOT inside quotes ("..." or '...') int end = fieldIndex; boolean quoteOpen = false, quote2Open = false; for (int i = fieldIndex + 1; i < html.length(); i++) { char c = html.charAt(i); if (c == '"' && !quoteOpen) quote2Open = !quote2Open; if (c == '\'' && !quote2Open) quoteOpen = !quoteOpen; if (!quoteOpen && !quote2Open && c == '>') { end = i + 1; break; } } return html.substring(fieldIndex, end); } private void saveFieldValue(StringBuilder html, int fieldIndex) { String header = getFieldHeader(html, fieldIndex); if (EFormUtil.blank(header)) return; String name = EFormUtil.removeQuotes(EFormUtil.getAttribute("name", header)); String value = EFormUtil.removeQuotes(EFormUtil.getAttribute("value", header)); if (EFormUtil.blank(name)) return; if (header.toLowerCase().startsWith("<input ")) { String type = EFormUtil.removeQuotes(EFormUtil.getAttribute("type", header)); if (EFormUtil.blank(type)) return; if (type.equalsIgnoreCase("radio")) { String checked = EFormUtil.removeQuotes(EFormUtil.getAttribute("checked", header)); if (EFormUtil.blank(checked) || !checked.equalsIgnoreCase("checked")) return; } } else if (header.toLowerCase().startsWith("<select ")) { String selects = html.substring(fieldIndex, html.indexOf("</select>", fieldIndex)); int pos = selects.indexOf("<option ", 0); while (pos >= 0) { String option = getFieldHeader(selects, pos); String selected = EFormUtil.removeQuotes(EFormUtil.getAttribute("selected", option)); if (!EFormUtil.blank(selected) && selected.equalsIgnoreCase("selected")) { value = EFormUtil.removeQuotes(EFormUtil.getAttribute("value", option)); break; } pos = selects.indexOf("<option ", pos + 1); } } else if (header.toLowerCase().startsWith("<textarea ")) { int fieldEnd = html.indexOf("</textarea>", fieldIndex); value = html.substring(fieldIndex + header.length(), fieldEnd).trim(); if (value.startsWith("\n")) value = value.substring(1); // remove 1st line break, UNIX style else if (value.startsWith("\r\n")) value = value.substring(2); // remove 1st line break, WINDOWS style } name = name.toLowerCase(); if (!EFormUtil.blank(value)) fieldValues.put(name, value); } private String getRefFid(String eform_name) { if (EFormUtil.blank(eform_name)) return fid; String refFid = EFormUtil.getEFormIdByName(eform_name); if (EFormUtil.blank(refFid)) refFid = fid; return refFid; } public void setSignatureCode(String contextPath, String userAgent, String demographicNo, String providerId) { String signatureRequestId = DigitalSignatureUtils.generateSignatureRequestId(providerId); String imageUrl = contextPath + "/imageRenderingServlet?source=" + ImageRenderingServlet.Source.signature_preview.name() + "&" + DigitalSignatureUtils.SIGNATURE_REQUEST_ID_KEY + "=" + signatureRequestId; String storedImgUrl = contextPath + "/imageRenderingServlet?source=" + ImageRenderingServlet.Source.signature_stored.name() + "&digitalSignatureId="; StringBuilder html = new StringBuilder(this.formHtml); int signatureLoc = StringBuilderUtils.indexOfIgnoreCase(html, signatureMarker, 0); if (signatureLoc > -1) { String browserType = ""; if (userAgent != null) { if (userAgent.toLowerCase().indexOf("ipad") > -1) { browserType = "IPAD"; } else { browserType = "ALL"; } } String signatureCode = "<script type='text/javascript' src='${oscar_javascript_path}../jquery/jquery-1.4.2.js'></script>" + "<script type='text/javascript' src='${oscar_javascript_path}signature.js'></script>" + "<script type='text/javascript'>\n" + "var _signatureRequestId = '" + signatureRequestId + "';\n" + "var _imageUrl = '" + imageUrl + "';\n" + "var _storedImgUrl = '" + storedImgUrl + "';\n" + "var _contextPath = '" + contextPath + "';\n" + "var _digitalSignatureRequestIdKey = '" + DigitalSignatureUtils.SIGNATURE_REQUEST_ID_KEY + "';\n" + "var _browserType = '" + browserType + "';\n" + "var _demographicNo = '" + demographicNo + "';\n" + "</script>"; html.replace(signatureLoc, signatureLoc + signatureMarker.length(), signatureCode); this.formHtml = html.toString(); } } }