package org.jetbrains.plugins.cucumber.psi.i18n; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.MalformedJsonException; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.cucumber.psi.*; import java.io.*; import java.util.*; public class JsonGherkinKeywordProvider implements GherkinKeywordProvider { private static final Logger LOG = Logger.getInstance(JsonGherkinKeywordProvider.class.getName()); private final GherkinKeywordList myEmptyKeywordList = new GherkinKeywordList(); private final Map<String, GherkinKeywordList> myLanguageKeywords = new HashMap<>(); private final Set<String> myAllStepKeywords = new HashSet<>(); private static GherkinKeywordProvider myKeywordProvider; public static GherkinKeywordProvider getKeywordProvider() { if (myKeywordProvider == null) { final ClassLoader classLoader = JsonGherkinKeywordProvider.class.getClassLoader(); if (classLoader != null) { @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") final InputStream inputStream = classLoader.getResourceAsStream("i18n.json"); if (inputStream != null) { myKeywordProvider = new JsonGherkinKeywordProvider(inputStream); } } if (myKeywordProvider == null) { myKeywordProvider = new PlainGherkinKeywordProvider(); } } return myKeywordProvider; } public JsonGherkinKeywordProvider(final File keywordsFile) throws FileNotFoundException { this(new FileInputStream(keywordsFile)); if (!(keywordsFile.exists() && !keywordsFile.isDirectory() && keywordsFile.canRead())){ LOG.error("Cannot read keywords from: " + keywordsFile); } } public JsonGherkinKeywordProvider(final InputStream inputStream) { Map<String, HashMap<Object, Object>> fromJson; try { final Reader in = new InputStreamReader(inputStream, CharsetToolkit.UTF8_CHARSET); try { fromJson = new Gson().fromJson(in, new TypeToken<HashMap<String, HashMap<Object, Object>>>() {}.getType()); for (Map.Entry<String, HashMap<Object, Object>> entry : fromJson.entrySet()) { HashMap<Object, Object> translation = entry.getValue(); final GherkinKeywordList keywordList = new GherkinKeywordList(translation); myLanguageKeywords.put(entry.getKey(), keywordList); for (String keyword : keywordList.getAllKeywords()) { if (keywordList.getTokenType(keyword) == GherkinTokenTypes.STEP_KEYWORD) { myAllStepKeywords.add(keyword); } } } } finally { in.close(); } } catch (MalformedJsonException e) { // ignore } catch (IOException e) { LOG.error(e); } } public Collection<String> getAllKeywords(String language) { return getKeywordList(language).getAllKeywords(); } @Override public IElementType getTokenType(String language, String keyword) { return getKeywordList(language).getTokenType(keyword); } @Override public String getBaseKeyword(String language, String keyword) { return getKeywordList(language).getBaseKeyword(keyword); } @Override public boolean isSpaceAfterKeyword(String language, String keyword) { return getKeywordList(language).isSpaceAfterKeyword(keyword); } @Override public boolean isStepKeyword(String keyword) { return myAllStepKeywords.contains(keyword); } @NotNull @Override public GherkinKeywordTable getKeywordsTable(@Nullable String language) { return getKeywordList(language).getKeywordsTable(); } @NotNull private GherkinKeywordList getKeywordList(@Nullable final String language) { GherkinKeywordList keywordList = myLanguageKeywords.get(language); if (keywordList == null) { keywordList = myEmptyKeywordList; } return keywordList; } }