Passing parameter to <ice:rowSelector>'s clickListener attribute - icefaces

I'm trying to use the IceFaces (+ Seam 3 Framework on Jboss AS7) "ice:rowSelector" tag in a way that when a dataTable's row is cliked, the data in that row will be show in a "ice:panelGrid" tag with "ice:outputLabel"s.
I'm setting the clickListener as in some examples around, like this:
<ice:rowSelector immediate="true" clickListener="#{categoryController.selectionListener}"/>
the method is:
public void selectionListener(ClickActionEvent clickActionEvent) {
selectedCategory= categories.get(clickActionEvent.getRow());
}
being "categories"
List<Category> categories
But when I test the app, I get a javax.el.MethodNotFoundException exception. Then I add the "()"s to the method call (clickListener="#{categoryController.selectionListener()}"), getting the same exception.
Finally, I set clickListener="#{categoryController.selectionListener(clickActionEvent)}" and the method is called BUT "clickActionEvent" makes it throw NullPointException. The relevant part is:
Caused by: javax.el.ELException: /showCategory.xhtml #20,114 clickListener="#{categoryController.selectionListener(clickActionEvent)}": java.lang.NullPointerException
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:111) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.icesoft.faces.component.facelets.MethodExpressionMethodBinding.invoke(IceComponentHandler.java:231) [icefaces-compat-3.0.1.jar:]
at com.icesoft.faces.component.ext.RowSelector.broadcast(RowSelector.java:530) [icefaces-compat-3.0.1.jar:]
at org.icefaces.impl.component.UISeriesBase.broadcast(UISeriesBase.java:481) [icefaces-3.0.1.jar:]
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:935) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78) [jsf-impl-2.1.7-jbossorg-2.jar:]
... 29 more
Caused by: java.lang.NullPointerException
My question is: what should I pass as ClickActionEvent parameter to the "selectionListener" method?

what should I pass as ClickActionEvent parameter to the
"selectionListener" method?
Pass RowSelectorEvent.

Related

Scala Play 2.5 How to make Java's Context/Session/Request accessible to a view?

I'm working on this Scala play-authenticate-usage-scala project where I build on top of a Java framework play-authenticate (I know, life is not perfect ...). While running the application I see the exception included below.
Carefully inspecting the stack trace leads me to the view views._providerPartial.scala.html that is using the forProviders.scala.html template that in turns uses classes that depend on Java's Play play.mvc.Http.{ Session, Context, etc} and thus, the error because my sample application brings the Scala play.api.mvc._ ones.
I know I can do in Scala:
import play.core.j.JavaHelpers
val jContext : play.mvc.Http.Context = JavaHelpers.createJavaContext(request)
val jSession : play.mvc.Http.Session = context.session()
The question is how can I make these above implicitly available to that view.
[error] application -
! #72ef8b5j8 - Internal server error, for (GET) [/login] ->
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[RuntimeException: There is no HTTP Context available from here.]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:293)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:220)
at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:100)
at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:346)
at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:345)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
Caused by: java.lang.RuntimeException: There is no HTTP Context available from here.
at play.mvc.Http$Context.current(Http.java:62)
at play.mvc.Http$Context$Implicit.session(Http.java:330)
at com.feth.play.module.pa.views.html.forProviders_Scope0$forProviders$$anonfun$apply$1.apply(forProviders.template.scala:37)
at com.feth.play.module.pa.views.html.forProviders_Scope0$forProviders$$anonfun$apply$1.apply(forProviders.template.scala:35)
at play.twirl.api.TemplateMagic$.defining(TemplateMagic.scala:13)
at com.feth.play.module.pa.views.html.forProviders_Scope0$forProviders.apply(forProviders.template.scala:35)
at views.html._providerPartial_Scope0$_providerPartial.apply(_providerPartial.template.scala:38)
at views.html.login_Scope0$login_Scope1$login.apply(login.template.scala:74)
at controllers.Application$$anonfun$4$$anonfun$apply$4.apply(Application.scala:57)
at controllers.Application$$anonfun$4$$anonfun$apply$4.apply(Application.scala:57)
UPDATE I attempted the following but didn't work. Basically Java side expects all these in a ThreadLocal. The specific ThreadLocal instance is publicly located in play.mvc.Http.Context.current. Therefore I prepared a template helper called _adaptScalaToJava.scala.html like this:
#import be.objectify.deadbolt.scala._
#import play.core.j.JavaHelpers
#()(implicit request: AuthenticatedRequest[Any])
#play.mvc.Http.Context.current.set(JavaHelpers.createJavaContext(request))
it sets directly the jContext in the current thread and is used like this:
#_adaptScalaToJava
#forProviders(playAuth, skipCurrent) { p =>
<li>
#if(p.getKey() == "openid") {
<a href="javascript:void(0);" onclick="askOpenID('#p.getUrl()');">
} else {
<a href="#p.getUrl()">
}
#_providerIcon(p.getKey())</a>
</li>
}
but even though compiles find it still fires the same exception ...
Placing only this line before the troubling code solves the issue:
#play.mvc.Http.Context.current.set(play.core.j.JavaHelpers.createJavaContext(request))
#forProviders(playAuth, skipCurrent) { p =>
trying to make it a bit more clean i.e. that it isn't reset all the time, it is still a mystery for me why this won't work:
#if (play.mvc.Http.Context.current.get() == null) {
#play.mvc.Http.Context.current.set(play.core.j.JavaHelpers.
createJavaContext(request))
}
Seems like the play.mvc.Http.Context.current is not null ... bottom line is I need to connect with the IDE and debug the code.
UPDATE Actually this is the official way to do it:
#play.core.j.JavaHelpers.withContext(request) { jContext =>
#forProviders(playAuth, skipCurrent) { p =>
...
}
}

Scala - Playframework 2.3 - serve a partial HTML

I have an app that is a backend and does not have views. Now I have to add the "terms of service" and I my idea is to serve a partial HTML. I do not want to have all the HTML because then I will embed this in different places (WEB and Mobile).
this is my view
#{
<h1>Hello world!!!</h1>
}
My controller
object TosEndpoints extends Controller {
def get() = PublicApi.async {
Ok(views.html.tos("Terms of service"))
}
}
my routes.conf
GET /tos controllers.TosEndpoints.get()
I can not serve the content of the view
I get for example this error
app/views/tos.html.scala:1: identifier expected but '{' found.
[error] #{
UPDATE
If I remove the arguments I get the same error.
If I pass one argument and bind it in the view (as suggested #AliDehghani) I get this error
app/views/tos.html.scala:1: ')' expected but ':' found.
[error] #(tos: String)
The problem is that you're calling the view with too many arguments. You should either fix the render part by removing the extra argument:
Ok(views.html.tos())
Or change your view in a way that it accepts the passed argument, something like following:
#(tos: String)
<h1>Hello world!!!</h1>
<p>#tos</p>
Then you can render the view by:
Ok(views.html.tos("Terms of service"))

Xtext linking service and derived state

I have this grammar:
Feature returns ecore::EStructuralFeature:
{Feature} name=ID ':' (fp_many?='*')? eType=[ecore::EClassifier];
And the EClass:
Class returns ecore::EClass:
{EClassClass}
name=ID (interface?=':Api')?
(BEGIN
(eStructuralFeatures+=Feature)*
(eOperations+=Operation)*
END)?;
My goal is to have a DSL for textual Ecore mm with a YAML like syntax, so I need to convert the Feature object depending on its EType to either an EAttribute or an EReference.
I have tried to hook the afterModelLinked in LazyLinker like this:
Queue<Feature> ftrs = Queues.newArrayDeque(features);
Feature f = null;
while ((f = ftrs.poll()) != null) {
if (f.getEType() == null)
continue;
if (f.getEType() instanceof EDataType) {
createEAttribute(eClazz, f);
} else if (f.getEType() instanceof EClass) {
createEReference(eClazz, f);
}
eClazz.getEStructuralFeatures().remove(f);
}
This code does converts the feature to the appropriate type but I get an error with the validation service an here the stack trace:
org.eclipse.emf.common.util.WrappedException: java.lang.NullPointerException
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:233)
at org.eclipse.xtext.resource.persistence.StorageAwareResource.getEObject(StorageAwareResource.java:124)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.doResolveLazyCrossReference(LazyLinkingResource.java:192)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.resolveLazyCrossReference(LazyLinkingResource.java:151)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.resolveLazyCrossReferences(LazyLinkingResource.java:137)
at org.eclipse.xtext.EcoreUtil2.resolveLazyCrossReferences(EcoreUtil2.java:528)
at org.eclipse.xtext.validation.ResourceValidatorImpl.resolveProxies(ResourceValidatorImpl.java:163)
at org.eclipse.xtext.validation.ResourceValidatorImpl.validate(ResourceValidatorImpl.java:75)
at org.eclipse.xtext.ui.editor.validation.ValidationJob$1.exec(ValidationJob.java:91)
at org.eclipse.xtext.ui.editor.validation.ValidationJob$1.exec(ValidationJob.java:1)
at org.eclipse.xtext.util.concurrent.CancelableUnitOfWork.exec(CancelableUnitOfWork.java:26)
at org.eclipse.xtext.resource.OutdatedStateManager.exec(OutdatedStateManager.java:121)
at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.internalReadOnly(XtextDocument.java:520)
at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.readOnly(XtextDocument.java:492)
at org.eclipse.xtext.ui.editor.model.XtextDocument.readOnly(XtextDocument.java:133)
at org.eclipse.xtext.ui.editor.validation.ValidationJob.createIssues(ValidationJob.java:86)
at org.eclipse.xtext.ui.editor.validation.ValidationJob.run(ValidationJob.java:67)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: java.lang.NullPointerException
at org.eclipse.xtext.linking.impl.ImportedNamesAdapter.find(ImportedNamesAdapter.java:34)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getImportedNamesAdapter(DefaultLinkingService.java:95)
at com.eacg.dsl.faml.linker.FamlLinkingService.getImportedNamesAdapter(FamlLinkingService.java:53)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.registerImportedNamesAdapter(DefaultLinkingService.java:86)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.registerImportedNamesAdapter(DefaultLinkingService.java:90)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.registerImportedNamesAdapter(DefaultLinkingService.java:80)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getScope(DefaultLinkingService.java:58)
at com.eacg.dsl.faml.linker.FamlLinkingService.getScope(FamlLinkingService.java:47)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getLinkedObjects(DefaultLinkingService.java:119)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:250)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:225)
When debugging I found that it's still using in context the object Feature even if I have removed it when I created the mapping.
My question is this: How to safely replace the object Feature without corrupting my model. I've also tried to implement IDerivedStateComputer but got the some error.
I think the underlying problem here is that EMF is a graph-based format; classes can be features of other classes, arguments to operations, etc. In general, this graph of relations can contain loops, cycles and knots. So anything that tries to modify things in-place is going to be tricky, requiring a full-blown graph traversal algorithm to make sure you don't change something depended on by something you haven't processed yet.
The alternative is to let the model load and link in it's native form, and then transform it as a single pass. This is the way xcore implements things; the equivalent declaration is:
XClass:
{XClass}
(annotations+=XAnnotation)*
((abstract?='abstract'? 'class') | interface?= 'interface') name = ID
('<' typeParameters+=XTypeParameter (',' typeParameters+=XTypeParameter)* '>')?
('extends' superTypes+=XGenericType (',' superTypes+=XGenericType)*)?
('wraps' instanceType=JvmTypeReference) ?
'{'
(members+=XMember)*
'}'
;
Note all the X's, those are local model classes. Then later on, there is just a function:
protected EClass getEClass(final XClass xClass)

CodeModel / Jinvocation with JMethod.body()

I have the next JInvocation:
JInvocation jInvoke = JExpr.invoke(anotherPageInstance, method);
where anotherPageInstance is JVar and method is JMethod.
I do some actions on this JInvocation, and then I want to add it to test.body().invoke where test is JMethod.
The main problem is that I can't, because test.body().invoke has no option to get JInvocation as argument.
I can do the next: test.body().invoke(anotherPageInstance, method), but this doesn't help me, because I want to save the JInvocation, and just when some conditions are taking place, add this Jinvocation to the body (and as I mentions before, meanwhile I do some action on this JInvocation).
Any help?
You can add an invocation the body (JBlock) by using the add() method:
test.body().add(jInvoke);
Instead of instantiating JInvocation with JExpr.invoke(), use the JExpr factory methods:
public static JInvocation invoke(JExpression lhs,
JMethod method)
public static JInvocation invoke(JExpression lhs,
String method)
See JExpr.

Cannot access the parameter of a Menu.param from a Lift Snippet

I'm trying to extract the parameter from a Lift Menu.param within a snippet so that I can use it to create a named Comet. However, I get a NullPointerException when I try to pass the parameter to the snippet using SnippetDisptach in my Boot.scala, as suggested here:
http://comments.gmane.org/gmane.comp.web.lift/44299
I've created the Menu item as follows:
object AnItemPage {
// create a parameterized page
def menu = Menu.param[Item]("Item", "Item",
s => fetchItem(s), item => item._id.toString) / "item"
private def fetchItem(s:String) : Box[Item] = synchronized {
ItemDAO.findById(ObjectId.massageToObjectId(s))
}
}
I've added the menu to SiteMap. I've also created a Snippet which I would like to pick up the Item parameter. (I'm using fmpwizard's InsertNamedComet library here):
class AddCometItemPage(boxedItem: Box[Item]) extends InsertNamedComet with DispatchSnippet{
val item : Item = boxedItem.openOr(null)
override lazy val name= "comet_item_" + item._id.toString
override lazy val cometClass= "UserItemCometActor"
def dispatch = null
}
My next step is to crate an instance of this class as demonstrated by David Pollak here:
http://comments.gmane.org/gmane.comp.web.lift/44299
This is what I have added to my Boot.scala:
LiftRules.snippetDispatch.append {
case "item_page" => new AddCometItemPage(AnItemPage.menu.currentValue)
}
My item.html references this snippet:
<div class="lift:item_page">
I get the following null pointer exception when I compile and run this:
Exception occurred while processing /item/5114eb4044ae953cf863b786
Message: java.lang.NullPointerException
net.liftweb.sitemap.Loc$class.siteMap(Loc.scala:147)
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.siteMap(Menu.scala:170)
net.liftweb.sitemap.Loc$class.allParams(Loc.scala:123)
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.allParams(Menu.scala:170)
net.liftweb.sitemap.Loc$class.net$liftweb$sitemap$Loc$$staticValue(Loc.scala:87)
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.net$liftweb$sitemap$Loc$$staticValue(Menu.scala:170)
net.liftweb.sitemap.Loc$$anonfun$paramValue$2.apply(Loc.scala:85)
net.liftweb.sitemap.Loc$$anonfun$paramValue$2.apply(Loc.scala:85)
net.liftweb.common.EmptyBox.or(Box.scala:646)
net.liftweb.sitemap.Loc$class.paramValue(Loc.scala:85)
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.paramValue(Menu.scala:170)
net.liftweb.sitemap.Loc$$anonfun$currentValue$3.apply(Loc.scala:114)
net.liftweb.sitemap.Loc$$anonfun$currentValue$3.apply(Loc.scala:114)
net.liftweb.common.EmptyBox.or(Box.scala:646)
net.liftweb.sitemap.Loc$class.currentValue(Loc.scala:114)
net.liftweb.sitemap.Menu$ParamMenuable$$anon$9.currentValue(Menu.scala:170)
bootstrap.liftweb.Boot$$anonfun$lift$8.apply(Boot.scala:107)
bootstrap.liftweb.Boot$$anonfun$lift$8.apply(Boot.scala:106)
net.liftweb.util.NamedPF$$anonfun$applyBox$1.apply(NamedPartialFunction.scala:97)
net.liftweb.util.NamedPF$$anonfun$applyBox$1.apply(NamedPartialFunction.scala:97)
net.liftweb.common.Full.map(Box.scala:553)
net.liftweb.util.NamedPF$.applyBox(NamedPartialFunction.scala:97)
net.liftweb.http.LiftRules.snippet(LiftRules.scala:711)
net.liftweb.http.LiftSession$$anonfun$net$liftweb$http$LiftSession$$findSnippetInstance$1.apply(LiftSession.scala:1506)
net.liftweb.http.LiftSession$$anonfun$net$liftweb$http$LiftSession$$findSnippetInstance$1.apply(LiftSession.scala:1506)
net.liftweb.common.EmptyBox.or(Box.scala:646)
net.liftweb.http.LiftSession.net$liftweb$http$LiftSession$$findSnippetInstance(LiftSession.scala:1505)
net.liftweb.http.LiftSession$$anonfun$locateAndCacheSnippet$1$1$$anonfun$apply$88.apply(LiftSession.scala:1670)
net.liftweb.http.LiftSession$$anonfun$locateAndCacheSnippet$1$1$$anonfun$apply$88.apply(LiftSession.scala:1669)
Has anybody any idea where I'm going wrong? I've not been able to find a lot of information on Menu.param.
Thank you very much for your help.
f
I have never tried what you are doing, so I am not sure the best way to accomplish it. The way you are using the Loc Param, you are extracting a variable from a URL pattern. In your case, http://server/item/ITEMID where ITEMID is the string representation of an Item, and which is the value that gets passed to the fetchItem function. The function call will not have a value if you just arbitrarily call it, and from what I can see you are requesting a value that is not initialized.
I would think there are two possible solutions. The first would be to use S.location instead of AnItemPage.menu.currentValue. It will return a Box[Loc[Any]] representing the Loc that is currently being accessed (with the parameters set). You can use that Loc to retrive currentValue and set your parameter.
The other option would be to instantiate the actor in your snippet. Something like this:
item.html
<div data-lift="AnItemPage">
<div id="mycomet"></div>
</div>
And then in your AnItemPage snippet, something like this:
class AnItemPage(item: Item) {
def render = "#mycomet" #> new AddCometItemPage(item).render
}
I haven't tested either of those, so they'll probably need some tweaking. Hopefully it will give you a general idea.