Refactoring of language injection

This commit is contained in:
Sergey Evdokimov
2013-01-03 23:40:39 +04:00
parent 9a683bbc4a
commit a0a81e3562
9 changed files with 335 additions and 355 deletions
@@ -0,0 +1,53 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.maven.plugins.api;
import com.intellij.lang.Language;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.InjectedLanguagePlaces;
import com.intellij.psi.LanguageInjector;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.xml.XmlText;
import com.intellij.util.PairProcessor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.model.MavenDomConfiguration;
/**
* @author Sergey Evdokimov
*/
public final class MavenPluginConfigurationLanguageInjector implements LanguageInjector {
@Override
public void getLanguagesToInject(@NotNull final PsiLanguageInjectionHost host, @NotNull final InjectedLanguagePlaces injectionPlacesRegistrar) {
if (!(host instanceof XmlText)) return;
XmlText xmlText = (XmlText)host;
if (!MavenPluginParamInfo.isSimpleText(xmlText)) return;
MavenPluginParamInfo.processParamInfo(xmlText, new PairProcessor<MavenPluginParamInfo.ParamInfo, MavenDomConfiguration>() {
@Override
public boolean process(MavenPluginParamInfo.ParamInfo info, MavenDomConfiguration configuration) {
Language language = info.getLanguage();
if (language != null) {
injectionPlacesRegistrar.addPlace(language, TextRange.from(0, host.getTextLength()), null, null);
return false;
}
return true;
}
});
}
}
@@ -66,6 +66,11 @@ public class MavenPluginDescriptor extends AbstractExtensionPointBean {
@Attribute("refProvider")
public String refProvider;
/**
* Language to inject.
*/
@Attribute("language")
public String language;
}
public static Pair<String, String> parsePluginId(String mavenId) {
@@ -0,0 +1,243 @@
package org.jetbrains.idea.maven.plugins.api;
import com.intellij.lang.Language;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlText;
import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.PairProcessor;
import com.intellij.util.ProcessingContext;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.model.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author Sergey Evdokimov
*/
public class MavenPluginParamInfo {
private static final Logger LOG = Logger.getInstance(MavenPluginParamInfo.class);
/**
* This map contains descriptions of all plugins.
*/
private static volatile Map<String, Map> myMap;
public static Map<String, Map> getMap() {
Map<String, Map> res = myMap;
if (res == null) {
res = new HashMap<String, Map>();
for (MavenPluginDescriptor pluginDescriptor : MavenPluginDescriptor.EP_NAME.getExtensions()) {
if (pluginDescriptor.params == null) continue;
Pair<String, String> pluginId = MavenPluginDescriptor.parsePluginId(pluginDescriptor.mavenId);
for (MavenPluginDescriptor.Param param : pluginDescriptor.params) {
String[] paramPath = param.name.split("/");
Map pluginsMap = res;
for (int i = paramPath.length - 1; i >= 0; i--) {
pluginsMap = getOrCreate(pluginsMap, paramPath[i]);
}
ParamInfo paramInfo = new ParamInfo(pluginDescriptor.getPluginDescriptor().getPluginClassLoader(), param);
Map<String, ParamInfo> goalsMap = getOrCreate(pluginsMap, pluginId);
ParamInfo oldValue = goalsMap.put(param.goal, paramInfo);
if (oldValue != null) {
LOG.error("Duplicated maven plugin parameter descriptor: "
+ pluginId.first + ':' + pluginId.second + " -> "
+ (param.goal != null ? "[" + param.goal + ']' : "") + param.name);
}
}
}
myMap = res;
}
return res;
}
@NotNull
private static <K, V extends Map> V getOrCreate(Map map, K key) {
Map res = (Map)map.get(key);
if (res == null) {
res = new HashMap();
map.put(key, res);
}
return (V)res;
}
public static boolean isSimpleText(@NotNull XmlText paramValue) {
PsiElement prevSibling = paramValue.getPrevSibling();
if (!(prevSibling instanceof LeafPsiElement) || ((LeafPsiElement)prevSibling).getElementType() != XmlTokenType.XML_TAG_END) {
return false;
}
PsiElement nextSibling = paramValue.getNextSibling();
if (!(nextSibling instanceof LeafPsiElement) || ((LeafPsiElement)nextSibling).getElementType() != XmlTokenType.XML_END_TAG_START) {
return false;
}
return true;
}
public static void processParamInfo(@NotNull XmlText paramValue, @NotNull PairProcessor<ParamInfo, MavenDomConfiguration> processor) {
XmlTag paramTag = paramValue.getParentTag();
if (paramTag == null) return;
XmlTag configurationTag = paramTag;
DomElement domElement;
Map m = getMap().get(paramTag.getName());
while (true) {
if (m == null) return;
configurationTag = configurationTag.getParentTag();
if (configurationTag == null) return;
String tagName = configurationTag.getName();
if ("configuration".equals(tagName)) {
domElement = DomManager.getDomManager(configurationTag.getProject()).getDomElement(configurationTag);
if (domElement instanceof MavenDomConfiguration) {
break;
}
if (domElement != null) return;
}
m = (Map)m.get(tagName);
}
Map<Pair<String, String>, Map<String, ParamInfo>> pluginsMap = m;
MavenDomConfiguration domCfg = (MavenDomConfiguration)domElement;
MavenDomPlugin domPlugin = domCfg.getParentOfType(MavenDomPlugin.class, true);
if (domPlugin == null) return;
String pluginGroupId = domPlugin.getGroupId().getStringValue();
String pluginArtifactId = domPlugin.getArtifactId().getStringValue();
Map<String, ParamInfo> goalsMap;
if (pluginGroupId == null) {
goalsMap = pluginsMap.get(Pair.create("org.apache.maven.plugins", pluginArtifactId));
if (goalsMap == null) {
goalsMap = pluginsMap.get(Pair.create("org.codehaus.mojo", pluginArtifactId));
}
}
else {
goalsMap = pluginsMap.get(Pair.create(pluginGroupId, pluginArtifactId));
}
if (goalsMap == null) return;
DomElement parent = domCfg.getParent();
if (parent instanceof MavenDomPluginExecution) {
MavenDomGoals goals = ((MavenDomPluginExecution)parent).getGoals();
for (MavenDomGoal goal : goals.getGoals()) {
ParamInfo info = goalsMap.get(goal.getStringValue());
if (info != null) {
if (!processor.process(info, domCfg)) return;
}
}
}
ParamInfo defaultInfo = goalsMap.get(null);
if (defaultInfo != null) {
if (!processor.process(defaultInfo, domCfg)) return;
}
}
public static class ParamInfo {
private final ClassLoader myClassLoader;
private final String myProviderClass;
private volatile String myLanguageId;
private Language myLanguageInstance;
private volatile MavenParamReferenceProvider myProviderInstance;
private ParamInfo(ClassLoader classLoader, MavenPluginDescriptor.Param param) {
myClassLoader = classLoader;
myProviderClass = param.refProvider;
myLanguageId = param.language;
}
public Language getLanguage() {
if (myLanguageInstance != null) {
return myLanguageInstance;
}
String languageId = myLanguageId;
if (languageId == null) return null;
Language l = Language.findLanguageByID(languageId);
if (l == null) { // May be plugin with language is disabled.
myLanguageId = null;
}
else {
myLanguageInstance = l;
}
return l;
}
public MavenParamReferenceProvider getProviderInstance() {
if (myProviderClass == null) {
return null;
}
MavenParamReferenceProvider res = myProviderInstance;
if (res == null) {
Object instance;
try {
instance = myClassLoader.loadClass(myProviderClass).newInstance();
}
catch (Exception e) {
throw new RuntimeException("Failed to create reference provider instance", e);
}
if (instance instanceof MavenParamReferenceProvider) {
res = (MavenParamReferenceProvider)instance;
}
else {
final PsiReferenceProvider psiReferenceProvider = (PsiReferenceProvider)instance;
res = new MavenParamReferenceProvider() {
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element,
@NotNull MavenDomConfiguration domCfg,
@NotNull ProcessingContext context) {
return psiReferenceProvider.getReferencesByElement(element, context);
}
};
}
myProviderInstance = res;
}
return res;
}
}
}
@@ -15,31 +15,23 @@
*/
package org.jetbrains.idea.maven.plugins.api;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.patterns.XmlPatterns;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlText;
import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.PairProcessor;
import com.intellij.util.ProcessingContext;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.model.*;
import org.jetbrains.idea.maven.dom.model.MavenDomConfiguration;
import java.util.HashMap;
import java.util.Map;
import static org.jetbrains.idea.maven.plugins.api.MavenPluginParamInfo.ParamInfo;
/**
* @author Sergey Evdokimov
*/
public class MavenPluginParamReferenceContributor extends PsiReferenceContributor {
private static final Logger LOG = Logger.getInstance(MavenPluginParamReferenceContributor.class);
@Override
public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(
@@ -51,198 +43,38 @@ public class MavenPluginParamReferenceContributor extends PsiReferenceContributo
private static class MavenPluginParamRefProvider extends PsiReferenceProvider {
/**
* This map contains descriptions of all plugins.
*/
private volatile Map<String, Map> myMap;
public Map<String, Map> getMap() {
Map<String, Map> res = myMap;
if (res == null) {
res = new HashMap<String, Map>();
for (MavenPluginDescriptor pluginDescriptor : MavenPluginDescriptor.EP_NAME.getExtensions()) {
if (pluginDescriptor.params == null) continue;
Pair<String, String> pluginId = MavenPluginDescriptor.parsePluginId(pluginDescriptor.mavenId);
for (MavenPluginDescriptor.Param param : pluginDescriptor.params) {
String[] paramPath = param.name.split("/");
Map pluginsMap = res;
for (int i = paramPath.length - 1; i >= 0; i--) {
pluginsMap = getOrCreate(pluginsMap, paramPath[i]);
}
ParamInfo paramInfo = new ParamInfo(pluginDescriptor.getPluginDescriptor().getPluginClassLoader(), param.refProvider);
Map<String, ParamInfo> goalsMap = getOrCreate(pluginsMap, pluginId);
ParamInfo oldValue = goalsMap.put(param.goal, paramInfo);
if (oldValue != null) {
LOG.error("Duplicated maven plugin parameter descriptor: "
+ pluginId.first + ':' + pluginId.second + " -> "
+ (param.goal != null ? "[" + param.goal + ']' : "") + param.name);
}
}
}
myMap = res;
}
return res;
}
@NotNull
private static <K, V extends Map> V getOrCreate(Map map, K key) {
Map res = (Map)map.get(key);
if (res == null) {
res = new HashMap();
map.put(key, res);
}
return (V)res;
}
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull final ProcessingContext context) {
XmlText xmlText = (XmlText)element.getParent();
PsiElement prevSibling = xmlText.getPrevSibling();
if (!(prevSibling instanceof LeafPsiElement) || ((LeafPsiElement)prevSibling).getElementType() != XmlTokenType.XML_TAG_END) return PsiReference.EMPTY_ARRAY;
if (!MavenPluginParamInfo.isSimpleText(xmlText)) return PsiReference.EMPTY_ARRAY;
PsiElement nextSibling = xmlText.getNextSibling();
if (!(nextSibling instanceof LeafPsiElement) || ((LeafPsiElement)nextSibling).getElementType() != XmlTokenType.XML_END_TAG_START) return PsiReference.EMPTY_ARRAY;
class MyProcessor implements PairProcessor<ParamInfo, MavenDomConfiguration> {
PsiReference[] result;
XmlTag paramTag = xmlText.getParentTag();
if (paramTag == null) return PsiReference.EMPTY_ARRAY;
XmlTag configurationTag = paramTag;
DomElement domElement;
Map m = getMap().get(paramTag.getName());
while (true) {
if (m == null) return PsiReference.EMPTY_ARRAY;
configurationTag = configurationTag.getParentTag();
if (configurationTag == null) return PsiReference.EMPTY_ARRAY;
String tagName = configurationTag.getName();
if ("configuration".equals(tagName)) {
domElement = DomManager.getDomManager(configurationTag.getProject()).getDomElement(configurationTag);
if (domElement instanceof MavenDomConfiguration) {
break;
@Override
public boolean process(ParamInfo info, MavenDomConfiguration domCfg) {
MavenParamReferenceProvider providerInstance = info.getProviderInstance();
if (providerInstance != null) {
result = providerInstance.getReferencesByElement(element, domCfg, context);
return false;
}
if (domElement != null) return PsiReference.EMPTY_ARRAY;
}
m = (Map)m.get(tagName);
}
Map<Pair<String, String>, Map<String, ParamInfo>> pluginsMap = m;
MavenDomConfiguration domCfg = (MavenDomConfiguration)domElement;
MavenDomPlugin domPlugin = domCfg.getParentOfType(MavenDomPlugin.class, true);
if (domPlugin == null) return PsiReference.EMPTY_ARRAY;
String pluginGroupId = domPlugin.getGroupId().getStringValue();
String pluginArtifactId = domPlugin.getArtifactId().getStringValue();
Map<String, ParamInfo> goalsMap;
if (pluginGroupId == null) {
goalsMap = pluginsMap.get(Pair.create("org.apache.maven.plugins", pluginArtifactId));
if (goalsMap == null) {
goalsMap = pluginsMap.get(Pair.create("org.codehaus.mojo", pluginArtifactId));
}
}
else {
goalsMap = pluginsMap.get(Pair.create(pluginGroupId, pluginArtifactId));
}
if (goalsMap == null) return PsiReference.EMPTY_ARRAY;
DomElement parent = domCfg.getParent();
if (parent instanceof MavenDomPluginExecution) {
MavenDomGoals goals = ((MavenDomPluginExecution)parent).getGoals();
for (MavenDomGoal goal : goals.getGoals()) {
ParamInfo info = goalsMap.get(goal.getStringValue());
if (info != null) {
MavenParamReferenceProvider providerInstance = info.getProviderInstance();
if (providerInstance != null) {
return providerInstance.getReferencesByElement(element, domCfg, context);
}
}
return true;
}
}
ParamInfo defaultInfo = goalsMap.get(null);
if (defaultInfo != null) {
MavenParamReferenceProvider providerInstance = defaultInfo.getProviderInstance();
if (providerInstance != null) {
return providerInstance.getReferencesByElement(element, domCfg, context);
}
MyProcessor processor = new MyProcessor();
MavenPluginParamInfo.processParamInfo(xmlText, processor);
if (processor.result != null) {
return processor.result;
}
return PsiReference.EMPTY_ARRAY;
}
}
private static class ParamInfo {
private final ClassLoader myClassLoader;
private final String myProviderClass;
private volatile MavenParamReferenceProvider myProviderInstance;
public ParamInfo(ClassLoader classLoader, String providerClass) {
myClassLoader = classLoader;
myProviderClass = providerClass;
}
public MavenParamReferenceProvider getProviderInstance() {
if (myProviderClass == null) {
return null;
}
MavenParamReferenceProvider res = myProviderInstance;
if (res == null) {
Object instance;
try {
instance = myClassLoader.loadClass(myProviderClass).newInstance();
}
catch (Exception e) {
throw new RuntimeException("Failed to create reference provider instance", e);
}
if (instance instanceof MavenParamReferenceProvider) {
res = (MavenParamReferenceProvider)instance;
}
else {
final PsiReferenceProvider psiReferenceProvider = (PsiReferenceProvider)instance;
res = new MavenParamReferenceProvider() {
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element,
@NotNull MavenDomConfiguration domCfg,
@NotNull ProcessingContext context) {
return psiReferenceProvider.getReferencesByElement(element, context);
}
};
}
myProviderInstance = res;
}
return res;
}
}
}
@@ -1,31 +0,0 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.maven.plugins.groovy;
import org.jetbrains.idea.maven.utils.MavenPluginConfigurationLanguageInjector;
import org.jetbrains.plugins.groovy.GroovyFileType;
import java.util.Arrays;
/**
* @author Sergey Evdokimov
*/
public class MavenGroovyInjector extends MavenPluginConfigurationLanguageInjector {
public MavenGroovyInjector() {
super("source", Arrays.asList("org.codehaus.groovy.maven", "org.codehaus.gmaven"), "gmaven-plugin", GroovyFileType.GROOVY_LANGUAGE);
}
}
@@ -1,29 +0,0 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.maven.plugins.sql;
import com.intellij.lang.Language;
import org.jetbrains.idea.maven.utils.MavenPluginConfigurationLanguageInjector;
/**
* @author Sergey Evdokimov
*/
public class MavenSqlInjector extends MavenPluginConfigurationLanguageInjector {
public MavenSqlInjector() {
super("sqlCommand", "org.codehaus.mojo", "sql-maven-plugin", Language.findLanguageByID("SQL"));
}
}
@@ -1,104 +0,0 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.maven.utils;
import com.intellij.lang.Language;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.InjectedLanguagePlaces;
import com.intellij.psi.LanguageInjector;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlText;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
/**
* @author Sergey Evdokimov
*/
public class MavenPluginConfigurationLanguageInjector implements LanguageInjector {
private final String myParameterName;
private final Collection<String> myPluginGroupIds;
private final String myPluginArtifactId;
private final Language myLanguage;
protected MavenPluginConfigurationLanguageInjector(@NotNull String parameterName,
@NotNull String pluginGroupId,
@NotNull String pluginArtifactId,
@Nullable Language language) {
this(parameterName, Collections.singleton(pluginGroupId), pluginArtifactId, language);
}
protected MavenPluginConfigurationLanguageInjector(@NotNull String parameterName,
@NotNull Collection<String> pluginGroupIds,
@NotNull String pluginArtifactId,
@Nullable Language language) {
myParameterName = parameterName;
myPluginGroupIds = pluginGroupIds;
myPluginArtifactId = pluginArtifactId;
myLanguage = language;
}
@Override
public void getLanguagesToInject(@NotNull PsiLanguageInjectionHost host, @NotNull InjectedLanguagePlaces injectionPlacesRegistrar) {
if (!(host instanceof XmlText)) return;
PsiElement sourceTag = host.getParent();
if (!isTagOfName(sourceTag, myParameterName)) return;
PsiElement configurationTag = sourceTag.getParent();
if (!isTagOfName(configurationTag, "configuration")) return;
PsiElement configurationParent = configurationTag.getParent();
PsiElement pluginTag;
if (isTagOfName(configurationParent, "execution")) {
PsiElement executionsTag = configurationParent.getParent();
if (!isTagOfName(executionsTag, "executions")) return;
pluginTag = executionsTag.getParent();
}
else {
pluginTag = configurationParent;
}
if (!isTagOfName(pluginTag, "plugin")) return;
XmlTag plugin = (XmlTag)pluginTag;
XmlTag groupId = plugin.findFirstSubTag("groupId");
if (groupId == null || !myPluginGroupIds.contains(groupId.getValue().getText().trim())) return;
XmlTag artifactId = plugin.findFirstSubTag("artifactId");
if (artifactId == null || !artifactId.getValue().getText().trim().equals(myPluginArtifactId)) return;
if (!"pom.xml".equals(plugin.getContainingFile().getName())) return;
if (myLanguage != null) { // Language can be null if specified language is in disabled plugin
injectionPlacesRegistrar.addPlace(myLanguage, TextRange.from(0, host.getTextLength()), null, null);
}
}
protected static boolean isTagOfName(@Nullable PsiElement element, String name) {
return element instanceof XmlTag && name.equals(((XmlTag)element).getName());
}
}
@@ -4,7 +4,14 @@
<importer implementation="org.jetbrains.idea.maven.importing.Groovy_1_0_Importer"/>
<importer implementation="org.jetbrains.idea.maven.importing.Groovy_1_1_plus_Importer"/>
</extensions>
<extensions xmlns="com.intellij">
<languageInjector implementation="org.jetbrains.idea.maven.plugins.groovy.MavenGroovyInjector"/>
<extensions defaultExtensionNs="org.jetbrains.idea.maven">
<pluginDescriptor mavenId="org.codehaus.groovy.maven:gmaven-plugin">
<param name="source" language="Groovy"/>
</pluginDescriptor>
<pluginDescriptor mavenId="org.codehaus.gmaven:gmaven-plugin">
<param name="source" language="Groovy"/>
</pluginDescriptor>
</extensions>
</idea-plugin>
@@ -52,7 +52,7 @@
<compiler implementation="org.jetbrains.idea.maven.compiler.MavenResourceCompiler" order="last"/>
<compileServer.plugin classpath="jps/maven-jps-plugin.jar"/>
<languageInjector implementation="org.jetbrains.idea.maven.plugins.sql.MavenSqlInjector"/>
<languageInjector implementation="org.jetbrains.idea.maven.plugins.api.MavenPluginConfigurationLanguageInjector"/>
<selectInTarget implementation="org.jetbrains.idea.maven.navigator.SelectInMavenNavigatorTarget"/>
@@ -155,6 +155,10 @@
<property name="git.tag"/>
<property name="git.branch"/>
</pluginDescriptor>
<pluginDescriptor mavenId="org.codehaus.mojo:sql-maven-plugin">
<param name="sqlCommand" language="SQL"/>
</pluginDescriptor>
</extensions>
<application-components>