Inject EL into strings

Hi. I'm trying to inject EL into some @annotation paramter. Example

class MyBean{
public Integer getIntegerValue() {
return 0;
}
}

class MyClass {
@ElAnn(expression = "bean.integerValue eq int")
public void meth() {
.....
}
public MyBean getBean() {
return new MyBean();
}
public Integer getInt() {
return 0;
}
}

Im' doing it wia InjectedLanguageManager like

InjectedLanguageManager.getInstance(project).registerMultiHostInjector(new MultiHostInjector() {
public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
PsiElement ann = context.getParent().getParent().getParent();
if (ann instanceof PsiAnnotation
&& "ElAnn".equals(((PsiAnnotation)ann).getNameReferenceElement().getCanonicalText())
&& "expression".equals(((PsiNameValuePair) context.getParent()).getName())) {
final TextRange range = new TextRange(1, context.getTextLength() - 1);
registrar.startInjecting(ELLanguage.INSTANCE)
.addPlace(null, null, (PsiLanguageInjectionHost) context, range)
.doneInjecting();
}
}

@NotNull
public List<? extends Class<? extends PsiElement>> elementsToInjectIn() {
return Arrays.asList(PsiLiteralExpression.class);
}
});

so i got highlighting and basic EL stuff working well.
My quesiton is how to make EL manager to know/resolve my bean methods to auto-compele/rsolve them. I.e. how to put my class into context of injected language ?

9 comments
Comment actions Permalink

there are several ways to add custom EL variables:

1. Use com.intellij.psi.impl.source.jsp.el.ELContextProvider

for instance,
public class ELClassInjector implements MultiHostInjector {

public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar,
@NotNull final PsiElement host) {
PsiClass psiClass = PsiTreeUtil.getParentOfType(host, PsiClass.class);
if (psiClass != null) {
if (SeamCommonUtils.isSeamClass(psiClass)) {
for (TextRange textRange : SeamELInjectorUtil.getELTextRanges(host))
{
registrar.startInjecting(ELLanguage.INSTANCE).addPlace(null, null,
(PsiLanguageInjectionHost)host, textRange)
.doneInjecting();

// put your provider in userdata
host.putUserData(ELContextProvider.ourContextProviderKey, new SeamELContextProvider(host));
// !!!!! added in diana
}
}
}
}
....

2. There are 2 extension points to add custom context variables in EL.
1. CustomJsfVariableResolverProvider: add context variables if custom Variable
Resolvers are defined in faces config. For instance, SpringJsfVariableResolverProvider
adds spring beans as context variables if "org.springframework.web.jsf.DelegatingVariableResolver"
is defined.

2. CustomJsfContextBeansProvider: add context variables too. For instance,
SeamJsfContexBeansProvider(Diana) adds JBoss Seam components.

Hi. I'm trying to inject EL into some @annotation paramter. Example

class MyBean{
public Integer getIntegerValue() {
return 0;
}
}
class MyClass {
@ElAnn(expression = "bean.integerValue eq int")
public void meth() {
....
}
public MyBean getBean() {
return new MyBean();
}
public Integer getInt() {
return 0;
}
}
Im' doing it wia InjectedLanguageManager like


InjectedLanguageManager.getInstance(project).registerMultiHostInjector
(new MultiHostInjector() {
public void getLanguagesToInject(@NotNull
MultiHostRegistrar registrar, @NotNull PsiElement context) {
PsiElement ann =
context.getParent().getParent().getParent();
if (ann instanceof PsiAnnotation
&&
"ElAnn".equals(((PsiAnnotation)ann).getNameReferenceElement().getCanon
icalText())
&& "expression".equals(((PsiNameValuePair)
context.getParent()).getName())) {
final TextRange range = new TextRange(1,
context.getTextLength() - 1);
registrar.startInjecting(ELLanguage.INSTANCE)
.addPlace(null, null,
(PsiLanguageInjectionHost) context, range)
.doneInjecting();
}
}
@NotNull
public List<? extends Class<? extends PsiElement>>
elementsToInjectIn() {
return Arrays.asList(PsiLiteralExpression.class);
}
});
so i got highlighting and basic EL stuff working well.

My quesiton is how to make EL manager to know/resolve my bean methods
to auto-compele/rsolve them. I.e. how to put my class into context of
injected language ?





0
Comment actions Permalink

1. So can i do injection of custom veriable without JSF and without Diana (writing for selena currently) ?
2. As i understood form Spring module i have to write CustomJsfVariableResolverProvider implementation to inject my variables
but questino - how to regiser it in IDEA ?

Edited by: Evgeny Shepelyuk on Apr 9, 2008 9:16 PM

0
Comment actions Permalink

In Selena one can cotribute your own beans using extension point
com.intellij.javaee.jsp.elImplicitVariablesProvider with
ElVariablesProvider abstract class implementation

Evgeny Shepelyuk wrote:

So can i do injection of custom veriable without JSF and without Diana (writing for selena currently) ?


--
Best regards,
Maxim Mossienko
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"

0
Comment actions Permalink

Sorry havent noticed your message before posting mine :)

Ok so steps to inject custom variables in SELENA are ??

implement com.intellij.psi.impl.source.jsp.el.impl.CustomJsfVariableResolverProvider

or implement ElVariablesProvider

And still is the question how to register one of those providers in IDEA to be used in injected code blocks

0
Comment actions Permalink

In plugin xml
]]>

Evgeny Shepelyuk wrote:

Sorry havent noticed your message before posting mine :)

Ok so steps to inject custom variables in SELENA are ??

implement com.intellij.psi.impl.source.jsp.el.impl.CustomJsfVariableResolverProvider

or implement ElVariablesProvider

And still is the question how to register one of those providers in IDEA to be used in injected code blocks



--
Best regards,
Maxim Mossienko
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"

0
Comment actions Permalink

Hello
Yes this approach works for EL in JSP, but i have another purpose

1) inject EL into string literals inside java class
2) inject EL into attributes of XML tags in JSP

And when doing this - i have no provider working for providing variables
Can you point what this can be when injecting the language ?

Thnx

0
Comment actions Permalink

Provider should be invoked during completion.
And IDEA 7 skips highlighting of injected EL (so you can write it yourself)

Evgeny Shepelyuk wrote:

Hello
Yes this approach works for EL in JSP, but i have another purpose

1) inject EL into string literals inside java class
2) inject EL into attributes of XML tags in JSP

And when doing this - i have no provider working for providing variables
Can you point what this can be when injecting the language ?

Thnx



--
Best regards,
Maxim Mossienko
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"

0
Comment actions Permalink

Sorry but this is for me not working. Let me try to show you te code - maybe im missing smth.

plugin.xml

.... ..... org.intellij.stripes.components.project.StripesReferencesComponent .... ]]>


StripesReferenceComponent.java
-


public class StripesReferencesComponent implements ProjectComponent {
public StripesReferencesComponent(Project project) {
registry = ReferenceProvidersRegistry.getInstance(project);
InjectedLanguageManager.getInstance(project).registerMultiHostInjector(new MultiHostInjector() {
public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) {
if (StripesReferencesComponent.STRIPES_NAMESPACE_FILTER.isAcceptable(context.getParent().getParent(), null)) {
final String name = ((XmlAttribute) context.getParent()).getName();
if ("name".equals(name)) {
final TextRange range = new TextRange(1, context.getTextLength() - 1);
registrar.startInjecting(ELLanguage.INSTANCE)
.addPlace(null, null, (PsiLanguageInjectionHost) context, range)
.doneInjecting();

}
}
}

@NotNull
public List<? extends Class<? extends PsiElement>> elementsToInjectIn() {
return Arrays.asList(XmlAttributeValue.class);
}
});

}
..........
}


index.jsp
-


<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<stripes:form bean>
<stripes:text name="1 eq 2"/>
</stripes:form>
</stripes:layout-component>
${...some el expression.....}

So according to my injector imlementation when i write code in name attribute og stripes:text tag - my veriable provider should be called.
But it's not called at all. And in that tag i don't have any implicit EL variables. Only i can see is EL operators (eq, not etc).
The same time, when i edit code in ${....} outsie of tags - variable provider is called succesfully and i'm able to add my context variables.

Also another question - am i able to remove implicit context variables from EL injected fragment ?
All of this is developed in Selena

0
Comment actions Permalink

Sorry for wakin this thread up but still can't find some answers

1. when i use this extension point
]]>

it still isn't called when i inject EL into some string literals ourside of JSP.

2. How can i remove implicit variables ? I need this in my injected language places.

I'm using Selena

Thnx a lot !

0

Please sign in to leave a comment.