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