List<CommandDescriptor> (String scriptText, File scriptDir) { List<CommandDescriptor> commands = new ArrayList<>(); final StringTokenizer tokens = new StringTokenizer(scriptText, "\n"); int line = 0; while (tokens.hasMoreTokens()) { final String eachLine = tokens.nextToken(); if (eachLine.startsWith(INCLUDE_CMD)) { File file = new PathMacro().setScriptDir(scriptDir).resolveFile(eachLine.substring(INCLUDE_CMD.length()).trim(), scriptDir); if (!file.exists()) { throw new RuntimeException("Cannot find file to include at line " + line + ": " + file.getAbsolutePath()); } try { String include = FileUtil.loadFile(file, true); commands.add(new CommandDescriptor(PrintCommand.PREFIX + " " + eachLine, line, scriptDir)); List<CommandDescriptor> includeCommands = includeScript(include, file.getParentFile()); commands.addAll(includeCommands); } catch (IOException e) { throw new RuntimeException("Error reading file at line " + line + ": " + file.getAbsolutePath()); } } else if (eachLine.startsWith(IMPORT_CALL_CMD)) { String className = eachLine.substring(IMPORT_CALL_CMD.length()).trim(); try { Class<?> facadeClass = Class.forName(className); facadeClasses.add(facadeClass); commands.add(new CommandDescriptor(PrintCommand.PREFIX + " " + eachLine, line++, scriptDir)); } catch (ClassNotFoundException e) { throw new RuntimeException("Cannot find class at line " + line + ": " + className); } } else { commands.add(new CommandDescriptor(eachLine, line++, scriptDir)); } } return commands; }