package com.intuit.karate; import java.io.File; import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import static com.intuit.karate.Script.eval; import com.intuit.karate.cucumber.FeatureWrapper; import com.jayway.jsonpath.DocumentContext; /** * * @author pthomas3 */ public class FileUtils { private FileUtils() { // only static methods } public static final boolean isClassPath(String text) { return text.startsWith("classpath:"); } public static final boolean isJsonFile(String text) { return text.endsWith(".json"); } public static final boolean isJavaScriptFile(String text) { return text.endsWith(".js"); } public static final boolean isYamlFile(String text) { return text.endsWith(".yaml") || text.endsWith(".yml"); } public static final boolean isXmlFile(String text) { return text.endsWith(".xml"); } public static final boolean isTextFile(String text) { return text.endsWith(".txt"); } public static final boolean isFeatureFile(String text) { return text.endsWith(".feature"); } public static ScriptValue readFile(String text, ScriptContext context) { text = StringUtils.trim(text); int pos = text.indexOf(':'); String fileName = pos == -1 ? text : text.substring(pos + 1); fileName = StringUtils.trim(fileName); if (isJsonFile(text) || isXmlFile(text) || isJavaScriptFile(text)) { String contents = readFileAsString(fileName, isClassPath(text), context); return eval(contents, context); } else if (isTextFile(text)) { String contents = readFileAsString(fileName, isClassPath(text), context); return new ScriptValue(contents); } else if (isFeatureFile(text)) { String contents = readFileAsString(fileName, isClassPath(text), context); FeatureWrapper feature = FeatureWrapper.fromString(contents, context.env); // TODO determine file dir return new ScriptValue(feature); } else if (isYamlFile(text)) { String contents = readFileAsString(fileName, isClassPath(text), context); DocumentContext doc = JsonUtils.fromYaml(contents); return new ScriptValue(doc); } else { InputStream is = getFileStream(fileName, isClassPath(text), context); return new ScriptValue(is); } } public static String readFileAsString(String path, boolean classpath, ScriptContext context) { InputStream is = getFileStream(path, classpath, context); try { return IOUtils.toString(is, "utf-8"); } catch (Exception e) { String message = String.format("could not read file: %s, classpath: %s", path, classpath); context.logger.error(message); throw new RuntimeException(message, e); } } public static InputStream getFileStream(String path, boolean classpath, ScriptContext context) { if (classpath) { return context.env.fileClassLoader.getResourceAsStream(path); } String fullPath = context.env.featureDir + File.separator + path; try { InputStream is = org.apache.commons.io.FileUtils.openInputStream(new File(fullPath)); context.logger.debug("loaded file from: {} - {}: {}", fullPath, path, is); return is; } catch (Exception e) { throw new RuntimeException(e); } } public static File getDirContaining(Class clazz) { String resourcePath = clazz.getResource(clazz.getSimpleName() + ".class").getFile(); return new File(resourcePath).getParentFile(); } public static URL toFileUrl(String path) { path = StringUtils.trim(path); File file = new File(path); try { return file.getAbsoluteFile().toURI().toURL(); } catch (Exception e) { throw new RuntimeException(e); } } public static ClassLoader createClassLoader(String ... paths) { List<URL> urls = new ArrayList<>(paths.length); for (String path : paths) { urls.add(toFileUrl(path)); } return new URLClassLoader(urls.toArray(new URL[]{})); } public static String getFeaturePath(String commandLine, String cwd) { cwd = cwd.replace('\\', '/'); // fix for windows int start = commandLine.indexOf(cwd); if (start == -1) { return null; } int end = commandLine.indexOf(".feature", start); if (end == -1) { return null; } return commandLine.substring(start, end + 8); } }