package fr.adrienbrault.idea.symfony2plugin.translation.collector; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import fr.adrienbrault.idea.symfony2plugin.util.yaml.YamlHelper; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.yaml.psi.*; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * @author Daniel Espendiller <daniel@espendiller.net> */ public class YamlTranslationVistor { public static void collectFileTranslations(@NotNull YAMLFile yamlFile, @NotNull YamlTranslationCollector translationCollector) { for(YAMLKeyValue yamlKeyValue: YamlHelper.getTopLevelKeyValues(yamlFile)) { collectItems(yamlKeyValue, translationCollector); } } private static void collectNextLevelElements(@NotNull YAMLCompoundValue yamlCompoundValue, @NotNull List<String> levels, @NotNull YamlTranslationCollector translationCollector) { Collection<YAMLKeyValue> yamlKeyValues = PsiTreeUtil.getChildrenOfTypeAsList(yamlCompoundValue, YAMLKeyValue.class); for(YAMLKeyValue yamlKeyValue: yamlKeyValues) { if(!collectItems(levels, yamlKeyValue, translationCollector)) { return; } } } private static void collectItems(@NotNull YAMLKeyValue yamlKeyValue, @NotNull YamlTranslationCollector translationCollector ) { collectItems(new ArrayList<>(), yamlKeyValue, translationCollector); } private static boolean collectItems(@NotNull List<String> levels, @NotNull YAMLKeyValue yamlKeyValue, @NotNull YamlTranslationCollector translationCollector) { List<YAMLPsiElement> childElements = yamlKeyValue.getYAMLElements(); String keyText = yamlKeyValue.getKeyText(); if(StringUtils.isBlank(keyText)) { return true; } // we check again after cleanup keyText = keyNormalizer(keyText); if(StringUtils.isBlank(keyText)) { return true; } // @TODO: use features of new yaml integration // yaml key-value provide main psielement in last child element // depending of what we get here we have another key-value inside, multiline or string value if(childElements.size() == 1 && childElements.get(0) instanceof YAMLMapping) { PsiElement lastChildElement = childElements.get(0); // catch next level keys if(lastChildElement instanceof YAMLMapping) { // use copy of current level and pipe to children call ArrayList<String> copyLevels = new ArrayList<>(levels); copyLevels.add(keyText); collectNextLevelElements((YAMLCompoundValue) childElements.get(0), copyLevels, translationCollector); return true; } // check multiline is also an tree end indicator // stats: | // accomplishment: > if((lastChildElement instanceof YAMLScalarText || lastChildElement instanceof YAMLScalarList)) { return callCollectCallback(levels, yamlKeyValue, translationCollector, keyText); } } else { return callCollectCallback(levels, yamlKeyValue, translationCollector, keyText); } return true; } private static boolean callCollectCallback(@NotNull List<String> levels, @NotNull YAMLKeyValue yamlKeyValue, @NotNull YamlTranslationCollector translationCollector, @NotNull String keyText) { ArrayList<String> copyLevels = new ArrayList<>(levels); copyLevels.add(keyText); return translationCollector.collect(StringUtils.join(copyLevels, "."), yamlKeyValue); } /** * Translation key allow quoted values and also space before and after */ private static String keyNormalizer(@NotNull String keyName) { return StringUtils.trim(StringUtils.strip(StringUtils.strip(keyName, "'"), "\"")); } }