package org.jetbrains.idea.maven.dom.model.completion; import com.intellij.codeInsight.actions.ReformatCodeProcessor; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.icons.AllIcons; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.psi.xml.XmlText; import com.intellij.psi.xml.XmlTokenType; import com.intellij.util.xml.DomElement; import com.intellij.util.xml.DomFileElement; import com.intellij.util.xml.DomManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.dom.converters.MavenDependencyCompletionUtil; import org.jetbrains.idea.maven.dom.model.MavenDomDependency; import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel; import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager; /** * @author Sergey Evdokimov */ public class MavenDependenciesCompletionProvider extends CompletionContributor { @Override public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) { PsiElement xmlText = parameters.getPosition().getParent(); if (!(xmlText instanceof XmlText)) return; PsiElement eDependencyTag = xmlText.getParent(); if (!(eDependencyTag instanceof XmlTag)) return; XmlTag dependencyTag = (XmlTag)eDependencyTag; if (!"dependency".equals(dependencyTag.getName())) return; if (!PsiImplUtil.isLeafElementOfType(xmlText.getPrevSibling(), XmlTokenType.XML_TAG_END) || !PsiImplUtil.isLeafElementOfType(xmlText.getNextSibling(), XmlTokenType.XML_END_TAG_START)) { return; } Project project = dependencyTag.getProject(); DomElement domElement = DomManager.getDomManager(project).getDomElement(dependencyTag); if (!(domElement instanceof MavenDomDependency)) { return; } MavenProjectIndicesManager indicesManager = MavenProjectIndicesManager.getInstance(project); for (String groupId : indicesManager.getGroupIds()) { for (String artifactId : indicesManager.getArtifactIds(groupId)) { LookupElement builder = LookupElementBuilder.create(groupId + ':' + artifactId) .withIcon(AllIcons.Nodes.PpLib).withInsertHandler(MavenDependencyInsertHandler.INSTANCE); result.addElement(builder); } } } private static class MavenDependencyInsertHandler implements InsertHandler<LookupElement> { public static final InsertHandler<LookupElement> INSTANCE = new MavenDependencyInsertHandler(); @Override public void handleInsert(final InsertionContext context, LookupElement item) { String s = item.getLookupString(); int idx = s.indexOf(':'); String groupId = s.substring(0, idx); String artifactId = s.substring(idx + 1); int startOffset = context.getStartOffset(); PsiFile psiFile = context.getFile(); DomFileElement<MavenDomProjectModel> domModel = DomManager.getDomManager(context.getProject()).getFileElement((XmlFile)psiFile, MavenDomProjectModel.class); if (domModel == null) return; boolean shouldInvokeCompletion = false; MavenDomDependency managedDependency = MavenDependencyCompletionUtil.findManagedDependency(domModel.getRootElement(), context.getProject(), groupId, artifactId); if (managedDependency == null) { String value = "<groupId>" + groupId + "</groupId>\n" + "<artifactId>" + artifactId + "</artifactId>\n" + "<version></version>"; context.getDocument().replaceString(startOffset, context.getSelectionEndOffset(), value); context.getEditor().getCaretModel().moveToOffset(startOffset + value.length() - 10); shouldInvokeCompletion = true; } else { StringBuilder sb = new StringBuilder(); sb.append("<groupId>").append(groupId).append("</groupId>\n") .append("<artifactId>").append(artifactId).append("</artifactId>\n"); String type = managedDependency.getType().getRawText(); if (type != null && !type.equals("jar")) { sb.append("<type>").append(type).append("</type>\n"); } String classifier = managedDependency.getClassifier().getRawText(); if (StringUtil.isNotEmpty(classifier)) { sb.append("<classifier>").append(classifier).append("</classifier>\n"); } context.getDocument().replaceString(startOffset, context.getSelectionEndOffset(), sb); } context.commitDocument(); PsiElement e = psiFile.findElementAt(startOffset); while (e != null && (!(e instanceof XmlTag) || !"dependency".equals(((XmlTag)e).getName()))) { e = e.getParent(); } if (e != null) { new ReformatCodeProcessor(psiFile.getProject(), psiFile, e.getTextRange(), false).run(); } if (shouldInvokeCompletion) { MavenDependencyCompletionUtil.invokeCompletion(context, CompletionType.BASIC); } } } }