package fr.adrienbrault.idea.symfony2plugin.translation.util; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.XmlElementFactory; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import fr.adrienbrault.idea.symfony2plugin.translation.dict.TranslationUtil; import fr.adrienbrault.idea.symfony2plugin.util.yaml.YamlHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.yaml.YAMLTokenTypes; import org.jetbrains.yaml.YAMLUtil; import org.jetbrains.yaml.psi.YAMLFile; import org.jetbrains.yaml.psi.YAMLKeyValue; import java.util.function.Function; /** * @author Daniel Espendiller <daniel@espendiller.net> */ public class TranslationInsertUtil { @Nullable public static PsiElement invokeTranslation(@NotNull final PsiFile psiFile, @NotNull final String keyName, @NotNull final String translation) { if(psiFile instanceof YAMLFile) { return invokeTranslation((YAMLFile) psiFile, keyName, translation); } else if(psiFile instanceof XmlFile && TranslationUtil.isSupportedXlfFile(psiFile)) { return invokeTranslation((XmlFile) psiFile, keyName, translation); } return null; } private static PsiElement invokeTranslation(@NotNull final YAMLFile yamlFile, @NotNull final String keyName, @NotNull final String translation) { String[] split = keyName.split("\\."); PsiElement psiElement = YamlHelper.insertKeyIntoFile(yamlFile, "'" + translation + "'", split); if(psiElement == null) { return null; } // resolve target to get value YAMLKeyValue target = YAMLUtil.getQualifiedKeyInFile(yamlFile, split); if(target != null && target.getValue() != null) { return target.getValue(); } else if(target != null) { return target; } return yamlFile; } @Nullable public static XmlTag invokeTranslation(@NotNull final XmlFile xmlFile, @NotNull final String keyName, @NotNull final String translation) { XmlTag rootTag = xmlFile.getRootTag(); if(rootTag == null) { return null; } String version = rootTag.getAttributeValue("version"); if(version == null) { return null; } XmlTag file = rootTag.findFirstSubTag("file"); if(file == null) { return null; } // version="1.2" if(version.equalsIgnoreCase("1.2")) { Function<XmlTag, XmlTag> func12 = body -> { XmlElementFactory instance = XmlElementFactory.getInstance(xmlFile.getProject()); XmlTag source = instance.createTagFromText("<source/>"); source.getValue().setText(keyName); XmlTag target = instance.createTagFromText("<target/>"); target.getValue().setText(translation); XmlTag transUnit = instance.createTagFromText("<trans-unit/>"); transUnit.setAttribute("id", String.valueOf(getIdForNewXlfUnit(body, "trans-unit"))); transUnit.addSubTag(source, false); transUnit.addSubTag(target, false); return body.addSubTag(transUnit, false); }; XmlTag body = file.findFirstSubTag("body"); if(body != null) { return func12.apply(body); } } else if(version.equalsIgnoreCase("2.0")) { Function<XmlTag, XmlTag> func20 = body -> { XmlElementFactory instance = XmlElementFactory.getInstance(xmlFile.getProject()); XmlTag source = instance.createTagFromText("<source/>"); source.getValue().setText(keyName); XmlTag target = instance.createTagFromText("<target/>"); target.getValue().setText(translation); XmlTag transUnit = instance.createTagFromText("<unit/>"); transUnit.setAttribute("id", String.valueOf(String.valueOf(getIdForNewXlfUnit(body, "unit")))); XmlTag segment = transUnit.addSubTag(instance.createTagFromText("<segment/>"), false); segment.addSubTag(source, false); segment.addSubTag(target, false); return body.addSubTag(transUnit, false); }; // version="2.0" XmlTag group = file.findFirstSubTag("group"); if(group != null) { return func20.apply(group); } else { // version="2.0" shortcut return func20.apply(file); } } return null; } private static int getIdForNewXlfUnit(@NotNull XmlTag body, @NotNull String subTag) { int lastId = 0; for (XmlTag transUnit : body.findSubTags(subTag)) { String id = transUnit.getAttributeValue("id"); if(id == null) { continue; } Integer integer; try { integer = Integer.valueOf(id); } catch (NumberFormatException e) { continue; } // next safe id if(integer >= lastId) { lastId = integer + 1; } } return lastId; } /** * Remove TODO; moved to core */ @Deprecated @NotNull public static String findEol(@NotNull PsiElement psiElement) { for(PsiElement child: YamlHelper.getChildrenFix(psiElement)) { if(PlatformPatterns.psiElement(YAMLTokenTypes.EOL).accepts(child)) { return child.getText(); } } PsiElement[] indentPsiElements = PsiTreeUtil.collectElements(psiElement.getContainingFile(), element -> PlatformPatterns.psiElement(YAMLTokenTypes.EOL).accepts(element) ); if(indentPsiElements.length > 0) { return indentPsiElements[0].getText(); } return "\n"; } }