001package org.hl7.fhir.validation.cli.utils; 002 003import java.io.File; 004import java.util.Arrays; 005import java.util.Locale; 006 007import org.hl7.fhir.exceptions.FHIRException; 008import org.hl7.fhir.r5.terminologies.JurisdictionUtilities; 009import org.hl7.fhir.r5.utils.validation.BundleValidationRule; 010import org.hl7.fhir.utilities.VersionUtilities; 011import org.hl7.fhir.validation.cli.model.CliContext; 012import org.hl7.fhir.validation.cli.model.HtmlInMarkdownCheck; 013 014public class Params { 015 016 public static final String VERSION = "-version"; 017 public static final String OUTPUT = "-output"; 018 019 public static final String OUTPUT_SUFFIX = "-outputSuffix"; 020 public static final String LEVEL = "-level"; 021 public static final String HTML_OUTPUT = "-html-output"; 022 public static final String PROXY = "-proxy"; 023 024 public static final String HTTPS_PROXY = "-https-proxy"; 025 public static final String PROXY_AUTH = "-auth"; 026 public static final String PROFILE = "-profile"; 027 public static final String BUNDLE = "-bundle"; 028 public static final String QUESTIONNAIRE = "-questionnaire"; 029 public static final String NATIVE = "-native"; 030 public static final String ASSUME_VALID_REST_REF = "-assumeValidRestReferences"; 031 public static final String DEBUG = "-debug"; 032 public static final String SCT = "-sct"; 033 public static final String RECURSE = "-recurse"; 034 public static final String SHOW_MESSAGES_FROM_REFERENCES = "-showReferenceMessages"; 035 public static final String LOCALE = "-locale"; 036 public static final String EXTENSION = "-extension"; 037 public static final String HINT_ABOUT_NON_MUST_SUPPORT = "-hintAboutNonMustSupport"; 038 public static final String TO_VERSION = "-to-version"; 039 public static final String DO_NATIVE = "-do-native"; 040 public static final String NO_NATIVE = "-no-native"; 041 public static final String COMPILE = "-compile"; 042 public static final String TRANSFORM = "-transform"; 043 public static final String NARRATIVE = "-narrative"; 044 public static final String SNAPSHOT = "-snapshot"; 045 public static final String SCAN = "-scan"; 046 public static final String TERMINOLOGY = "-tx"; 047 public static final String TERMINOLOGY_LOG = "-txLog"; 048 public static final String TERMINOLOGY_CACHE = "-txCache"; 049 public static final String LOG = "-log"; 050 public static final String LANGUAGE = "-language"; 051 public static final String IMPLEMENTATION_GUIDE = "-ig"; 052 public static final String DEFINITION = "defn"; 053 public static final String MAP = "-map"; 054 public static final String X = "-x"; 055 public static final String CONVERT = "-convert"; 056 public static final String FHIRPATH = "-fhirpath"; 057 public static final String TEST = "-tests"; 058 public static final String HELP = "help"; 059 public static final String COMPARE = "-compare"; 060 public static final String SPREADSHEET = "-spreadsheet"; 061 public static final String DESTINATION = "-dest"; 062 public static final String LEFT = "-left"; 063 public static final String RIGHT = "-right"; 064 public static final String NO_INTERNAL_CACHING = "-no-internal-caching"; 065 public static final String NO_EXTENSIBLE_BINDING_WARNINGS = "-no-extensible-binding-warnings"; 066 public static final String NO_UNICODE_BIDI_CONTROL_CHARS = "-no_unicode_bidi_control_chars"; 067 public static final String NO_INVARIANTS = "-no-invariants"; 068 public static final String WANT_INVARIANTS_IN_MESSAGES = "-want-invariants-in-messages"; 069 public static final String SECURITY_CHECKS = "-security-checks"; 070 public static final String CRUMB_TRAIL = "-crumb-trails"; 071 public static final String FOR_PUBLICATION = "-forPublication"; 072 public static final String VERBOSE = "-verbose"; 073 public static final String SHOW_TIMES = "-show-times"; 074 public static final String ALLOW_EXAMPLE_URLS = "-allow-example-urls"; 075 public static final String OUTPUT_STYLE = "-output-style"; 076 public static final String DO_IMPLICIT_FHIRPATH_STRING_CONVERSION = "-implicit-fhirpath-string-conversions"; 077 public static final String JURISDICTION = "-jurisdiction"; 078 public static final String HTML_IN_MARKDOWN = "-html-in-markdown"; 079 080 public static final String RUN_TESTS = "-run-tests"; 081 082 public static final String TEST_MODULES = "-test-modules"; 083 084 public static final String TEST_NAME_FILTER = "-test-classname-filter"; 085 086 /** 087 * Checks the list of passed in params to see if it contains the passed in param. 088 * 089 * @param args Array of params to search. 090 * @param param {@link String} param to search for. 091 * @return {@link Boolean#TRUE} if the list contains the given param. 092 */ 093 public static boolean hasParam(String[] args, String param) { 094 return Arrays.asList(args).contains(param); 095 } 096 097 /** 098 * Fetches the value for the passed in param from the provided list of params. 099 * 100 * @param args Array of params to search. 101 * @param param {@link String} param keyword to search for. 102 * @return {@link String} value for the provided param. 103 */ 104 public static String getParam(String[] args, String param) { 105 for (int i = 0; i < args.length - 1; i++) { 106 if (args[i].equals(param)) return args[i + 1]; 107 } 108 return null; 109 } 110 111 /** 112 * TODO Don't do this all in one for loop. Use the above methods. 113 */ 114 public static CliContext loadCliContext(String[] args) throws Exception { 115 CliContext cliContext = new CliContext(); 116 117 // load the parameters - so order doesn't matter 118 for (int i = 0; i < args.length; i++) { 119 if (args[i].equals(VERSION)) { 120 cliContext.setSv(VersionUtilities.getCurrentPackageVersion(args[++i])); 121 } else if (args[i].equals(OUTPUT)) { 122 if (i + 1 == args.length) 123 throw new Error("Specified -output without indicating output file"); 124 else 125 cliContext.setOutput(args[++i]); 126 } else if (args[i].equals(OUTPUT_SUFFIX)) { 127 if (i + 1 == args.length) 128 throw new Error("Specified -outputSuffix without indicating output suffix"); 129 else 130 cliContext.setOutputSuffix(args[++i]); 131 } 132 else if (args[i].equals(HTML_OUTPUT)) { 133 if (i + 1 == args.length) 134 throw new Error("Specified -html-output without indicating output file"); 135 else 136 cliContext.setHtmlOutput(args[++i]); 137 } else if (args[i].equals(PROXY)) { 138 i++; // ignore next parameter 139 } else if (args[i].equals(PROXY_AUTH)) { 140 i++; 141 } else if (args[i].equals(HTTPS_PROXY)) { 142 i++; 143 } 144 else if (args[i].equals(PROFILE)) { 145 String p = null; 146 if (i + 1 == args.length) { 147 throw new Error("Specified -profile without indicating profile source"); 148 } else { 149 p = args[++i]; 150 cliContext.addProfile(p); 151 } 152 } else if (args[i].equals(BUNDLE)) { 153 String p = null; 154 String r = null; 155 if (i + 1 == args.length) { 156 throw new Error("Specified -profile without indicating bundle rule "); 157 } else { 158 r = args[++i]; 159 } 160 if (i + 1 == args.length) { 161 throw new Error("Specified -profile without indicating profile source"); 162 } else { 163 p = args[++i]; 164 } 165 cliContext.getBundleValidationRules().add(new BundleValidationRule(r, p)); 166 } else if (args[i].equals(QUESTIONNAIRE)) { 167 if (i + 1 == args.length) 168 throw new Error("Specified -questionnaire without indicating questionnaire mode"); 169 else { 170 String q = args[++i]; 171 cliContext.setQuestionnaireMode(QuestionnaireMode.fromCode(q)); 172 } 173 } else if (args[i].equals(LEVEL)) { 174 if (i + 1 == args.length) 175 throw new Error("Specified -level without indicating level mode"); 176 else { 177 String q = args[++i]; 178 cliContext.setLevel(ValidationLevel.fromCode(q)); 179 } 180 } else if (args[i].equals(NATIVE)) { 181 cliContext.setDoNative(true); 182 } else if (args[i].equals(ASSUME_VALID_REST_REF)) { 183 cliContext.setAssumeValidRestReferences(true); 184 } else if (args[i].equals(DEBUG)) { 185 cliContext.setDoDebug(true); 186 } else if (args[i].equals(SCT)) { 187 cliContext.setSnomedCT(args[++i]); 188 } else if (args[i].equals(RECURSE)) { 189 cliContext.setRecursive(true); 190 } else if (args[i].equals(SHOW_MESSAGES_FROM_REFERENCES)) { 191 cliContext.setShowMessagesFromReferences(true); 192 } else if (args[i].equals(DO_IMPLICIT_FHIRPATH_STRING_CONVERSION)) { 193 cliContext.setDoImplicitFHIRPathStringConversion(true); 194 } else if (args[i].equals(HTML_IN_MARKDOWN)) { 195 if (i + 1 == args.length) 196 throw new Error("Specified "+HTML_IN_MARKDOWN+" without indicating mode"); 197 else { 198 String q = args[++i]; 199 if (!HtmlInMarkdownCheck.isValidCode(q)) { 200 throw new Error("Specified "+HTML_IN_MARKDOWN+" with na invalid code - must be ignore, warning, or error"); 201 } else { 202 cliContext.setHtmlInMarkdownCheck(HtmlInMarkdownCheck.fromCode(q)); 203 } 204 } 205 } else if (args[i].equals(LOCALE)) { 206 if (i + 1 == args.length) { 207 throw new Error("Specified -locale without indicating locale"); 208 } else { 209 cliContext.setLocale(new Locale(args[++i])); 210 } 211 } else if (args[i].equals(EXTENSION)) { 212 cliContext.getExtensions().add(args[++i]); 213 } else if (args[i].equals(NO_INTERNAL_CACHING)) { 214 cliContext.setNoInternalCaching(true); 215 } else if (args[i].equals(NO_EXTENSIBLE_BINDING_WARNINGS)) { 216 cliContext.setNoExtensibleBindingMessages(true); 217 } else if (args[i].equals(NO_UNICODE_BIDI_CONTROL_CHARS)) { 218 cliContext.setNoUnicodeBiDiControlChars(true); 219 } else if (args[i].equals(NO_INVARIANTS)) { 220 cliContext.setNoInvariants(true); 221 } else if (args[i].equals(WANT_INVARIANTS_IN_MESSAGES)) { 222 cliContext.setWantInvariantsInMessages(true); 223 } else if (args[i].equals(HINT_ABOUT_NON_MUST_SUPPORT)) { 224 cliContext.setHintAboutNonMustSupport(true); 225 } else if (args[i].equals(TO_VERSION)) { 226 cliContext.setTargetVer(args[++i]); 227 cliContext.setMode(EngineMode.VERSION); 228 } else if (args[i].equals(DO_NATIVE)) { 229 cliContext.setCanDoNative(true); 230 } else if (args[i].equals(NO_NATIVE)) { 231 cliContext.setCanDoNative(false); 232 } else if (args[i].equals(TRANSFORM)) { 233 cliContext.setMap(args[++i]); 234 cliContext.setMode(EngineMode.TRANSFORM); 235 } else if (args[i].equals(COMPILE)) { 236 cliContext.setMap(args[++i]); 237 cliContext.setMode(EngineMode.COMPILE); 238 } else if (args[i].equals(NARRATIVE)) { 239 cliContext.setMode(EngineMode.NARRATIVE); 240 } else if (args[i].equals(SPREADSHEET)) { 241 cliContext.setMode(EngineMode.SPREADSHEET); 242 } else if (args[i].equals(SNAPSHOT)) { 243 cliContext.setMode(EngineMode.SNAPSHOT); 244 } else if (args[i].equals(RUN_TESTS)) { 245 // TODO setBaseTestingUtils test directory 246 cliContext.setMode(EngineMode.RUN_TESTS); 247 } else if (args[i].equals(SECURITY_CHECKS)) { 248 cliContext.setSecurityChecks(true); 249 } else if (args[i].equals(CRUMB_TRAIL)) { 250 cliContext.setCrumbTrails(true); 251 } else if (args[i].equals(FOR_PUBLICATION)) { 252 cliContext.setForPublication(true); 253 } else if (args[i].equals(VERBOSE)) { 254 cliContext.setCrumbTrails(true); 255 } else if (args[i].equals(ALLOW_EXAMPLE_URLS)) { 256 String bl = args[++i]; 257 if ("true".equals(bl)) { 258 cliContext.setAllowExampleUrls(true); 259 } else if ("false".equals(bl)) { 260 cliContext.setAllowExampleUrls(false); 261 } else { 262 throw new Error("Value for "+ALLOW_EXAMPLE_URLS+" not understood: "+bl); 263 } 264 } else if (args[i].equals(SHOW_TIMES)) { 265 cliContext.setShowTimes(true); 266 } else if (args[i].equals(OUTPUT_STYLE)) { 267 cliContext.setOutputStyle(args[++i]); 268 } else if (args[i].equals(SCAN)) { 269 cliContext.setMode(EngineMode.SCAN); 270 } else if (args[i].equals(TERMINOLOGY)) { 271 if (i + 1 == args.length) 272 throw new Error("Specified -tx without indicating terminology server"); 273 else 274 cliContext.setTxServer("n/a".equals(args[++i]) ? null : args[i]); 275 } else if (args[i].equals(TERMINOLOGY_LOG)) { 276 if (i + 1 == args.length) 277 throw new Error("Specified -txLog without indicating file"); 278 else 279 cliContext.setTxLog(args[++i]); 280 } else if (args[i].equals(TERMINOLOGY_CACHE)) { 281 if (i + 1 == args.length) 282 throw new Error("Specified -txCache without indicating file"); 283 else 284 cliContext.setTxCache(args[++i]); 285 } 286 else if (args[i].equals(LOG)) { 287 if (i + 1 == args.length) 288 throw new Error("Specified -log without indicating file"); 289 else 290 cliContext.setMapLog(args[++i]); 291 } else if (args[i].equals(LANGUAGE)) { 292 if (i + 1 == args.length) 293 throw new Error("Specified -language without indicating language"); 294 else 295 cliContext.setLang(args[++i]); 296 } else if (args[i].equals(JURISDICTION)) { 297 if (i + 1 == args.length) 298 throw new Error("Specified -jurisdiction without indicating jurisdiction"); 299 else 300 cliContext.setJurisdiction(processJurisdiction(args[++i])); 301 } else if (args[i].equals(IMPLEMENTATION_GUIDE) || args[i].equals(DEFINITION)) { 302 if (i + 1 == args.length) 303 throw new Error("Specified " + args[i] + " without indicating ig file"); 304 else { 305 String s = args[++i]; 306 String version = Common.getVersionFromIGName(null, s); 307 if (version == null) { 308 cliContext.addIg(s); 309 } else { 310 cliContext.setSv(version); 311 } 312 } 313 } else if (args[i].equals(MAP)) { 314 if (cliContext.getMap() == null) { 315 if (i + 1 == args.length) 316 throw new Error("Specified -map without indicating map file"); 317 else 318 cliContext.setMap(args[++i]); 319 } else { 320 throw new Exception("Can only nominate a single -map parameter"); 321 } 322 } else if (args[i].startsWith(X)) { 323 i++; 324 } else if (args[i].equals(CONVERT)) { 325 cliContext.setMode(EngineMode.CONVERT); 326 } else if (args[i].equals(FHIRPATH)) { 327 cliContext.setMode(EngineMode.FHIRPATH); 328 if (cliContext.getFhirpath() == null) 329 if (i + 1 == args.length) 330 throw new Error("Specified -fhirpath without indicating a FHIRPath expression"); 331 else 332 cliContext.setFhirpath(args[++i]); 333 else 334 throw new Exception("Can only nominate a single -fhirpath parameter"); 335 } else { 336 cliContext.addSource(args[i]); 337 } 338 } 339 return cliContext; 340 } 341 342 private static String processJurisdiction(String s) { 343 if (s.startsWith("urn:iso:std:iso:3166#") || s.startsWith("urn:iso:std:iso:3166:-2#") || s.startsWith("http://unstats.un.org/unsd/methods/m49/m49.htm#")) { 344 return s; 345 } else { 346 String v = JurisdictionUtilities.getJurisdictionFromLocale(s); 347 if (v != null) { 348 return v; 349 } else { 350 throw new FHIRException("Unable to understand Jurisdiction '"+s+"'"); 351 } 352 } 353 } 354 355 public static String getTerminologyServerLog(String[] args) { 356 String txLog = null; 357 if (hasParam(args, "-txLog")) { 358 txLog = getParam(args, "-txLog"); 359 new File(txLog).delete(); 360 } 361 return txLog; 362 } 363 364 public static void checkIGFileReferences(String[] args) { 365 for (int i = 0; i < args.length; i++) { 366 if (IMPLEMENTATION_GUIDE.equals(args[i])) { 367 if (i + 1 == args.length) 368 throw new Error("Specified -ig without indicating ig file"); 369 else { 370 String s = args[++i]; 371 if (!s.startsWith("hl7.fhir.core-")) { 372 System.out.println("Load Package: " + s); 373 } 374 } 375 } 376 } 377 } 378}