IDEA-95964 IntelliJ doesn't recognize jgit build number plugin variables in pom.xml

This commit is contained in:
Sergey Evdokimov
2013-01-03 22:13:31 +04:00
parent ac671ea0a2
commit 6da90c61d8
8 changed files with 248 additions and 37 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.idea.maven.dom.MavenDomUtil;
import org.jetbrains.idea.maven.project.MavenProject;
import java.util.List;
import java.util.Set;
public class MavenFilteredPropertyPsiReference extends MavenPropertyPsiReference {
public MavenFilteredPropertyPsiReference(MavenProject mavenProject, PsiElement element, String text, TextRange range) {
@@ -49,13 +50,13 @@ public class MavenFilteredPropertyPsiReference extends MavenPropertyPsiReference
}
@Override
protected void collectVariants(List<Object> result) {
super.collectVariants(result);
protected void collectVariants(List<Object> result, Set<String> variants) {
super.collectVariants(result, variants);
for (String each : myMavenProject.getFilters()) {
VirtualFile file = LocalFileSystem.getInstance().findFileByPath(each);
if (file == null) continue;
collectPropertiesFileVariants(MavenDomUtil.getPropertiesFile(myProject, file), null, result);
collectPropertiesFileVariants(MavenDomUtil.getPropertiesFile(myProject, file), null, result, variants);
}
}
@@ -213,6 +213,10 @@ public class MavenPropertyPsiReference extends MavenPsiReference {
}
}
if (mavenProject.getProperties().containsKey(myText)) {
return myElement;
}
if (myText.startsWith("settings.")) {
return resolveSettingsModelProperty();
}
@@ -287,11 +291,11 @@ public class MavenPropertyPsiReference extends MavenPsiReference {
@NotNull
public Object[] getVariants() {
List<Object> result = new ArrayList<Object>();
collectVariants(result);
collectVariants(result, new THashSet<String>());
return ArrayUtil.toObjectArray(result);
}
protected void collectVariants(final List<Object> result) {
protected void collectVariants(final List<Object> result, Set<String> variants) {
int prefixLength = 0;
if (myText.startsWith("pom.")) {
prefixLength = "pom.".length();
@@ -339,33 +343,30 @@ public class MavenPropertyPsiReference extends MavenPsiReference {
}
});
collectPropertiesVariants(result);
collectSystemEnvProperties(MavenPropertiesVirtualFileSystem.SYSTEM_PROPERTIES_FILE, null, result);
collectSystemEnvProperties(MavenPropertiesVirtualFileSystem.ENV_PROPERTIES_FILE, "env.", result);
collectPropertiesVariants(result, variants);
collectSystemEnvProperties(MavenPropertiesVirtualFileSystem.SYSTEM_PROPERTIES_FILE, null, result, variants);
collectSystemEnvProperties(MavenPropertiesVirtualFileSystem.ENV_PROPERTIES_FILE, "env.", result, variants);
MavenRunnerSettings runnerSettings = MavenRunner.getInstance(myProject).getSettings();
for (String prop : runnerSettings.getMavenProperties().keySet()) {
if (!isResultAlreadyContains(result, prop)) {
if (variants.add(prefix)) {
result.add(LookupElementBuilder.create(prop).withIcon(PlatformIcons.PROPERTY_ICON));
}
}
for (String prop : MavenUtil.getPropertiesFromMavenOpts().keySet()) {
if (!isResultAlreadyContains(result, prop)) {
if (variants.add(prop)) {
result.add(LookupElementBuilder.create(prop).withIcon(PlatformIcons.PROPERTY_ICON));
}
}
}
private static boolean isResultAlreadyContains(List<Object> results, String propertyName) {
for (Object result : results) {
if (result instanceof LookupElement) {
if (((LookupElement)result).getLookupString().equals(propertyName)) {
return true;
for (Object key : myMavenProject.getProperties().keySet()) {
if (key instanceof String) {
String property = (String)key;
if (variants.add(property)) {
result.add(LookupElementBuilder.create(property).withIcon(PlatformIcons.PROPERTY_ICON));
}
}
}
return false;
}
private static void addVariant(List<Object> result, String name, @NotNull Object element, @Nullable String prefix, @NotNull Icon icon) {
@@ -382,28 +383,34 @@ public class MavenPropertyPsiReference extends MavenPsiReference {
result.add(createLookupElement(element, nameWithPrefix, icon));
}
private void collectPropertiesVariants(final List<Object> result) {
private void collectPropertiesVariants(final List<Object> result, Set<String> variants) {
if (myProjectDom != null) {
for (XmlTag xmlTag : MavenDomProjectProcessorUtils.collectProperties(myProjectDom, myProject)) {
result.add(createLookupElement(xmlTag, xmlTag.getName(), PlatformIcons.PROPERTY_ICON));
String propertyName = xmlTag.getName();
if (variants.add(propertyName)) {
result.add(createLookupElement(xmlTag, propertyName, PlatformIcons.PROPERTY_ICON));
}
}
}
}
private void collectSystemEnvProperties(String propertiesFileName, @Nullable String prefix, List<Object> result) {
private void collectSystemEnvProperties(String propertiesFileName, @Nullable String prefix, List<Object> result, Set<String> variants) {
VirtualFile virtualFile = MavenPropertiesVirtualFileSystem.getInstance().findFileByPath(propertiesFileName);
PropertiesFile file = MavenDomUtil.getPropertiesFile(myProject, virtualFile);
collectPropertiesFileVariants(file, prefix, result);
collectPropertiesFileVariants(file, prefix, result, variants);
}
protected static void collectPropertiesFileVariants(@Nullable PropertiesFile file, @Nullable String prefix, List<Object> result) {
protected static void collectPropertiesFileVariants(@Nullable PropertiesFile file, @Nullable String prefix, List<Object> result, Set<String> variants) {
if (file == null) return;
for (IProperty each : file.getProperties()) {
String name = each.getKey();
if (name != null) {
if (prefix != null) name = prefix + name;
result.add(createLookupElement(each, name, PlatformIcons.PROPERTY_ICON));
if (variants.add(name)) {
result.add(createLookupElement(each, name, PlatformIcons.PROPERTY_ICON));
}
}
}
}
@@ -0,0 +1,71 @@
package org.jetbrains.idea.maven.plugins.api;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.model.MavenPlugin;
import java.util.*;
/**
* @author Sergey Evdokimov
*/
public class MavenModelPropertiesPatcher {
private static volatile Map<String, Map<String, String[]>> ourMap;
private static Map<String, Map<String, String[]>> getMap() {
Map<String, Map<String, String[]>> res = ourMap;
if (res == null) {
res = new HashMap<String, Map<String, String[]>>();
for (MavenPluginDescriptor pluginDescriptor : MavenPluginDescriptor.EP_NAME.getExtensions()) {
if (pluginDescriptor.properties != null && pluginDescriptor.properties.length > 0) {
Pair<String, String> pluginId = MavenPluginDescriptor.parsePluginId(pluginDescriptor.mavenId);
String[] properties = new String[pluginDescriptor.properties.length];
for (int i = 0; i < pluginDescriptor.properties.length; i++) {
properties[i] = pluginDescriptor.properties[i].name;
}
Map<String, String[]> groupMap = res.get(pluginId.second);// pluginId.second is artifactId
if (groupMap == null) {
groupMap = new HashMap<String, String[]>();
res.put(pluginId.second, groupMap);
}
groupMap.put(pluginId.first, properties); // pluginId.first is groupId
}
}
ourMap = res;
}
return res;
}
/*
* Add properties those should be added by plugins.
*/
public static void patch(Properties modelProperties, @Nullable Collection<MavenPlugin> plugins) {
if (plugins == null) return;
Map<String, Map<String, String[]>> map = getMap();
for (MavenPlugin plugin : plugins) {
Map<String, String[]> groupMap = map.get(plugin.getArtifactId());
if (groupMap != null) {
String[] properties = groupMap.get(plugin.getGroupId());
if (properties != null) {
for (String property : properties) {
if (!modelProperties.containsKey(property)) {
modelProperties.setProperty(property, "");
}
}
}
}
}
}
}
@@ -17,6 +17,7 @@ package org.jetbrains.idea.maven.plugins.api;
import com.intellij.openapi.extensions.AbstractExtensionPointBean;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.util.Pair;
import com.intellij.util.xml.Required;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Attribute;
@@ -38,9 +39,17 @@ public class MavenPluginDescriptor extends AbstractExtensionPointBean {
@AbstractCollection(surroundWithTag = false)
public Param[] params;
/**
* @author Sergey Evdokimov
*/
@Property(surroundWithTag = false)
@AbstractCollection(surroundWithTag = false)
public ModelProperty[] properties;
@Tag("property")
public static class ModelProperty {
@Attribute("name")
@Required
public String name;
}
@Tag("param")
public static class Param {
@@ -58,4 +67,14 @@ public class MavenPluginDescriptor extends AbstractExtensionPointBean {
public String refProvider;
}
public static Pair<String, String> parsePluginId(String mavenId) {
int idx = mavenId.indexOf(':');
if (idx <= 0 || idx == mavenId.length() - 1 || mavenId.lastIndexOf(':') != idx) {
throw new RuntimeException("Failed to parse mavenId: " + mavenId + " (mavenId should has format 'groupId:artifactId')");
}
return new Pair<String, String>(mavenId.substring(0, idx), mavenId.substring(idx + 1));
}
}
@@ -63,7 +63,9 @@ public class MavenPluginParamReferenceContributor extends PsiReferenceContributo
res = new HashMap<String, Map>();
for (MavenPluginDescriptor pluginDescriptor : MavenPluginDescriptor.EP_NAME.getExtensions()) {
Pair<String, String> pluginId = parsePluginId(pluginDescriptor.mavenId);
if (pluginDescriptor.params == null) continue;
Pair<String, String> pluginId = MavenPluginDescriptor.parsePluginId(pluginDescriptor.mavenId);
for (MavenPluginDescriptor.Param param : pluginDescriptor.params) {
String[] paramPath = param.name.split("/");
@@ -93,15 +95,6 @@ public class MavenPluginParamReferenceContributor extends PsiReferenceContributo
return res;
}
private static Pair<String, String> parsePluginId(String mavenId) {
int idx = mavenId.indexOf(':');
if (idx <= 0 || idx == mavenId.length() - 1 || mavenId.lastIndexOf(':') != idx) {
throw new RuntimeException("Failed to parse mavenId: " + mavenId + " (mavenId should has format 'groupId:artifactId')");
}
return new Pair<String, String>(mavenId.substring(0, idx), mavenId.substring(idx + 1));
}
@NotNull
private static <K, V extends Map> V getOrCreate(Map map, K key) {
Map res = (Map)map.get(key);
@@ -37,6 +37,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.importing.MavenExtraArtifactType;
import org.jetbrains.idea.maven.importing.MavenImporter;
import org.jetbrains.idea.maven.model.*;
import org.jetbrains.idea.maven.plugins.api.MavenModelPropertiesPatcher;
import org.jetbrains.idea.maven.server.MavenEmbedderWrapper;
import org.jetbrains.idea.maven.server.NativeMavenProjectHolder;
import org.jetbrains.idea.maven.utils.*;
@@ -154,6 +155,8 @@ public class MavenProject {
doSetResolvedAttributes(newState, readerResult, resetArtifacts);
MavenModelPropertiesPatcher.patch(newState.myProperties, newState.myPlugins);
newState.myModulesPathsAndNames = collectModulePathsAndNames(model, getDirectory());
Collection<String> newProfiles = collectProfilesIds(model.getProfiles());
if (resetProfiles || newState.myProfilesIds == null) {
@@ -147,6 +147,14 @@
<pluginDescriptor mavenId="org.apache.maven.plugins:maven-surefire-plugin">
<param name="additionalClasspathElements/additionalClasspathElement" refProvider="org.jetbrains.idea.maven.plugins.api.common.MavenCommonParamReferenceProviders$DirPath"/>
</pluginDescriptor>
<pluginDescriptor mavenId="ru.concerteza.buildnumber:maven-jgit-buildnumber-plugin">
<property name="git.revision"/>
<property name="git.buildnumber"/>
<property name="git.commitsCount"/>
<property name="git.tag"/>
<property name="git.branch"/>
</pluginDescriptor>
</extensions>
<application-components>
@@ -0,0 +1,109 @@
package org.jetbrains.idea.maven.plugins.jgitBuildnumber;
import org.jetbrains.idea.maven.dom.MavenDomTestCase;
import java.io.IOException;
import java.util.List;
/**
* @author Sergey Evdokimov
*/
public class JGitBuildNumberTest extends MavenDomTestCase {
public void testCompletion() throws Exception {
importProject("<groupId>test</groupId>\n" +
"<artifactId>project</artifactId>\n" +
"<version>1</version>\n" +
"<properties>\n" +
" <aaa>${}</aaa>" +
"</properties>\n" +
" <build>\n" +
" <plugins>\n" +
" <plugin>\n" +
" <groupId>ru.concerteza.buildnumber</groupId>\n" +
" <artifactId>maven-jgit-buildnumber-plugin</artifactId>\n" +
" </plugin>\n" +
" </plugins>\n" +
" </build>\n"
);
createProjectPom("<groupId>test</groupId>\n" +
"<artifactId>project</artifactId>\n" +
"<version>1</version>\n" +
"<properties>\n" +
" <aaa>${<caret>}</aaa>" +
"</properties>\n" +
" <build>\n" +
" <plugins>\n" +
" <plugin>\n" +
" <groupId>ru.concerteza.buildnumber</groupId>\n" +
" <artifactId>maven-jgit-buildnumber-plugin</artifactId>\n" +
" </plugin>\n" +
" </plugins>\n" +
" </build>\n"
);
List<String> variants = getCompletionVariants(myProjectPom);
assertContain(variants, "git.commitsCount");
}
public void testHighlighting() throws Exception {
importProject("<groupId>test</groupId>\n" +
"<artifactId>project</artifactId>\n" +
"<version>1</version>\n" +
"<properties>\n" +
" <aaa>${git.commitsCount}</aaa>" +
" <bbb>${git.commitsCount__}</bbb>" +
"</properties>\n" +
" <build>\n" +
" <plugins>\n" +
" <plugin>\n" +
" <groupId>ru.concerteza.buildnumber</groupId>\n" +
" <artifactId>maven-jgit-buildnumber-plugin</artifactId>\n" +
" </plugin>\n" +
" </plugins>\n" +
" </build>\n"
);
createProjectPom("<groupId>test</groupId>\n" +
"<artifactId>project</artifactId>\n" +
"<version>1</version>\n" +
"<properties>\n" +
" <aaa>${git.commitsCount}</aaa>" +
" <bbb>${<error>git.commitsCount__</error>}</bbb>" +
"</properties>\n" +
" <build>\n" +
" <plugins>\n" +
" <plugin>\n" +
" <groupId>ru.concerteza.buildnumber</groupId>\n" +
" <artifactId>maven-jgit-buildnumber-plugin</artifactId>\n" +
" </plugin>\n" +
" </plugins>\n" +
" </build>\n"
);
checkHighlighting(myProjectPom);
}
public void testNoPluginHighlighting() throws Exception {
importProject("<groupId>test</groupId>\n" +
"<artifactId>project</artifactId>\n" +
"<version>1</version>\n" +
"<properties>\n" +
" <aaa>${git.commitsCount}</aaa>" +
"</properties>\n"
);
createProjectPom("<groupId>test</groupId>\n" +
"<artifactId>project</artifactId>\n" +
"<version>1</version>\n" +
"<properties>\n" +
" <aaa>${<error>git.commitsCount</error>}</aaa>" +
"</properties>\n");
checkHighlighting(myProjectPom);
}
}