Skip to content

Commit

Permalink
Merge pull request #1 from opensrp/bugfixes_enhancements
Browse files Browse the repository at this point in the history
Bug Fixes and Enhancements - Version 2.1.0 release
  • Loading branch information
ndegwamartin authored Apr 26, 2023
2 parents 82e4547 + ff52bc6 commit c46912b
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 32 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ A command line utility to support FHIRCore content authoring. This tool supports

Download the latest release from https://github.com/opensrp/fhircore-tooling/releases

To run it as a java jar by using the command `java -jar efsity-2.0.0.jar -h` . This is the help command and will list the available options.
To run it as a java jar by using the command `java -jar efsity-2.1.0.jar -h` . This is the help command and will list the available options.

If you are using a linux environment e.g. bash you can choose to create an _alias_ for this as shown below. _(Remember to reload the terminal)_

`alias fct='java -jar ~/Downloads/efsity-2.0.0.jar'`
`alias fct='java -jar ~/Downloads/efsity-2.1.0.jar'`

To run the previous help command you can then run `fct -h` in your terminal.

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.smartregister</groupId>
<artifactId>fhircore-tooling</artifactId>
<version>2.0.0</version>
<version>2.1.0</version>

<properties>
<code.name>efsity</code.name>
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/smartregister/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
@Command(
name = "fct",
description = "FHIRCore tooling to make content authoring easier.",
version = "2.0.0",
version = "2.1.0",
mixinStandardHelpOptions = true,
subcommands = {
ConvertCommand.class,
StructureMapExtractResourcesCommand.class,
ValidateCommand.class
})
public class Main implements Runnable {
public static final String VERSION = "2.0.0";
public static final String VERSION = "2.1.0";

@CommandLine.Option(
names = {"-v"},
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/org/smartregister/util/FCTUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.io.FilenameUtils;
import org.smartregister.domain.FCTFile;

public class FCTUtils {
Expand Down Expand Up @@ -124,16 +126,19 @@ public static void printCompletedInDuration(long startTime) {
FCTUtils.getHumanDuration(System.currentTimeMillis() - startTime)));
}

public static Map<String, Map<String, String>> indexConfigurationFiles(String inputDirectoryPath)
throws IOException {
public static Map<String, Map<String, String>> indexConfigurationFiles(
String inputDirectoryPath, String... fileExtensions) throws IOException {
Map<String, Map<String, String>> filesMap = new HashMap<>();
Path rootDir = Paths.get(inputDirectoryPath);
Files.walkFileTree(
rootDir,
new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (!Files.isDirectory(file)) {
if (!Files.isDirectory(file)
&& (fileExtensions.length == 1 && fileExtensions[0] == "*"
|| Arrays.asList(fileExtensions)
.contains(FilenameUtils.getExtension(file.getFileName().toString())))) {

String parentDirKey =
file.getParent().equals(rootDir)
Expand Down
72 changes: 52 additions & 20 deletions src/main/java/org/smartregister/util/FCTValidationEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ public class FCTValidationEngine {

private JSONObject currentParamDataWorkflowJSONObject;
private JSONObject lastWorkflowJSONObject;
private JSONObject previousParentJSONObject;
private JSONObject parentJSONObject;
private String parentJSONObjectKey;
private String currentFile;
private int configurationFilesCount;
private Set<String> factMapKeys = new HashSet<>();

private Map<String, Set<String>> factMapKeysByFile = new HashMap<>();
private Map<String, String> fileConfigTypeIdentifierToFilenameMap = new HashMap<>();
private Map<String, Set<String>> questionnairesToLinkIds;
private Map<String, Set<String>> structureMapToLinkIds;
Expand All @@ -47,7 +47,6 @@ private void handleValue(String key, Object value, boolean isComposition) {
} else if (value instanceof JSONObject) {

parentJSONObjectKey = key;
previousParentJSONObject = parentJSONObject;
parentJSONObject = (JSONObject) value;

if (parentJSONObject != null && parentJSONObject.has(Constants.workflow))
Expand Down Expand Up @@ -121,22 +120,24 @@ private void handleValue(String key, Object value, boolean isComposition) {

if (value.toString().contains("data.put(")) {
String ruleFactKey = StringUtils.substringBetween(value.toString(), "'", "'");
factMapKeys.add(ruleFactKey);
Set<String> factsByFile = factMapKeysByFile.getOrDefault(currentFile, new HashSet<>());
factsByFile.add(ruleFactKey);
factMapKeysByFile.put(currentFile, factsByFile);
if (errorsMap.getOrDefault(currentFile, new HashMap<>()).containsKey(Constants.Rules))
errorsMap.get(currentFile).get(Constants.Rules).remove(ruleFactKey);
} else if (value.toString().contains("@{")) {
String ruleFactKey = StringUtils.substringBetween(value.toString(), "@{", "}");
if (!factMapKeys.contains(ruleFactKey)) {
if (!factMapKeysByFile
.getOrDefault(currentFile, new HashSet<>())
.contains(ruleFactKey)) {
addToErrorMap(Constants.Rules, ruleFactKey);
}
}

if (Constants.PARAMDATA.equals(value)) {

if (previousParentJSONObject != null
&& previousParentJSONObject.has(Constants.workflow))
currentParamDataWorkflowJSONObject = previousParentJSONObject;
if (Constants.workflow.equals(key))
currentParamDataWorkflowJSONObject = lastWorkflowJSONObject;

if (Constants.PARAMDATA.equals(value)) {
String configFileIdentifier =
currentParamDataWorkflowJSONObject.getString(Constants.ID);

Expand All @@ -150,8 +151,13 @@ private void handleValue(String key, Object value, boolean isComposition) {

// Add to fact-map for this file
if (currentFile.equals(
fileConfigTypeIdentifierToFilenameMap.getOrDefault(configFileIdentifier, null)))
factMapKeys.add(parentJSONObject.getString(Constants.KEY));
fileConfigTypeIdentifierToFilenameMap.getOrDefault(configFileIdentifier, null))) {

Set<String> factsByFile =
factMapKeysByFile.getOrDefault(currentFile, new HashSet<>());
factsByFile.add(parentJSONObject.getString(Constants.KEY));
factMapKeysByFile.put(currentFile, factsByFile);
}
}

//
Expand Down Expand Up @@ -190,7 +196,8 @@ private void handleValue(String key, Object value, boolean isComposition) {
questionnaireId));
}

if (structureMapToLinkIds.containsKey(structureMapId)
if (structureMapId != null
&& structureMapToLinkIds.containsKey(structureMapId)
&& !structureMapToLinkIds.get(structureMapId).contains(fieldLinkId)) {
addToErrorMap(
"Prepopulate",
Expand Down Expand Up @@ -281,7 +288,7 @@ public void process(

long startTime = System.currentTimeMillis();
Map<String, Map<String, String>> configDirIndexMap =
FCTUtils.indexConfigurationFiles(directoryPath);
FCTUtils.indexConfigurationFiles(directoryPath, "*");

if (questionnairesFolderPath != null) {

Expand All @@ -296,7 +303,7 @@ public void process(
structureMapToLinkIds = new StructureMapProcessor(structureMapsFolderPath).process();

FCTUtils.printNewLine();
FCTUtils.printInfo("\u001b[36mPRE PARSING VALIDATION\u001b[0m");
FCTUtils.printInfo("\u001b[36mPreparsing validation\u001b[0m");

// Validate all Structure Map Link ids should be in questionnaire
for (var entry : structureMapToLinkIds.entrySet()) {
Expand All @@ -323,11 +330,31 @@ public void process(
} else {
FCTUtils.printError(
String.format(
"No Questionnaire found for Structure Map with id \u001b[36m%s\u001b[0m",
"No Questionnaire resource was found for the Structure Map with id \u001b[36m%s\u001b[0m",
structureMapId));
}
}

// Validate all Structure Map IDs referenced in Questionnaire extensions exist as Structure
// Maps(files)

for (var entry : questionnaireToStructureMapId.entrySet()) {

String questionnaireId = entry.getKey();
String structureMapId = entry.getValue().stream().findFirst().orElse("");

if (!structureMapId.isBlank() && !structureMapToLinkIds.containsKey(structureMapId)) {

FCTUtils.printError(
String.format(
"No Structure Map with id \u001b[36m%s\u001b[0m was found. Defining Questionnaire has id \u001b[36m%s\u001b[0m",
structureMapId, questionnaireId));
}
}
}

FCTUtils.printInfo("\u001b[36mPreparsing validation complete\u001b[0m");

// Load Composition
currentFile = compositionPath;
FCTFile compositionFile = FCTUtils.readFile(compositionPath);
Expand Down Expand Up @@ -365,9 +392,15 @@ public void process(
}
}
}

FCTUtils.printToConsole(String.format("%d translation files found", translationsMap.size()));
FCTUtils.printToConsole(String.format("%d configuration files found", configurationFilesCount));
FCTUtils.printNewLine();
FCTUtils.printToConsole(
String.format(
"%d translation file" + (translationsMap.size() > 1 ? "s" : "") + " found",
translationsMap.size()));
FCTUtils.printToConsole(
String.format(
"%d configuration file" + (configurationFilesCount > 1 ? "s" : "") + " found",
configurationFilesCount));
printValidationResults();

FCTUtils.printNewLine();
Expand All @@ -387,7 +420,6 @@ private String getQuestionnaireIdByStructureMapId(String structureMapId) {

private void resetStatePerFile() {
currentFile = null;
factMapKeys.clear();
}

private void printValidationResults() {
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/org/smartregister/util/QuestionnaireProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public Map<String, Map<String, Set<String>>> process() {
try {

Map<String, Map<String, String>> folderTofilesIndexMap =
FCTUtils.indexConfigurationFiles(directoryPath);
FCTUtils.indexConfigurationFiles(directoryPath, "json");

// Process other configurations
for (var entry : folderTofilesIndexMap.entrySet()) {
Expand Down Expand Up @@ -69,7 +69,7 @@ public Map<String, Map<String, Set<String>>> process() {
} catch (JSONException jsonException) {

FCTUtils.printError(String.format("Error processing file %s", currentFile));
FCTUtils.printError(String.format("Error message %s", jsonException.getMessage()));
printJsonExceptionMessages(jsonException.getMessage());
}
}
}
Expand All @@ -82,6 +82,15 @@ public Map<String, Map<String, Set<String>>> process() {
return resultsMap;
}

private void printJsonExceptionMessages(String message) {
if (message.contains("JSONObject[\"id\"] not found")) {
FCTUtils.printWarning(
"Questionnaire DOES NOT have an id field. Are we expecting it to be generated on the Server?");
} else {
FCTUtils.printError(String.format("%s", message));
}
}

private String getStructureMapId(JSONArray extensionJSONArray) {

for (int i = 0; i < extensionJSONArray.length(); i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public Map<String, Set<String>> process() {
try {

Map<String, Map<String, String>> folderTofilesIndexMap =
FCTUtils.indexConfigurationFiles(directoryPath);
FCTUtils.indexConfigurationFiles(directoryPath, "map", "txt");

// Process other configurations
for (var entry : folderTofilesIndexMap.entrySet()) {
Expand Down Expand Up @@ -82,7 +82,8 @@ public Map<String, Set<String>> process() {
}
}

structureMapToLinkIds.put(getStructureMapId(firstLine), linkIds);
if (!firstLine.isBlank())
structureMapToLinkIds.put(getStructureMapId(firstLine), linkIds);
}
}

Expand Down

0 comments on commit c46912b

Please sign in to comment.