diff --git a/README.md b/README.md index 16689ea6..86a3c918 100644 --- a/README.md +++ b/README.md @@ -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 use the command `java -jar efsity-1.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.0.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-1.0.0.jar'` +`alias fct='java -jar ~/Downloads/efsity-2.0.0.jar'` To run the previous help command you can then run `fct -h` in your terminal. @@ -60,7 +60,12 @@ The above will output a list of errors and warnings based on any configuration r -c or --composition - the composition json file of the project -i or --input - the input directory path. This should point to the folder with the app configurations e.g. ~/Workspace/fhir-resources/ecbis_cha_preview/ -o or --output - the output path, can be a file or directory. Optional - default is current directory +-sm or --structure-maps - (Optional) the directory path to the location of structure map .txt or .map files. Must be a directory. Must be used with the -q flag +-q or --questionnaires - (Optional) the directory path to the location of questionnaires .json files. Must be a directory. Must be used with the -sm flag ``` + +**Note:** To include _Questionnaire_ and _Structure Map_ validation add the `-sm` and `-q` flags + **Sample screenshot output**
Screenshot 2023-03-27 at 21 43 09 diff --git a/pom.xml b/pom.xml index 711df400..fe018c0f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.smartregister fhircore-tooling - 1.0.0 + 2.0.0 efsity @@ -118,22 +118,48 @@ org.opencds.cqf.cql evaluator - ${opencds.cql.version} + ${cql.version} + + + ca.uhn.hapi.fhir + org.hl7.fhir.r5 + + + ca.uhn.hapi.fhir + org.hl7.fhir.dstu2 + + + ca.uhn.hapi.fhir + org.hl7.fhir.dstu3 + + + ca.uhn.hapi.fhir + org.hl7.fhir.dstu2016may + + + ca.uhn.hapi.fhir + hapi-fhir-structures-dstu3 + + + ca.uhn.hapi.fhir + hapi-fhir-structures-r5 + + org.opencds.cqf.cql evaluator.builder - ${opencds.cql.version} + ${cql.version} org.opencds.cqf.cql evaluator.dagger - ${opencds.cql.version} + ${cql.version} org.opencds.cqf.cql evaluator.plandefinition - ${opencds.cql.version} + ${cql.version} @@ -291,19 +317,29 @@ - org.apache.maven.plugins - maven-jar-plugin - ${maven.jar.plugin.version} - - - - true - libs/ - org.smartregister.Main - - - + maven-assembly-plugin + + + + single + + package + + + + org.smartregister.Main + + + + src/main/resources/dependency-set.xml + + + jar-with-dependencies + + + + diff --git a/src/main/java/org/smartregister/Main.java b/src/main/java/org/smartregister/Main.java index 091690dd..f5e5ca87 100644 --- a/src/main/java/org/smartregister/Main.java +++ b/src/main/java/org/smartregister/Main.java @@ -11,7 +11,7 @@ @Command( name = "fct", description = "FHIRCore tooling to make content authoring easier.", - version = "1.0.0", + version = "2.0.0", mixinStandardHelpOptions = true, subcommands = { ConvertCommand.class, @@ -19,7 +19,7 @@ ValidateCommand.class }) public class Main implements Runnable { - public static final String VERSION = "1.0.0"; + public static final String VERSION = "2.0.0"; @CommandLine.Option( names = {"-v"}, diff --git a/src/main/java/org/smartregister/command/ValidateCommand.java b/src/main/java/org/smartregister/command/ValidateCommand.java index 5ea01d0e..36026175 100644 --- a/src/main/java/org/smartregister/command/ValidateCommand.java +++ b/src/main/java/org/smartregister/command/ValidateCommand.java @@ -24,17 +24,53 @@ public class ValidateCommand implements Runnable { required = true) private String compositionFilePath; + @CommandLine.Option( + names = {"-sm", "--structure-maps"}, + description = + "directory path to the location of structure map .txt or .map files. Must be a directory. Must be used with the -q flag", + required = false) + private String structureMapsFolderPath; + + @CommandLine.Option( + names = {"-q", "--questionnaires"}, + description = + "directory path to the location of questionnaires .json files. Must be a directory. Must be used with the -sm flag", + required = false) + private String questionnairesFolderPath; + @Override public void run() { if (!Files.isDirectory(Paths.get(inputFolder))) { - throw new RuntimeException("path needs to be a directory"); + throw new RuntimeException("-i, --input configs input path needs to be a directory"); + } + + if (structureMapsFolderPath != null && questionnairesFolderPath == null) { + + throw new RuntimeException( + "You have supplied a -sm, --structure-maps flag without a corresponding -q, --questionnaires flag"); + + } else if (structureMapsFolderPath == null && questionnairesFolderPath != null) { + throw new RuntimeException( + "You have supplied a -q, --questionnaires flag without a corresponding -sm, --structure-maps flag"); + } + + if (structureMapsFolderPath != null) { + + if (!Files.isDirectory(Paths.get(structureMapsFolderPath))) { + throw new RuntimeException("-sm, --structure-maps path needs to be a directory"); + } + + if (!Files.isDirectory(Paths.get(questionnairesFolderPath))) { + throw new RuntimeException("-q, --questionnaires path needs to be a directory"); + } } try { FCTValidationEngine FCTValidationEngine = new FCTValidationEngine(); - FCTValidationEngine.process(compositionFilePath, inputFolder); + FCTValidationEngine.process( + compositionFilePath, structureMapsFolderPath, questionnairesFolderPath, inputFolder); } catch (IOException e) { logger.severe(e.getMessage()); diff --git a/src/main/java/org/smartregister/util/FCTUtils.java b/src/main/java/org/smartregister/util/FCTUtils.java index f062dfbd..34d2723f 100644 --- a/src/main/java/org/smartregister/util/FCTUtils.java +++ b/src/main/java/org/smartregister/util/FCTUtils.java @@ -12,9 +12,10 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import org.smartregister.domain.FCTFile; @@ -123,6 +124,31 @@ public static void printCompletedInDuration(long startTime) { FCTUtils.getHumanDuration(System.currentTimeMillis() - startTime))); } + public static Map> indexConfigurationFiles(String inputDirectoryPath) + throws IOException { + Map> 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)) { + + String parentDirKey = + file.getParent().equals(rootDir) + ? FCTValidationEngine.Constants.ROOT + : file.getParent().getFileName().toString(); + Map fileList = filesMap.getOrDefault(parentDirKey, new HashMap<>()); + fileList.put(file.getFileName().toString(), file.toAbsolutePath().toString()); + filesMap.put(parentDirKey, fileList); + } + return FileVisitResult.CONTINUE; + } + }); + return filesMap; + } + public static final class Constants { public static final String HL7_FHIR_PACKAGE = "hl7.fhir.r4.core"; public static final String HL7_FHIR_PACKAGE_VERSION = "4.0.1"; diff --git a/src/main/java/org/smartregister/util/FCTValidationEngine.java b/src/main/java/org/smartregister/util/FCTValidationEngine.java index d415293a..7ee9138c 100644 --- a/src/main/java/org/smartregister/util/FCTValidationEngine.java +++ b/src/main/java/org/smartregister/util/FCTValidationEngine.java @@ -3,12 +3,7 @@ import com.google.common.collect.ImmutableSet; import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -29,6 +24,7 @@ public class FCTValidationEngine { private Map>> errorsMap = new HashMap<>(); private JSONObject currentParamDataWorkflowJSONObject; + private JSONObject lastWorkflowJSONObject; private JSONObject previousParentJSONObject; private JSONObject parentJSONObject; private String parentJSONObjectKey; @@ -36,6 +32,9 @@ public class FCTValidationEngine { private int configurationFilesCount; private Set factMapKeys = new HashSet<>(); private Map fileConfigTypeIdentifierToFilenameMap = new HashMap<>(); + private Map> questionnairesToLinkIds; + private Map> structureMapToLinkIds; + private Map> questionnaireToStructureMapId; private void handleValue(String key, Object value, boolean isComposition) { if (value instanceof JSONArray) { @@ -51,6 +50,9 @@ private void handleValue(String key, Object value, boolean isComposition) { previousParentJSONObject = parentJSONObject; parentJSONObject = (JSONObject) value; + if (parentJSONObject != null && parentJSONObject.has(Constants.workflow)) + lastWorkflowJSONObject = parentJSONObject; + handleJSONObject((JSONObject) value, isComposition); } else { @@ -151,6 +153,61 @@ private void handleValue(String key, Object value, boolean isComposition) { fileConfigTypeIdentifierToFilenameMap.getOrDefault(configFileIdentifier, null))) factMapKeys.add(parentJSONObject.getString(Constants.KEY)); } + + // + if (questionnairesToLinkIds != null && Constants.PREPOPULATE.equals(value.toString())) { + + // All Pre-populate ids should be in questionnaire + String questionnaireId = + lastWorkflowJSONObject + .getJSONObject(Constants.questionnaire) + .getString(Constants.ID); + + String fieldLinkId = parentJSONObject.getString(Constants.linkId); + + if (questionnairesToLinkIds.containsKey(questionnaireId) + && !questionnairesToLinkIds.get(questionnaireId).contains(fieldLinkId)) { + addToErrorMap( + "Prepopulate", + String.format( + "\u001b[34mPREP\u001b[0m :: link id \u001b[36m%s\u001b[0m missing in Questionnaire with id \u001b[36m%s\u001b[0m", + fieldLinkId, questionnaireId)); + } + + // All Pre-populate ids should be in Structure map + String structureMapId = + questionnaireToStructureMapId.containsKey(questionnaireId) + && questionnaireToStructureMapId.get(questionnaireId).iterator().hasNext() + ? questionnaireToStructureMapId.get(questionnaireId).iterator().next() + : null; + + if (structureMapId == null && !questionnaireId.contains("{")) { + // Executes multiple times (per pre-populate) - consider move to process() function? + addToErrorMap( + "Questionnaire", + String.format( + "\u001b[31mSMAP\u001b[0m :: Structure Map missing for Questionnaire with id \u001b[36m%s\u001b[0m", + questionnaireId)); + } + + if (structureMapToLinkIds.containsKey(structureMapId) + && !structureMapToLinkIds.get(structureMapId).contains(fieldLinkId)) { + addToErrorMap( + "Prepopulate", + String.format( + "\u001b[34mPREP\u001b[0m :: link id \u001b[36m%s\u001b[0m missing in Structure Map with id \u001b[36m%s\u001b[0m", + fieldLinkId, structureMapId)); + } else if (structureMapId != null + && !structureMapToLinkIds.containsKey(structureMapId) + && !questionnaireId.contains("{")) { + // Executes multiple times (per pre-populate) - consider move to process() function? + addToErrorMap( + "Questionnaire", + String.format( + "\u001b[31mSMAP\u001b[0m :: Structure Map with id \u001b[36m%s\u001b[0m missing for Questionnaire with id \u001b[36m%s\u001b[0m", + structureMapId, questionnaireId)); + } + } } } } @@ -214,37 +271,63 @@ private void handleJSONArray(String key, JSONArray jsonArray, boolean isComposit jsonArrayIterator.forEachRemaining(element -> handleValue(key, element, isComposition)); } - private Map> indexConfigurationFiles(String inputDirectoryPath) + public void process( + String compositionPath, + String structureMapsFolderPath, + String questionnairesFolderPath, + String directoryPath) throws IOException { - Map> 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)) { - - String parentDirKey = - file.getParent().equals(rootDir) - ? FCTValidationEngine.Constants.ROOT - : file.getParent().getFileName().toString(); - Map fileList = filesMap.getOrDefault(parentDirKey, new HashMap<>()); - fileList.put(file.getFileName().toString(), file.toAbsolutePath().toString()); - filesMap.put(parentDirKey, fileList); - } - return FileVisitResult.CONTINUE; - } - }); - return filesMap; - } - - public void process(String compositionPath, String directoryPath) throws IOException { FCTUtils.printToConsole("Processing starting... \uD83D\uDE80"); long startTime = System.currentTimeMillis(); - Map> configDirIndexMap = indexConfigurationFiles(directoryPath); + Map> configDirIndexMap = + FCTUtils.indexConfigurationFiles(directoryPath); + if (questionnairesFolderPath != null) { + + FCTUtils.printInfo("\u001b[36mRunning preprocessor...\u001b[0m"); + + Map>> questionnaireProcessorResults = + new QuestionnaireProcessor(questionnairesFolderPath).process(); + questionnairesToLinkIds = + questionnaireProcessorResults.getOrDefault(Constants.questionnaire, new HashMap<>()); + questionnaireToStructureMapId = + questionnaireProcessorResults.getOrDefault(Constants.structuremap, new HashMap<>()); + structureMapToLinkIds = new StructureMapProcessor(structureMapsFolderPath).process(); + + FCTUtils.printNewLine(); + FCTUtils.printInfo("\u001b[36mPRE PARSING VALIDATION\u001b[0m"); + + // Validate all Structure Map Link ids should be in questionnaire + for (var entry : structureMapToLinkIds.entrySet()) { + + String structureMapId = entry.getKey(); + String questionnaireID = getQuestionnaireIdByStructureMapId(structureMapId); + + if (questionnaireID != null) { + + Iterator iterator = entry.getValue().iterator(); + while (iterator.hasNext()) { + + String structureMapLinkId = iterator.next(); + + if (!questionnairesToLinkIds.get(questionnaireID).contains(structureMapLinkId)) { + + FCTUtils.printError( + String.format( + "No Structure Map link id \u001b[36m%s\u001b[0m found in Questionnaire with id \u001b[36m%s\u001b[0m", + structureMapLinkId, structureMapId)); + } + } + + } else { + FCTUtils.printError( + String.format( + "No Questionnaire found for Structure Map with id \u001b[36m%s\u001b[0m", + structureMapId)); + } + } + } // Load Composition currentFile = compositionPath; FCTFile compositionFile = FCTUtils.readFile(compositionPath); @@ -277,7 +360,8 @@ public void process(String compositionPath, String directoryPath) throws IOExcep fileJSONObject, Paths.get(compositionPath).equals(Paths.get(nestedEntry.getValue()))); } else { - FCTUtils.printWarning("Unrecognized Config File Format"); + FCTUtils.printWarning( + String.format("Unrecognized Config File Format for file %s", nestedEntry.getKey())); } } } @@ -290,6 +374,17 @@ public void process(String compositionPath, String directoryPath) throws IOExcep FCTUtils.printCompletedInDuration(startTime); } + private String getQuestionnaireIdByStructureMapId(String structureMapId) { + + for (var entry : questionnaireToStructureMapId.entrySet()) { + String questionnaireId = entry.getKey(); + + if (entry.getValue().contains(structureMapId)) return questionnaireId; + } + + return null; + } + private void resetStatePerFile() { currentFile = null; factMapKeys.clear(); @@ -339,7 +434,8 @@ private void printValidationResults() { StringBuilder errorMessageBuilder = new StringBuilder( String.format( - "%d out of %d files with errors", errorsMap.size(), configurationFilesCount)) + "%d out of %d configuration files with errors", + errorsMap.size(), configurationFilesCount)) .append("\n\n\u001b[32mVALIDATION SUMMARY\u001b[0m \n----------------"); for (var entry : errorsMapCount.entrySet()) { @@ -373,6 +469,9 @@ public static final class Constants { public static final String PARAMDATA = "PARAMDATA"; public static final String workflow = "workflow"; public static final String KEY = "key"; + public static final String linkId = "linkId"; + public static final String structuremap = "structuremap"; + public static final String PREPOPULATE = "PREPOPULATE"; public static final Set translatables = ImmutableSet.of( "saveButtonText", "title", "display", "actionButtonText", "message"); // , "description" diff --git a/src/main/java/org/smartregister/util/QuestionnaireProcessor.java b/src/main/java/org/smartregister/util/QuestionnaireProcessor.java new file mode 100644 index 00000000..fec73a1e --- /dev/null +++ b/src/main/java/org/smartregister/util/QuestionnaireProcessor.java @@ -0,0 +1,145 @@ +/* (C)2023 */ +package org.smartregister.util; + +import com.google.common.collect.Sets; +import java.io.IOException; +import java.util.*; +import org.apache.commons.lang3.StringUtils; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.smartregister.domain.FCTFile; + +public class QuestionnaireProcessor { + private String directoryPath; + private String currentFile; + private String currentQuestionnaireId; + + private String currentStructureMapId; + + private Map> questionnairesToLinkIds = new HashMap<>(); + private Map> questionnairesToStructureMapIds = new HashMap<>(); + + private Map>> resultsMap = new HashMap<>(); + + public QuestionnaireProcessor(String folderPath) { + this.directoryPath = folderPath; + } + + public Map>> process() { + + try { + + Map> folderTofilesIndexMap = + FCTUtils.indexConfigurationFiles(directoryPath); + + // Process other configurations + for (var entry : folderTofilesIndexMap.entrySet()) { + + Map fileIndexMap = folderTofilesIndexMap.get(entry.getKey()); + + for (var nestedEntry : fileIndexMap.entrySet()) { + + currentFile = nestedEntry.getValue(); + + if (nestedEntry.getKey().startsWith(".")) continue; + + FCTFile file = FCTUtils.readFile(nestedEntry.getValue()); + + try { + + JSONObject questionnaireJSONObject = new JSONObject(file.getContent()); + currentQuestionnaireId = + questionnaireJSONObject.getString(FCTValidationEngine.Constants.ID); + currentStructureMapId = + questionnaireJSONObject.has("extension") + ? getStructureMapId(questionnaireJSONObject.getJSONArray("extension")) + : null; + + questionnairesToStructureMapIds.put( + currentQuestionnaireId, + currentStructureMapId != null + ? Sets.newHashSet(currentStructureMapId) + : Sets.newHashSet()); + resultsMap.put( + FCTValidationEngine.Constants.structuremap, questionnairesToStructureMapIds); + + handleJSONObject(questionnaireJSONObject, true); + + } catch (JSONException jsonException) { + + FCTUtils.printError(String.format("Error processing file %s", currentFile)); + FCTUtils.printError(String.format("Error message %s", jsonException.getMessage())); + } + } + } + + } catch (IOException ioException) { + ioException.toString(); + } + + resultsMap.put(FCTValidationEngine.Constants.questionnaire, questionnairesToLinkIds); + return resultsMap; + } + + private String getStructureMapId(JSONArray extensionJSONArray) { + + for (int i = 0; i < extensionJSONArray.length(); i++) { + + if ("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-targetStructureMap" + .equals(extensionJSONArray.getJSONObject(i).getString("url"))) { + + if (extensionJSONArray.getJSONObject(i).has("valueCanonical")) { + return StringUtils.substringAfterLast( + extensionJSONArray.getJSONObject(i).optString("valueCanonical").trim(), "/"); + } else if (extensionJSONArray.getJSONObject(i).has("valueReference")) { + + JSONObject valueReferenceJSONObject = + extensionJSONArray.getJSONObject(i).getJSONObject("valueReference"); + return StringUtils.substringAfterLast( + valueReferenceJSONObject.optString("reference").trim(), "/"); + } else { + + FCTUtils.printError("Structure Map value format not supported"); + } + } + } + + return null; + } + + private void handleValue(String key, Object value, boolean isComposition) { + if (value instanceof JSONArray) { + + handleJSONArray(key, (JSONArray) value, isComposition); + + } else if (value instanceof JSONObject) { + + handleJSONObject((JSONObject) value, isComposition); + + } else { + + if (FCTValidationEngine.Constants.linkId.equals(key)) { + + Set results = + questionnairesToLinkIds.getOrDefault(currentQuestionnaireId, new HashSet<>()); + results.add(value.toString()); + questionnairesToLinkIds.put(currentQuestionnaireId, results); + } + } + } + + private void handleJSONObject(JSONObject jsonObject, boolean isComposition) { + Iterator jsonObjectIterator = jsonObject.keys(); + jsonObjectIterator.forEachRemaining( + key -> { + Object value = jsonObject.get(key); + handleValue(key, value, isComposition); + }); + } + + private void handleJSONArray(String key, JSONArray jsonArray, boolean isComposition) { + Iterator jsonArrayIterator = jsonArray.iterator(); + jsonArrayIterator.forEachRemaining(element -> handleValue(key, element, isComposition)); + } +} diff --git a/src/main/java/org/smartregister/util/StructureMapProcessor.java b/src/main/java/org/smartregister/util/StructureMapProcessor.java new file mode 100644 index 00000000..4033f770 --- /dev/null +++ b/src/main/java/org/smartregister/util/StructureMapProcessor.java @@ -0,0 +1,105 @@ +/* (C)2023 */ +package org.smartregister.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.apache.commons.lang3.StringUtils; + +public class StructureMapProcessor { + private String directoryPath; + private String currentFile; + + private Map>> exceptionsMap = new HashMap<>(); + + public StructureMapProcessor(String folderPath) { + this.directoryPath = folderPath; + } + + public Map> process() { + Map> structureMapToLinkIds = new HashMap<>(); + + try { + + Map> folderTofilesIndexMap = + FCTUtils.indexConfigurationFiles(directoryPath); + + // Process other configurations + for (var entry : folderTofilesIndexMap.entrySet()) { + + Map fileIndexMap = folderTofilesIndexMap.get(entry.getKey()); + + for (var nestedEntry : fileIndexMap.entrySet()) { + + currentFile = nestedEntry.getValue(); + + if (nestedEntry.getKey().startsWith(".")) continue; + + Path path = Paths.get(nestedEntry.getValue()); + Set linkIds = new HashSet<>(); + + String line; + String firstLine = ""; + int i = 0; + try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8); ) { + + while ((line = reader.readLine()) != null) { + + if (i == 0) { + i++; + firstLine = line; + } + + if (line.contains(FCTValidationEngine.Constants.linkId)) { + + String[] linkIdRaw = + StringUtils.deleteWhitespace(line.toString()) + .split(FCTValidationEngine.Constants.linkId); + for (int j = 0; j < linkIdRaw.length; j++) { + + String subLine = + StringUtils.deleteWhitespace(line.toString()) + .split(FCTValidationEngine.Constants.linkId)[j]; + if (subLine.startsWith("=")) { + + try { + linkIds.add(getSubstringBetween(subLine, "='", "'")); + + } catch (StringIndexOutOfBoundsException e) { + + linkIds.add(getSubstringBetween(subLine, "=\"", "\"")); + } + } + } + } + } + } + + structureMapToLinkIds.put(getStructureMapId(firstLine), linkIds); + } + } + + } catch (IOException ioException) { + ioException.toString(); + } + return structureMapToLinkIds; + } + + private String getSubstringBetween(String str, String opening, String closing) { + String temp = str.substring(str.indexOf(opening) + opening.length()); + return temp.substring(0, temp.indexOf(closing)); + } + + private String getStructureMapId(String firstLine) { + + return StringUtils.substringAfterLast( + firstLine.replace("\'", "").replace("\"", "").split("=")[0].trim(), '/'); + } +} diff --git a/src/main/resources/dependency-set.xml b/src/main/resources/dependency-set.xml new file mode 100644 index 00000000..ff55102f --- /dev/null +++ b/src/main/resources/dependency-set.xml @@ -0,0 +1,35 @@ + + + jar-with-dependencies-and-exclude-classes + + jar + + false + + + / + false + true + runtime + + ca.uhn.hapi.fhir:org.hl7.fhir.r5 + ca.uhn.hapi.fhir:org.hl7.fhir.dstu2 + ca.uhn.hapi.fhir:org.hl7.fhir.dstu3 + ca.uhn.hapi.fhir:org.hl7.fhir.dstu2016may + ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3 + ca.uhn.hapi.fhir:hapi-fhir-structures-r5 + ca.uhn.hapi.fhir:hapi-fhir-structures-dstu2 + ca.uhn.hapi.fhir:hapi-fhir-structures-hl7org-dstu2 + + + + + + + / + ${project.build.outputDirectory} + + +