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