package com.google.jstestdriver.idea.execution.settings; import com.google.common.collect.Lists; import com.google.jstestdriver.idea.util.EnumUtils; import com.intellij.ide.browsers.BrowserFamily; import com.intellij.ide.browsers.WebBrowserManager; import com.intellij.openapi.util.JDOMExternalizer; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ObjectUtils; import org.jdom.Attribute; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import java.util.List; public class JstdRunSettingsSerializationUtils { private enum Key { TEST_TYPE("configLocationType"), JSTD_CONFIG_FILE("settingsFile"), ALL_IN_DIRECTORY("allInDirectory"), CONFIG_TYPE("configType"), JS_FILE("jsFile"), TEST_CASE("testCase"), TEST_METHOD("testMethod"), SERVER_ADDRESS("serverAddress"), SERVER_TYPE("serverType"), COVERAGE("coverage"), COVERAGE_EXCLUDED("excluded"), COVERAGE_EXCLUDED_PATH("path"), PREFERRED_DEBUG_BROWSER("preferredDebugBrowser"); private final String key; Key(String key) { this.key = key; } public String getKey() { return key; } } private JstdRunSettingsSerializationUtils() {} public static JstdRunSettings readFromXml(@NotNull Element element) { JstdRunSettings.Builder builder = new JstdRunSettings.Builder(); TestType testType = readEnumByName(element, Key.TEST_TYPE, TestType.CONFIG_FILE); builder.setTestType(testType); if (testType == TestType.ALL_CONFIGS_IN_DIRECTORY) { String directory = readString(element, Key.ALL_IN_DIRECTORY, ""); builder.setDirectory(FileUtil.toSystemDependentName(directory)); } else if (testType == TestType.CONFIG_FILE) { String configFile = readString(element, Key.JSTD_CONFIG_FILE, ""); builder.setConfigFile(FileUtil.toSystemDependentName(configFile)); } else if (testType == TestType.JS_FILE) { readJsFile(element, builder); } else if (testType == TestType.TEST_CASE) { readTestCase(element, builder); } else if (testType == TestType.TEST_METHOD) { readTestMethod(element, builder); } ServerType serverType = readEnumByName(element, Key.SERVER_TYPE, ServerType.INTERNAL); builder.setServerType(serverType); if (serverType == ServerType.EXTERNAL) { String serverAddress = readString(element, Key.SERVER_ADDRESS, ""); builder.setServerAddress(serverAddress); } List<String> filesExcludedFromCoverage = readFilesExcludedFromCoverage(element); builder.setFilesExcludedFromCoverage(filesExcludedFromCoverage); builder.setPreferredDebugBrowser(WebBrowserManager.getInstance().getFirstBrowser(readEnumByName(element, Key.PREFERRED_DEBUG_BROWSER, BrowserFamily.CHROME))); return builder.build(); } @SuppressWarnings("unchecked") private static List<String> readFilesExcludedFromCoverage(@NotNull Element root) { List<String> excludedPaths = Lists.newArrayList(); Element coverageElement = root.getChild(Key.COVERAGE.getKey()); if (coverageElement != null) { List<Element> excludedElements = coverageElement.getChildren(Key.COVERAGE_EXCLUDED.getKey()); for (Element excludedElement : excludedElements) { Attribute pathAttr = excludedElement.getAttribute(Key.COVERAGE_EXCLUDED_PATH.getKey()); if (pathAttr != null) { String path = pathAttr.getValue(); if (StringUtil.isNotEmpty(path)) { excludedPaths.add(FileUtil.toSystemDependentName(path)); } } } } return excludedPaths; } private static void writeFilesExcludedFromCoverage(@NotNull Element root, @NotNull List<String> excludedPaths) { if (excludedPaths.isEmpty()) { return; } Element coverageElement = new Element(Key.COVERAGE.getKey()); root.addContent(coverageElement); for (String path : excludedPaths) { Element excludedElement = new Element(Key.COVERAGE_EXCLUDED.getKey()); excludedElement.setAttribute( Key.COVERAGE_EXCLUDED_PATH.getKey(), FileUtil.toSystemIndependentName(path) ); coverageElement.addContent(excludedElement); } } private static void readTestMethod(@NotNull Element element, @NotNull JstdRunSettings.Builder builder) { readTestCase(element, builder); String testMethodName = readString(element, Key.TEST_METHOD, ""); builder.setTestMethodName(testMethodName); } private static void readTestCase(@NotNull Element element, @NotNull JstdRunSettings.Builder builder) { readJsFile(element, builder); String testCaseName = readString(element, Key.TEST_CASE, ""); builder.setTestCaseName(testCaseName); } private static void readJsFile(@NotNull Element element, @NotNull JstdRunSettings.Builder builder) { String configFile = readString(element, Key.JSTD_CONFIG_FILE, ""); builder.setConfigFile(FileUtil.toSystemDependentName(configFile)); String jsFile = readString(element, Key.JS_FILE, ""); builder.setJSFilePath(FileUtil.toSystemDependentName(jsFile)); } @SuppressWarnings({"unchecked"}) @NotNull private static <E extends Enum<E>> E readEnumByName(@NotNull Element element, @NotNull Key key, @NotNull E defaultValue) { String str = readString(element, key, ""); E enumConstant = EnumUtils.findEnum(defaultValue.getDeclaringClass(), str); return ObjectUtils.notNull(enumConstant, defaultValue); } @NotNull private static String readString(@NotNull Element element, @NotNull Key key, @NotNull String defaultValue) { String value = JDOMExternalizer.readString(element, key.getKey()); return value != null ? value : defaultValue; } public static void writeToXml(@NotNull Element element, @NotNull JstdRunSettings runSettings) { TestType testType = runSettings.getTestType(); writeString(element, Key.TEST_TYPE, testType.name()); if (testType == TestType.ALL_CONFIGS_IN_DIRECTORY) { writeString(element, Key.ALL_IN_DIRECTORY, FileUtil.toSystemIndependentName(runSettings.getDirectory())); } else if (testType == TestType.CONFIG_FILE) { writeString(element, Key.JSTD_CONFIG_FILE, FileUtil.toSystemIndependentName(runSettings.getConfigFile())); } else if (testType == TestType.JS_FILE) { writeJsFile(element, runSettings); } else if (testType == TestType.TEST_CASE) { writeTestCase(element, runSettings); } else if (testType == TestType.TEST_METHOD) { writeTestMethod(element, runSettings); } writeString(element, Key.SERVER_TYPE, runSettings.getServerType().name()); if (runSettings.getServerType() == ServerType.EXTERNAL) { writeString(element, Key.SERVER_ADDRESS, runSettings.getServerAddress()); } writeFilesExcludedFromCoverage(element, runSettings.getFilesExcludedFromCoverage()); writeString(element, Key.PREFERRED_DEBUG_BROWSER, runSettings.getPreferredDebugBrowser().getName()); } private static void writeTestMethod(@NotNull Element element, @NotNull JstdRunSettings runSettings) { writeTestCase(element, runSettings); writeString(element, Key.TEST_METHOD, runSettings.getTestMethodName()); } private static void writeTestCase(@NotNull Element element, @NotNull JstdRunSettings runSettings) { writeJsFile(element, runSettings); writeString(element, Key.TEST_CASE, runSettings.getTestCaseName()); } private static void writeJsFile(@NotNull Element element, @NotNull JstdRunSettings runSettings) { writeString(element, Key.CONFIG_TYPE, "FILE_PATH"); writeString(element, Key.JSTD_CONFIG_FILE, FileUtil.toSystemIndependentName(runSettings.getConfigFile())); writeString(element, Key.JS_FILE, FileUtil.toSystemIndependentName(runSettings.getJsFilePath())); } private static void writeString(@NotNull Element element, @NotNull Key key, @NotNull String value) { JDOMExternalizer.write(element, key.getKey(), value); } }