diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/DataSet.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/DataSet.java new file mode 100644 index 000000000..ede4eea83 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/DataSet.java @@ -0,0 +1,72 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis; + +import com.opencsv.CSVWriter; +import lombok.Data; +import org.apache.commons.lang.StringUtils; + +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Data +public class DataSet { + + private String name; + private List columns = new ArrayList<>(); + private List> rows = new ArrayList<>(); + + public DataSet() {} + + @Override + public String toString() { + return name + " (" + columns.size() + " x " + rows.size() + ")"; + } + + public void setHeaderRow(String... values) { + columns = Arrays.asList(values); + } + + public void addDataRow(String... values) { + if (values == null || columns == null || values.length != columns.size()) { + throw new IllegalArgumentException("Values and columns must have same length"); + } + Map row = new LinkedHashMap<>(); + for (int i=0; i row : rows) { + String[] r = new String[columns.size()]; + for (int i = 0; i < columns.size(); i++) { + r[i] = row.get(columns.get(i)); + } + writer.writeNext(r); + } + } + } + } + + public void print(String separator) { + if (StringUtils.isNotBlank(name)) { + System.out.println(name); + } + System.out.println(String.join(separator, columns)); + for (Map row : rows) { + List values = new ArrayList<>(); + for (String c : columns) { + values.add(row.get(c)); + } + System.out.println(String.join(separator, values)); + } + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormAnalyzer.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormAnalyzer.java new file mode 100644 index 000000000..91dc11660 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormAnalyzer.java @@ -0,0 +1,163 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis; + +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.file.FileToStringConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag.FlattenObsGroupsConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag.FlattenOrExcludeIfModeConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag.MergeParentToChildrenConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag.MergeSectionToChildrenConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag.MergeSiblingsConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag.RemoveTagByNameConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml.ApplyMacrosConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml.ApplyRepeatsConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml.ApplyTranslationsConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml.StripCommentsConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml.TextConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml.XmlToTagConverter; +import org.openmrs.module.pihcore.htmlformentry.analysis.processor.TagProcessor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class HtmlFormAnalyzer { + + private final Logger log = LoggerFactory.getLogger(HtmlFormAnalyzer.class); + + public DataSet analyze(File fileOrDirectory, TagProcessor processor) throws Exception { + log.info("Analysis started for " + fileOrDirectory.getAbsolutePath() + " with processor: " + processor); + List tags = new ArrayList<>(); + if (fileOrDirectory.exists()) { + if (fileOrDirectory.isFile()) { + tags.add(convertFileToTag(fileOrDirectory)); + } + else if (fileOrDirectory.isDirectory()) { + for (File file : HtmlFormUtils.getNestedFilesBySuffix(fileOrDirectory, "xml")) { + try { + tags.add(convertFileToTag(file)); + } + catch (Exception e) { + log.error("Unable to convert file to tag at: " + file, e); + } + } + } + } + log.info("Successfully converted " + tags.size() + " forms to tags. Executing processor..."); + return processor.process(tags); + } + + public HtmlFormTag convertFileToTag(File formFile) { + try { + log.debug("Processing htmlform file: " + formFile.getAbsolutePath()); + String xml = new FileToStringConverter().convert(formFile); + for (Converter converter : getXmlConverters()) { + log.debug("Converting xml: " + converter); + xml = converter.convert(xml); + } + log.debug("Converting xml to tags"); + HtmlFormTag tag = new XmlToTagConverter().convert(xml); + for (Converter converter : getTagConverters()) { + log.debug("Converting tag: " + converter); + tag = converter.convert(tag); + } + tag.setHtmlFormFile(formFile); + return tag; + } + catch (Exception e) { + throw new IllegalArgumentException("Unable to load form from " + formFile.getName(), e); + } + } + + public List> getXmlConverters() { + List> l = new ArrayList<>(); + l.add(new StripCommentsConverter()); + l.add(new ApplyMacrosConverter()); + l.add(new ApplyRepeatsConverter()); + l.add(new ApplyTranslationsConverter()); + l.add(new TextConverter("(!$user.hasPrivilege('Task: emr.retroConsultNoteThisProviderOnly') and !$user.hasPrivilege('Task: emr.retroConsultNote')) or ($user.hasPrivilege('Task: emr.retroConsultNoteThisProviderOnly') and !$user.hasPrivilege('Task: emr.retroConsultNote') and $visit.open)", "retroCondition1")); + l.add(new TextConverter("$user.hasPrivilege('Task: emr.retroConsultNoteThisProviderOnly') and !($user.hasPrivilege('Task: emr.retroConsultNote')) and (!$visit.open)", "retroCondition2")); + l.add(new TextConverter("$user.hasPrivilege('Task: emr.retroConsultNote')", "retroCondition3")); + return l; + } + + public List> getTagConverters() { + List> l = new ArrayList<>(); + + // Remove any standard html tags + l.add(new RemoveTagByNameConverter("#comment")); + l.add(new RemoveTagByNameConverter("#text")); + l.add(new RemoveTagByNameConverter("a")); + l.add(new RemoveTagByNameConverter("b")); + l.add(new RemoveTagByNameConverter("br")); + l.add(new RemoveTagByNameConverter("button")); + l.add(new RemoveTagByNameConverter("center")); + l.add(new RemoveTagByNameConverter("dd")); + l.add(new RemoveTagByNameConverter("div")); + l.add(new RemoveTagByNameConverter("dl")); + l.add(new RemoveTagByNameConverter("dt")); + l.add(new RemoveTagByNameConverter("field")); + l.add(new RemoveTagByNameConverter("fieldset")); + l.add(new RemoveTagByNameConverter("font")); + l.add(new RemoveTagByNameConverter("h1")); + l.add(new RemoveTagByNameConverter("h2")); + l.add(new RemoveTagByNameConverter("h3")); + l.add(new RemoveTagByNameConverter("h4")); + l.add(new RemoveTagByNameConverter("h5")); + l.add(new RemoveTagByNameConverter("h6")); + l.add(new RemoveTagByNameConverter("h7")); + l.add(new RemoveTagByNameConverter("hr")); + l.add(new RemoveTagByNameConverter("i")); + l.add(new RemoveTagByNameConverter("img")); + l.add(new RemoveTagByNameConverter("input")); + l.add(new RemoveTagByNameConverter("label")); + l.add(new RemoveTagByNameConverter("legend")); + l.add(new RemoveTagByNameConverter("li")); + l.add(new RemoveTagByNameConverter("p")); + l.add(new RemoveTagByNameConverter("script")); + l.add(new RemoveTagByNameConverter("select")); + l.add(new RemoveTagByNameConverter("sl")); + l.add(new RemoveTagByNameConverter("small")); + l.add(new RemoveTagByNameConverter("span")); + l.add(new RemoveTagByNameConverter("strong")); + l.add(new RemoveTagByNameConverter("style")); + l.add(new RemoveTagByNameConverter("table")); + l.add(new RemoveTagByNameConverter("tbody")); + l.add(new RemoveTagByNameConverter("td")); + l.add(new RemoveTagByNameConverter("th")); + l.add(new RemoveTagByNameConverter("thead")); + l.add(new RemoveTagByNameConverter("tr")); + l.add(new RemoveTagByNameConverter("u")); + l.add(new RemoveTagByNameConverter("ul")); + + // Remove tags that do not impact the data model and cannot be easily used as context for other elements + l.add(new RemoveTagByNameConverter("uimessage")); + l.add(new RemoveTagByNameConverter("lookup")); + l.add(new RemoveTagByNameConverter("submit")); + + // Remove any sections of the form that are added *just* for view mode + l.add(new FlattenOrExcludeIfModeConverter()); + + // Flatten any includeIf or excludeIf expressions down into the child tags + l.add(new MergeParentToChildrenConverter("includeIf", " | ")); + l.add(new MergeParentToChildrenConverter("excludeIf", " | ")); + + // Handle the complex web of velocity conditions for entry of date/location/provider + l.add(new MergeSiblingsConverter("encounterDate")); + l.add(new MergeSiblingsConverter("encounterLocation")); + l.add(new MergeSiblingsConverter("encounterProviderAndRole")); + + // Merge obs groups attributes down into children, and add any hidden obs + l.add(new FlattenObsGroupsConverter()); + + // Flatten sections down into the child tags + l.add(new MergeSectionToChildrenConverter()); + + // Handle when/then tags + l.add(new MergeSiblingsConverter("when")); + l.add(new RemoveTagByNameConverter("controls")); + + return l; + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormTag.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormTag.java new file mode 100644 index 000000000..29630ccce --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormTag.java @@ -0,0 +1,83 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis; + +import lombok.Data; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A tag represents a specific xml node in a html form + */ +@Data +public class HtmlFormTag { + + private String name; + private final Map attributes = new HashMap<>(); + private String data; + private final List childTags = new ArrayList<>(); + private File htmlFormFile; + + public HtmlFormTag() { + } + + public HtmlFormTag cloneWithoutChildren() { + HtmlFormTag clone = new HtmlFormTag(); + clone.setName(name); + clone.setData(data); + for (String key : attributes.keySet()) { + clone.getAttributes().put(key, attributes.get(key)); + } + return clone; + } + + public String getAttributeValue(String name) { + return getAttributes().get(name); + } + + public void addAttribute(String name, String value) { + String existingValue = getAttributes().get(name); + if (existingValue != null && !existingValue.equals(value)) { + throw new IllegalStateException("Attribute with name " + name + " already exists in: " + this); + } + attributes.put(name, value); + } + + public void mergeAttributeRecursively(String name, String value, String separator) { + String existingValue = getAttributes().get(name); + if (existingValue != null && !existingValue.equals(value)) { + value = existingValue + separator + value; + } + attributes.put(name, value); + for (HtmlFormTag child : childTags) { + child.mergeAttributeRecursively(name, value, separator); + } + } + + public boolean hasAttribute(String name, String value) { + String v = attributes.get(name); + return v != null && v.equalsIgnoreCase(value); + } + + public boolean hasAttribute(String name) { + return attributes.containsKey(name); + } + + public List getAllTagsByName(String name) { + List ret = new ArrayList<>(); + if (getName().equalsIgnoreCase(name)) { + ret.add(this); + } + for (HtmlFormTag childTag : getChildTags()) { + ret.addAll(childTag.getAllTagsByName(name)); + } + return ret; + } + + @Override + public String toString() { + return getName() + getAttributes(); + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormUtils.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormUtils.java new file mode 100644 index 000000000..89f8f4f84 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormUtils.java @@ -0,0 +1,39 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * A tag represents a specific xml node in a html form + */ +public class HtmlFormUtils { + + public static List getNestedFilesBySuffix(File directory, String suffix) { + List files = new ArrayList<>(); + if (directory.exists() && directory.isDirectory()) { + File[] filesInDirectory = directory.listFiles(); + if (filesInDirectory != null) { + for (File f : filesInDirectory) { + if (f.isDirectory()) { + files.addAll(getNestedFilesBySuffix(f, suffix)); + } else { + if (f.getName().endsWith(suffix)) { + files.add(f); + } + } + } + } + } + return files; + } + + public static String mapToString(Map m, String keyValueSeparator, String entrySeparator) { + List ret = new ArrayList<>(); + for (String key : m.keySet()) { + ret.add(key + keyValueSeparator + m.get(key)); + } + return String.join(entrySeparator, ret); + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/Converter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/Converter.java new file mode 100644 index 000000000..0285008d5 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/Converter.java @@ -0,0 +1,5 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter; + +public interface Converter { + O convert(I input) throws Exception; +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/file/FileToStringConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/file/FileToStringConverter.java new file mode 100644 index 000000000..ff96632be --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/file/FileToStringConverter.java @@ -0,0 +1,14 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.file; + +import org.apache.commons.io.FileUtils; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +import java.io.File; +import java.nio.charset.StandardCharsets; + +public class FileToStringConverter implements Converter { + + public String convert(File input) throws Exception { + return FileUtils.readFileToString(input, StandardCharsets.UTF_8); + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/FlattenObsGroupsConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/FlattenObsGroupsConverter.java new file mode 100644 index 000000000..e642862e0 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/FlattenObsGroupsConverter.java @@ -0,0 +1,32 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag; + +import lombok.Data; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormTag; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +@Data +public class FlattenObsGroupsConverter implements Converter { + + @Override + public HtmlFormTag convert(HtmlFormTag input) throws Exception { + HtmlFormTag outputTag = input.cloneWithoutChildren(); + for (HtmlFormTag childTag : input.getChildTags()) { + childTag = convert(childTag); + if (childTag.getName().equalsIgnoreCase("obsGroup")) { + String hiddenConceptId = childTag.getAttributes().remove("hiddenConceptId"); + String hiddenAnswerConceptId = childTag.getAttributes().remove("hiddenAnswerConceptId"); + if (hiddenConceptId != null || hiddenAnswerConceptId != null) { + HtmlFormTag hiddenTag = new HtmlFormTag(); + hiddenTag.setName("obs"); + hiddenTag.getAttributes().put("hidden", "true"); + hiddenTag.getAttributes().put("conceptId", hiddenConceptId); + hiddenTag.getAttributes().put("answerConceptId", hiddenAnswerConceptId); + childTag.getChildTags().add(hiddenTag); + } + } + outputTag.getChildTags().add(childTag); + } + MergeParentToChildrenConverter parentToChildMerger = new MergeParentToChildrenConverter("obsGroup", " > "); + return parentToChildMerger.convert(outputTag); + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/FlattenOrExcludeIfModeConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/FlattenOrExcludeIfModeConverter.java new file mode 100644 index 000000000..52ccca922 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/FlattenOrExcludeIfModeConverter.java @@ -0,0 +1,29 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag; + +import lombok.Data; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormTag; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +@Data +public class FlattenOrExcludeIfModeConverter implements Converter { + + @Override + public HtmlFormTag convert(HtmlFormTag input) throws Exception { + HtmlFormTag outputTag = input.cloneWithoutChildren(); + for (HtmlFormTag childTag : input.getChildTags()) { + childTag = convert(childTag); + if (childTag.getName().equalsIgnoreCase("ifMode")) { + boolean viewMode = childTag.hasAttribute("mode", "view"); + boolean include = !childTag.hasAttribute("include", "false"); + boolean viewOnlyNode = (viewMode && include) || (!viewMode && !include); + if (!viewOnlyNode) { + outputTag.getChildTags().addAll(childTag.getChildTags()); + } + } + else { + outputTag.getChildTags().add(childTag); + } + } + return outputTag; + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/MergeParentToChildrenConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/MergeParentToChildrenConverter.java new file mode 100644 index 000000000..22f761fb3 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/MergeParentToChildrenConverter.java @@ -0,0 +1,41 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag; + +import lombok.Data; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormTag; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +import java.util.HashMap; +import java.util.Map; + +@Data +public class MergeParentToChildrenConverter implements Converter { + + private String tagName; + private String multiValueSeparator = " AND "; + + public MergeParentToChildrenConverter(String tagName, String multiValueSeparator) { + this.tagName = tagName; + this.multiValueSeparator = multiValueSeparator; + } + + @Override + public HtmlFormTag convert(HtmlFormTag input) throws Exception { + HtmlFormTag outputTag = input.cloneWithoutChildren(); + for (HtmlFormTag childTag : input.getChildTags()) { + if (input.getName().equalsIgnoreCase(tagName)) { + Map attributesToAdd = computeAttributesToMerge(new HashMap<>(input.getAttributes())); + for (Map.Entry attribute : attributesToAdd.entrySet()) { + childTag.mergeAttributeRecursively(attribute.getKey(), attribute.getValue(), multiValueSeparator); + } + } + childTag = convert(childTag); + outputTag.getChildTags().add(childTag); + } + outputTag = new RemoveTagByNameConverter(tagName).convert(outputTag); + return outputTag; + } + + public Map computeAttributesToMerge(Map inputAttributes) { + return inputAttributes; + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/MergeSectionToChildrenConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/MergeSectionToChildrenConverter.java new file mode 100644 index 000000000..93fe0ed68 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/MergeSectionToChildrenConverter.java @@ -0,0 +1,25 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag; + +import org.apache.commons.lang.StringUtils; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormUtils; + +import java.util.HashMap; +import java.util.Map; + +public class MergeSectionToChildrenConverter extends MergeParentToChildrenConverter { + + public MergeSectionToChildrenConverter() { + super("section", " > "); + } + + @Override + public Map computeAttributesToMerge(Map inputAttributes) { + String section = inputAttributes.get("headerCode"); + if (StringUtils.isBlank(section)) { + section = HtmlFormUtils.mapToString(inputAttributes, "=", ","); + } + Map ret = new HashMap<>(); + ret.put("section", section); + return ret; + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/MergeSiblingsConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/MergeSiblingsConverter.java new file mode 100644 index 000000000..36b0a8cbe --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/MergeSiblingsConverter.java @@ -0,0 +1,51 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag; + +import lombok.Data; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormTag; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +@Data +public class MergeSiblingsConverter implements Converter { + + private String tagName; + + public MergeSiblingsConverter(String tagName) { + this.tagName = tagName; + } + + @Override + public HtmlFormTag convert(HtmlFormTag input) throws Exception { + HtmlFormTag outputTag = input.cloneWithoutChildren(); + HtmlFormTag matchingTag = null; + for (HtmlFormTag childTag : input.getChildTags()) { + childTag = convert(childTag); + if (childTag.getName().equalsIgnoreCase(tagName)) { + if (!childTag.getChildTags().isEmpty()) { + throw new IllegalStateException("You cannot merge siblings that have children"); + } + if (matchingTag == null) { + matchingTag = childTag; + outputTag.getChildTags().add(matchingTag); + } + else { + Set attributes = new LinkedHashSet<>(matchingTag.getAttributes().keySet()); + attributes.addAll(childTag.getAttributes().keySet()); + for (String attribute : attributes) { + Set values = new HashSet<>(); + values.add(matchingTag.getAttributes().get(attribute)); + values.add(childTag.getAttributes().get(attribute)); + matchingTag.getAttributes().put(attribute, String.join(" || ", values)); + } + } + } + else { + outputTag.getChildTags().add(childTag); + } + } + return outputTag; + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/ObsConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/ObsConverter.java new file mode 100644 index 000000000..7862754f1 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/ObsConverter.java @@ -0,0 +1,21 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag; + +import lombok.Data; +import org.apache.commons.lang.StringUtils; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormTag; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +@Data +public class ObsConverter implements Converter { + + @Override + public HtmlFormTag convert(HtmlFormTag input) throws Exception { + // Any of these will effectively show the comment field, so update that if needed + if (!input.hasAttribute("showCommentField", "true")) { + if (input.hasAttribute("commentFieldLabel") || input.hasAttribute("commentFieldCode")) { + input.addAttribute("showCommentField", "true"); + } + } + return input; + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/RemoveTagByNameConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/RemoveTagByNameConverter.java new file mode 100644 index 000000000..32245b375 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/tag/RemoveTagByNameConverter.java @@ -0,0 +1,33 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.tag; + +import lombok.Data; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormTag; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +@Data +public class RemoveTagByNameConverter implements Converter { + + private String tagName; + private boolean removeChildren; + + public RemoveTagByNameConverter(String tagName) { + this.tagName = tagName; + } + + @Override + public HtmlFormTag convert(HtmlFormTag input) throws Exception { + HtmlFormTag outputTag = input.cloneWithoutChildren(); + for (HtmlFormTag childTag : input.getChildTags()) { + childTag = convert(childTag); + if (childTag.getName().equalsIgnoreCase(tagName)) { + if (!removeChildren) { + outputTag.getChildTags().addAll(childTag.getChildTags()); + } + } + else { + outputTag.getChildTags().add(childTag); + } + } + return outputTag; + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/ApplyMacrosConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/ApplyMacrosConverter.java new file mode 100644 index 000000000..8be4918c8 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/ApplyMacrosConverter.java @@ -0,0 +1,15 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml; + +import lombok.Data; +import org.openmrs.module.htmlformentry.HtmlFormEntryGenerator; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +@Data +public class ApplyMacrosConverter implements Converter { + + @Override + public String convert(String input) throws Exception { + HtmlFormEntryGenerator generator = new HtmlFormEntryGenerator(); + return generator.applyMacros(input); + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/ApplyRepeatsConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/ApplyRepeatsConverter.java new file mode 100644 index 000000000..6a1587d77 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/ApplyRepeatsConverter.java @@ -0,0 +1,15 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml; + +import lombok.Data; +import org.openmrs.module.htmlformentry.HtmlFormEntryGenerator; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +@Data +public class ApplyRepeatsConverter implements Converter { + + @Override + public String convert(String input) throws Exception { + HtmlFormEntryGenerator generator = new HtmlFormEntryGenerator(); + return generator.applyRepeats(input); + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/ApplyTranslationsConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/ApplyTranslationsConverter.java new file mode 100644 index 000000000..b62469b59 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/ApplyTranslationsConverter.java @@ -0,0 +1,28 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml; + +import lombok.Data; +import org.openmrs.module.htmlformentry.FormEntryContext; +import org.openmrs.module.htmlformentry.HtmlFormEntryGenerator; +import org.openmrs.module.htmlformentry.Translator; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +@Data +public class ApplyTranslationsConverter implements Converter { + + @Override + public String convert(String input) throws Exception { + HtmlFormEntryGenerator generator = new HtmlFormEntryGenerator(); + return generator.applyTranslations(input, new FormEntryContext(FormEntryContext.Mode.EDIT) { + @Override + public Translator getTranslator() { + return new Translator() { + @Override + public String translate(String localeStr, String key) { + String ret = getTranslations(localeStr).get(key); + return (ret == null ? key : ret); + } + }; + } + }); + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/StripCommentsConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/StripCommentsConverter.java new file mode 100644 index 000000000..d27437fb5 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/StripCommentsConverter.java @@ -0,0 +1,15 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml; + +import lombok.Data; +import org.openmrs.module.htmlformentry.HtmlFormEntryGenerator; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +@Data +public class StripCommentsConverter implements Converter { + + @Override + public String convert(String input) throws Exception { + HtmlFormEntryGenerator generator = new HtmlFormEntryGenerator(); + return generator.stripComments(input); + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/TextConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/TextConverter.java new file mode 100644 index 000000000..c939aa181 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/TextConverter.java @@ -0,0 +1,21 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml; + +import lombok.Data; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; + +@Data +public class TextConverter implements Converter { + + private String find; + private String replace; + + public TextConverter(String find, String replace) { + this.find = find; + this.replace = replace; + } + + @Override + public String convert(String input) throws Exception { + return input.replace(find, replace); + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/XmlToTagConverter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/XmlToTagConverter.java new file mode 100644 index 000000000..543147590 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/converter/xml/XmlToTagConverter.java @@ -0,0 +1,69 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.converter.xml; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.module.htmlformentry.HtmlFormEntryUtil; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormTag; +import org.openmrs.module.pihcore.htmlformentry.analysis.converter.Converter; +import org.w3c.dom.CharacterData; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.Stack; + +/** + * Loads and html form and parses it into tags + */ +public class XmlToTagConverter implements Converter { + + protected final Log log = LogFactory.getLog(getClass()); + + public static final String HTMLFORM_TAG_NAME = "htmlform"; + + private final Stack tagStack = new Stack<>(); + + public HtmlFormTag convert(String input) throws Exception { + Document document = HtmlFormEntryUtil.stringToDocument(input); + Node htmlFormNode = HtmlFormEntryUtil.findChild(document, HTMLFORM_TAG_NAME); + HtmlFormTag htmlFormTag = processNode(htmlFormNode); + if (!tagStack.isEmpty()) { + throw new IllegalStateException("Tag Stack is not empty after processing. Found: " + tagStack); + } + return htmlFormTag; + } + + protected HtmlFormTag processNode(Node node) { + HtmlFormTag tag = null; + if (node != null) { + tag = new HtmlFormTag(); + tag.setName(node.getNodeName()); + if (node instanceof CharacterData) { + CharacterData characterDataNode = (CharacterData) node; + tag.setData(characterDataNode.getData()); + } + NamedNodeMap attrs = node.getAttributes(); + if (attrs != null) { + for (int i = 0; i < attrs.getLength(); i++) { + Node attr = attrs.item(i); + tag.getAttributes().put(attr.getNodeName(), attr.getNodeValue()); + log.trace("tagAttribute: " + attr.getNodeName() + " = " + attr.getNodeValue()); + } + } + if (!tagStack.isEmpty()) { + tagStack.peek().getChildTags().add(tag); + } + log.trace("startTag: " + tag.getName()); + tagStack.push(tag); + NodeList childNodes = node.getChildNodes(); + for (int i=0; i tags) throws Exception { + Map> counters = new TreeMap<>(); + Stack stack = new Stack<>(); + for (HtmlFormTag tag : tags) { + process(tag, counters, stack); + } + DataSet dataSet = new DataSet(); + dataSet.setHeaderRow("counter", "key", "value"); + for (String counter : counters.keySet()) { + Map counterValues = counters.get(counter); + for (String key : counterValues.keySet()) { + Integer count = counterValues.get(key); + dataSet.addDataRow(counter, key, Integer.toString(count)); + } + } + return dataSet; + } + + private void process(HtmlFormTag inputTag, Map> counters, Stack stack) { + Map tagCounter = counters.computeIfAbsent("tags", k -> new TreeMap<>()); + tagCounter.put(inputTag.getName(), tagCounter.getOrDefault(inputTag.getName(), 0) + 1); + + List names = new ArrayList<>(); + for (HtmlFormTag tagInStack : stack) { + names.add(tagInStack.getName()); + } + names.add(inputTag.getName()); + String flatName = String.join(".", names); + Map flatTagCounter = counters.computeIfAbsent("flatTags", k -> new TreeMap<>()); + flatTagCounter.put(flatName, flatTagCounter.getOrDefault(flatName, 0) + 1); + + Map attributeCounter = counters.computeIfAbsent("attributes", k -> new TreeMap<>()); + for (String attributeName : inputTag.getAttributes().keySet()) { + String name = inputTag.getName() + "." + attributeName; + attributeCounter.put(name, attributeCounter.getOrDefault(name, 0) + 1); + } + + stack.push(inputTag); + for (HtmlFormTag childTag : inputTag.getChildTags()) { + process(childTag, counters, stack); + } + stack.pop(); + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/processor/TagExporter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/processor/TagExporter.java new file mode 100644 index 000000000..757f033a1 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/processor/TagExporter.java @@ -0,0 +1,107 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.processor; + +import lombok.Data; +import org.openmrs.module.pihcore.htmlformentry.analysis.DataSet; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormTag; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +@Data +public class TagExporter implements TagProcessor { + + private File outputDirectory; + + private final Logger log = LoggerFactory.getLogger(TagExporter.class); + + public static final List COLUMNS = Arrays.asList( + "section", "tagName", "style", "groupingConceptId", "conceptId", "conceptIds", "valueCoded", + "answerConceptId", "answerConceptIds", "answers", "answerConceptSetIds", "answerClasses", + "answerDrugs", "answerLocationTags", "labelCode", "labelText", "conceptLabels", + "answerCode", "answerLabel", "answerCodes", "answerLabels", "required", + "obsCommentUsed", "showCommentField", "commentFieldLabel", "commentFieldCode", + "dateLabel", "allowFutureDates", "showTime", "defaultValue", "whenValueThen", "toggle", "additionalAttributes" + ); + + public DataSet process(List tags) throws Exception { + DataSet ret = new DataSet(); + ret.setHeaderRow("inputFile", "outputFile"); + for (HtmlFormTag tag : tags) { + try { + if (outputDirectory == null) { + outputDirectory = tag.getHtmlFormFile().getParentFile(); + } + File outputFile = new File(outputDirectory, tag.getHtmlFormFile().getName() + ".csv"); + log.info("Processing tag " + tag + " into " + outputFile); + List columns = new ArrayList<>(getAllColumns(Collections.singletonList(tag))); + DataSet formDataSet = new DataSet(); + formDataSet.setColumns(columns); + formDataSet.setRows(getAllRows(columns, tag)); + formDataSet.toCsv(outputFile, ','); + ret.addDataRow(tag.getHtmlFormFile().getAbsolutePath(), outputFile.getAbsolutePath()); + } + catch (Exception e) { + log.error("Error exporting tag " + tag, e); + } + } + return ret; + } + + private Set getAllColumns(List tags) { + Set ret = new TreeSet<>(new ColumnComparator()); + ret.add("tagName"); + for (HtmlFormTag tag : tags) { + ret.addAll(tag.getAttributes().keySet()); + ret.addAll(getAllColumns(tag.getChildTags())); + } + return ret; + } + + private List> getAllRows(List columns, HtmlFormTag tag) { + List> rows = new ArrayList<>(); + Map row = new HashMap<>(); + Map attributes = new HashMap<>(tag.getAttributes()); + attributes.put("tagName", tag.getName()); + for (String column : columns) { + String value = attributes.remove(column); + row.put(column, value == null ? "" : value); + } + row.put("additionalAttributes", HtmlFormUtils.mapToString(attributes, "=", ",")); + rows.add(row); + for (HtmlFormTag childTag : tag.getChildTags()) { + rows.addAll(getAllRows(columns, childTag)); + } + return rows; + } + + private static class ColumnComparator implements Comparator { + + @Override + public int compare(String s1, String s2) { + int index1 = COLUMNS.indexOf(s1); + int index2 = COLUMNS.indexOf(s2); + if (index1 == -1 && index2 != -1) { + return 1; + } + if (index1 != -1 && index2 == -1) { + return -1; + } + int ret = index1 - index2; + if (ret == 0) { + ret = s1.compareTo(s2); + } + return ret; + } + } +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/processor/TagProcessor.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/processor/TagProcessor.java new file mode 100644 index 000000000..5843fb515 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/processor/TagProcessor.java @@ -0,0 +1,10 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.processor; + +import org.openmrs.module.pihcore.htmlformentry.analysis.DataSet; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormTag; + +import java.util.List; + +public interface TagProcessor { + DataSet process(List tags) throws Exception; +} diff --git a/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/processor/TagWriter.java b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/processor/TagWriter.java new file mode 100644 index 000000000..82ade4df1 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/pihcore/htmlformentry/analysis/processor/TagWriter.java @@ -0,0 +1,45 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis.processor; + +import lombok.Data; +import org.openmrs.module.pihcore.htmlformentry.analysis.DataSet; +import org.openmrs.module.pihcore.htmlformentry.analysis.HtmlFormTag; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.List; + +@Data +public class TagWriter implements TagProcessor { + + private File outputFile; + + private final Logger log = LoggerFactory.getLogger(TagWriter.class); + + public DataSet process(List tags) throws Exception { + DataSet ret = new DataSet(); + ret.setHeaderRow("inputFile", "outputData"); + for (HtmlFormTag tag : tags) { + try (StringWriter writer = new StringWriter()) { + write(tag, writer, " "); + String data = writer.toString(); + ret.addDataRow(tag.getHtmlFormFile().getName(), data); + } + } + return ret; + } + + public static void write(HtmlFormTag tag, Writer writer, String prefix) throws IOException { + write(tag, writer, "", prefix); + } + + private static void write(HtmlFormTag tag, Writer writer, String prefix, String prefixIncrement) throws IOException { + writer.write(prefix + tag + System.lineSeparator()); + for (HtmlFormTag childTag : tag.getChildTags()) { + write(childTag, writer, prefix + prefixIncrement, prefix); + } + } +} diff --git a/api/src/test/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormAnalyzerTest.java b/api/src/test/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormAnalyzerTest.java new file mode 100644 index 000000000..fd9052ea4 --- /dev/null +++ b/api/src/test/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormAnalyzerTest.java @@ -0,0 +1,58 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis; + +import org.junit.jupiter.api.Test; +import org.openmrs.module.pihcore.htmlformentry.analysis.processor.TagCounter; +import org.openmrs.module.pihcore.htmlformentry.analysis.processor.TagExporter; +import org.openmrs.module.pihcore.htmlformentry.analysis.processor.TagWriter; + +import java.io.File; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.util.Map; + +public class HtmlFormAnalyzerTest { + + public File getHtmlFormsDirectory() { + return new File("/home/mseaton/code/github/pih/openmrs-config-pihsl/target/openmrs-packager-config/configuration/pih/htmlforms"); + } + + @Test + public void generateCountsOfAllTags() throws Exception { + HtmlFormAnalyzer analyzer = new HtmlFormAnalyzer(); + DataSet dataSet = analyzer.analyze(getHtmlFormsDirectory(), new TagCounter()); + dataSet.toCsv(new File(getHtmlFormsDirectory(), "tagAnalysis.csv"), ','); + dataSet.print("\t"); + } + + @Test + public void generateCsvForForms() throws Exception { + HtmlFormAnalyzer analyzer = new HtmlFormAnalyzer(); + File htmlForm = new File(getHtmlFormsDirectory(), "mentalHealthFollowup.xml"); + DataSet dataSet = analyzer.analyze(htmlForm, new TagExporter()); + dataSet.print("\t"); + } + + @Test + public void writeFormData() throws Exception { + HtmlFormAnalyzer analyzer = new HtmlFormAnalyzer(); + DataSet dataSet = analyzer.analyze(getHtmlFormsDirectory(), new TagWriter()); + try (FileWriter writer = new FileWriter(new File(getHtmlFormsDirectory(), "tagAnalysis.txt"))) { + for (Map rows : dataSet.getRows()) { + writer.write(rows.get("inputFile") + System.lineSeparator()); + writer.write("=============================" + System.lineSeparator()); + writer.write(rows.get("outputData") + System.lineSeparator()); + } + } + } + + @Test + public void writeMentalHealthForm() throws Exception { + HtmlFormAnalyzer analyzer = new HtmlFormAnalyzer(); + DataSet dataSet = analyzer.analyze(new File(getHtmlFormsDirectory(), "admissionNote.xml"), new TagWriter()); + try (PrintWriter writer = new PrintWriter(System.out)) { + for (Map rows : dataSet.getRows()) { + writer.write(rows.get("outputData") + System.lineSeparator()); + } + } + } +} diff --git a/api/src/test/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormNonMemoryTest.java b/api/src/test/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormNonMemoryTest.java new file mode 100644 index 000000000..711616a7c --- /dev/null +++ b/api/src/test/java/org/openmrs/module/pihcore/htmlformentry/analysis/HtmlFormNonMemoryTest.java @@ -0,0 +1,102 @@ +package org.openmrs.module.pihcore.htmlformentry.analysis; + +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.Test; +import org.openmrs.EncounterType; +import org.openmrs.Form; +import org.openmrs.Patient; +import org.openmrs.api.context.Context; +import org.openmrs.module.htmlformentry.FormEntryContext; +import org.openmrs.module.htmlformentry.FormEntrySession; +import org.openmrs.module.htmlformentry.HtmlForm; +import org.openmrs.module.htmlformentry.HtmlFormEntryService; +import org.openmrs.module.htmlformentry.HtmlFormEntryUtil; +import org.openmrs.module.htmlformentry.handler.TagHandler; +import org.openmrs.test.SkipBaseSetup; +import org.openmrs.test.jupiter.BaseModuleContextSensitiveTest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.mock.web.MockHttpSession; + +import javax.servlet.http.HttpSession; +import java.io.File; +import java.io.FileInputStream; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; + +@SkipBaseSetup +public class HtmlFormNonMemoryTest extends BaseModuleContextSensitiveTest { + + Properties p = null; + private static final Logger log = LoggerFactory.getLogger(HtmlFormNonMemoryTest.class); + + public HtmlFormNonMemoryTest() { + super(); + p = getRuntimeProperties(); + } + + @Override + public Properties getRuntimeProperties() { + Properties props = new Properties(); + String serverId = System.getProperty("serverId"); + if (serverId != null) { + String path = System.getProperty("user.home") + File.separator + "openmrs" + File.separator + serverId + File.separator + "openmrs-runtime.properties"; + try (FileInputStream fis = new FileInputStream(path)) { + props.load(fis); + } catch (Exception e) { + System.out.println("Error loading properties from " + path + ": " + e.getMessage()); + } + if (!props.isEmpty()) { + System.setProperty("databaseUrl", props.getProperty("connection.url")); + System.setProperty("databaseUsername", props.getProperty("connection.username")); + System.setProperty("databasePassword", props.getProperty("connection.password")); + System.setProperty("databaseDriver", props.getProperty("connection.driver_class")); + System.setProperty("databaseDialect", "org.hibernate.dialect.MySQLDialect"); + System.setProperty("useInMemoryDatabase", "false"); + } + } + props = super.getRuntimeProperties(); + props.setProperty("junit.username", "admin"); + props.setProperty("junit.password", "Admin123"); + return props; + } + + @Test + public void execute() throws Exception { + authenticate(); + + Map tagHandlers = Context.getService(HtmlFormEntryService.class).getHandlers(); + Set nodeNames = new TreeSet<>(tagHandlers.keySet()); + for (String nodeName : nodeNames) { + System.out.println(nodeName); + } + } + + public static FormEntrySession getFormEntrySession(HtmlForm htmlForm) { + try { + Patient patient = HtmlFormEntryUtil.getFakePerson(); + HttpSession session = new MockHttpSession(); + session.setAttribute("emrContext.sessionLocationId", Context.getLocationService().getAllLocations().get(0)); + FormEntrySession s = new FormEntrySession(patient, null, FormEntryContext.Mode.ENTER, htmlForm, session); + s.getHtmlToDisplay(); + return s; + } + catch (Exception e) { + throw new IllegalStateException("Unable to get htmlform schema: ", e); + } + } + + public HtmlForm getHtmlFrom(String path) throws Exception { + HtmlForm htmlform = new HtmlForm(); + Form form = new Form(); + htmlform.setForm(form); + form.setEncounterType(new EncounterType()); + htmlform.setDateCreated(new Date()); + htmlform.setXmlData(FileUtils.readFileToString(new File(path), StandardCharsets.UTF_8)); + return htmlform; + } +} diff --git a/pom.xml b/pom.xml index 0cb7de4e4..076a82997 100644 --- a/pom.xml +++ b/pom.xml @@ -103,6 +103,7 @@ 2.0.7 2.45.0-SNAPSHOT + 1.18.26 1.20.1 UTF-8 @@ -738,6 +739,13 @@ provided + + org.projectlombok + lombok + ${lombokVersion} + provided + +