JSF: invoke action after value change - jsf-2

In the bad old days in my codebase we relied quite heavily on event requeuing, which I suspect worked due to implementation details in ICEfaces or MyFaces rather than standard-specified behavior. One thing we used to do frequently was this kind of thing:
<ice:inputText value="#{bb.frequency}" valueChangeListener="#{bb.valueChanged}"/>
The goal is to arrange for retune to be called after setFrequency whenever the frequency changes.
Then we had some fairly disgusting code in the backing bean which would requeue the event. It usually looked something like this:
class BB {
// this happens first, thanks to UPDATE_MODEL_VALUES
public void setFrequency(Frequency f) {
this.model.f = f;
}
public void valueChanged(ValueChangeEvent event) {
if (event.getOldValue().equals(event.getNewValue())
return; // nothing changed, so leave
if (FacesContext.getCurrentInstance().getPhaseId() != INVOKE_APPLICATION) {
OurMagicEventUtils.requeueEvent(event, INVOKE_APPLICATION);
}
else {
// do the post-setter work here (the setter happened recently during
// UPDATE_MODEL_VALUES so we're up-to-date by here
this.model.retune();
}
}
}
This isn't a good way to live. I haven't found a reliable way to requeue events for later phases and it clearly isn't the kind of thing people do. I see two solutions:
Move the retune intelligence to the BB#setFrequency method.
I can't get away with this in many cases because I'm directly addressing a lower-level model class and I don't want to disturb its behavior for other clients.
Create a custom component and move the logic into the setFoo method there.
I don't love this because there are a lot of issues with Mojarra and custom components when embedded in other containers. It also seems like overkill for what I need to do—I literally just need to call retune after setting some properties.
Create backing beans for everything. Delegate most methods directly to the inner thing, but catch setFoo and perform the retune there. This is very similar to what we used to do, and it means a lot of boilerplate, wrappers, and glue code, so I don't love it.
In my mind I imagine something like this:
<ice:inputText value="#{bb.frequency}" afterChange=#{bb.retune}"/>
but that obviously doesn't work, nor would attaching an <f:actionListener> since that requires a class name but has no association to whatever you're currently doing, and besides it can only be set on UICommands which UIInputs are not.
What's the elegant/correct way to solve this dilemma?

As you're using JSF2 already, just use <f:ajax>.
<ice:inputText value="#{bb.frequency}">
<f:ajax listener="#{bb.retune}"/>
</ice:inputText>
with
public void retune(AjaxBehaviorEvent event) { // Note: the argument is optional.
// ...
}
This will be invoked during invoke action phase when the HTML DOM change event has occured.

Related

Subscribing to PostValidationEvent of dynamicaly created child component

For a forms framework in which I like to use JSF as the real UI frontend, I am searching for a way that a parent component gets informed if in a child component the value is changed. The facelet of a basic 'control' looks like this(body/head omitted since no-one can run it anyway without a dozen classes):
<xf:input ref="/my/xpath/value">
<xf:label>Label</xf:label>
</xf:input>
The xf:input component which I developed, dynamically creates a real ui component (PrimeFaces ones) based on the type of the value that ref="/my/xpath/value" points to. This real ui component is created in a preRenderView event like is done in this example. It is handled in the following method in the 'parent' control
#Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
FacesContext context = FacesContext.getCurrentInstance();
if (!context.isPostback()) {
control = createControl(context);
//context.getApplication().unsubscribeFromEvent(PostValidateEvent.class, getControl().getClass(), this);
control.subscribeToEvent(PostValidateEvent.class, this);
}
}
The actual controls all have an programmatically added ajax handler added to it, which makes it possible to just process the specific input ('implicit ajax'). Default JSF component validations are normally applied and this all works great.
The issue/challenge is that in this 'wrapper' component I'd like to be informed of value changes after the validation. My first idea was to us the subscribeEvent on the dynamically added control like this:
control.subscribeToEvent(PostValidateEvent.class, this);
The subscribing works, but on the postback, an NPE is thrown in the UIComponent (Mojarra 2.2.9) because the wrapped is null in the following method
public boolean isListenerForSource(Object component) {
if (wrapped instanceof SystemEventListener) {
return ((SystemEventListener) wrapped).isListenerForSource(component);
} else {
return instanceClass.isAssignableFrom(component.getClass());
}
}
This might be because the actual component seems to be newly created when the data is submitted en hence the 'subscription' is lost.
Registering on the ViewRoot does not work since the source of the event is always the ViewRoot and registering on the Application is plain wrong.
It might be that I'm looking for a solution in the wrong direction but for now I'm clueless. Keep in mind that I have no direct control over the created ui controls, nor do I want to override their renderers if I can prevent to. So signalling the parent from the child control is not an option to.
Other things I tried:
Using valueChangeListeners but that did not work either with lots of other problems (including ways to make it extensible)
Using composite components with binding but that failed including them dynamically, requiring naming containers that conflict with the id's required by the rest of the framework, the positions of labels, hints and alerts in the xhtml and/or resulting dom
Taghandlers to manipulate the tree when creating them
This all is with Mojarra up to 2.2.9 (did not check newer yet or MyFaces)
Adding the component in the PreRenderViewEvent works nicely. The thing is that you do not seem to be able to have subscriptions to events survive a request. The actual components are recreated (in the RestoreViewPhase I assume, did not check) and then the subscription to the event is still there, just the 'wrapped' context where it should be called is empty.
Adding the PostValidationEvent event in the PostRestoreStateEvent of this specific component (it is the only one in the FacesContext.getCurrentInstance().getPartialViewContext().getExecuteIds()) makes it fire as mentioned in the comments. The trick (hack/workaround/...) to get rid of the NPE in the next request is to actually remove the event again.
((UIComponent) event.getSource()).unsubscribeFromEvent(PostValidateEvent.class, this);
I'll try to create an example without any PrimeFaces or OmniFaces and see what happens then since they both seem to be wrappers around the context and I want to make sure they are not the cause of the behaviour.

Using NonEmptyNavigator.metaClass.invokeMethod { ... } to introduce short pause after field set

In my application, some of the Geb tests are a bit flaky since we're firing off an ajax validation http request after each form field changes. If the ajax call doesn't return fast enough, the test blows up.
I wanted to test a simple solution for this, which (rightly or wrongly, let's not get into that debate here...) is to introduce a short 100ms or so pause after each field is set, so I started looking at how & where I could make this happen.
It looks like I need to add a Thread.sleep after the NonEmptyNavigator.setInputValue and NonEmptyNavigator.setSelectValue methods are invoked. I created a subclass of GebSpec, into which I added a static initializer block:
static {
NonEmptyNavigator.metaClass.invokeMethod = { String name, args ->
def m = delegate.metaClass.getMetaMethod(name, *args)
def result = (m ? m.invoke(delegate, *args) : delegate.metaClass.invokeMissingMethod(delegate, name, args))
if ("setInputValue".equals(name) || "setSelectValue".equals(name)) {
Thread.sleep(100)
}
return result
}
}
However I added some debug logging, and I noticed that when I execute my spec I never hit this code. What am I doing wrong here...?
I know you asked not to get into a debate about putting sleeps whenever you set a form element value but I just want to assure you that this is really something you don't want to do. There are two reasons:
it will make your tests significantly slower and this will be painful in the long run as browser tests are slow in general
there will be situations (slow CI for instance) where that 100ms will not be enough, so in essence you are not removing the flakiness you are just somehow limiting it
If you really insist on doing it this way then Geb allows you to use custom Navigator implementations. Your custom non empty Navigator implementation would look like this:
class ValueSettingWaitingNonEmptyNavigator extends NonEmptyNavigator {
Navigator value(value) {
super.value(value)
Thread.sleep(100)
this
}
}
This way there's no need to monkey-patch NonEmptyNavigator and you will avoid any strange problems that might cause.
A proper solution would be to have a custom Module implementation that would override Navigator value(value) method and use waitFor() to check if the validation has completed. Finally you would wrap all your validated form elements in this module in your pages and modules content blocks. This would mean that you only wait where it's necessary and as little as possible. I don't know how big your suite is but as it will grow these 100ms will turn into minutes and you will be upset about how slow your tests are. Believe me, I've been there.

Add a property to an object (or at least similar outcome)

First, the context of what I'm doing. I am running an HttpServer which is handling HttpRequests.
HttpServer.bind(ADDRESS, PORT).then((HttpServer server) {
listenSubscription = server.listen(onRequest);
});
void onRequest(HttpRequest request) {
//handle request here
}
I'd like to add some logging to all this, and due to the asynchronous nature of it all, want to add some identifying marker to the requests (so I can match up the request receipts with the responses, fer example). The code inside of onRequest() calls a bunch of other functions to do different things (handle GET vs POST requests, etc.), so simply generating an id at the top is a cumbersome solution as I'd have to pass it around through all those other function calls. I am, however, already passing around the HttpRequest object, so I thought it would be nice to throw an id field on it, just like you would in Javascript, except that Dart doesn't work that way.
Thoughts then went to subclassing the HttpRequest class, but converting the HttpRequest object the onRequest() method receives seemed like much more trouble and overhead than my needs required.
So I ask, is there any idiomatic Dart way attach some data to an existing object? If there isn't something idiomatic, what is the simplest (both in code and runtime complexity) way you can think of to accomplish this?
Well, there's an Expando, but I don't know the performance implications.
Something like:
// somewhere top level. Create this once.
final loggingId = new Expando();
...
// inside of onRequest
loggingId[request] = generateId();
...
// later inside log()
print(loggingId[request]);
Expandos are like weak-reference maps, from my understanding.

OpenRasta: Uri seems to be irrelevant for handler selection

When registering two handlers for the same type, but with different URIs, the handler selection algorithm doesn't seem to check the uri when it determines which handler to use.
If you run the program below, you'll notice that only HandlerOne will be invoked (twice). It does not matter if I call for "/one" or "/two", the latter supposed to be handled by HandlerTwo.
Am I doing something wrong or is this something to be fixed in OpenRasta? (I'm using 2.0.3.0 btw)
class Program
{
static void Main(string[] args)
{
using (InMemoryHost host = new InMemoryHost(new Configuration()))
{
host.ProcessRequest(new InMemoryRequest
{
HttpMethod = "GET",
Uri = new Uri("http://x/one")
});
host.ProcessRequest(new InMemoryRequest
{
HttpMethod = "GET",
Uri = new Uri("http://x/two")
});
}
}
}
class Configuration : IConfigurationSource
{
public void Configure()
{
using (OpenRastaConfiguration.Manual)
{
ResourceSpace.Has.ResourcesOfType(typeof(object))
.AtUri("/one").HandledBy(typeof(HandlerOne));
ResourceSpace.Has.ResourcesOfType(typeof(object))
.AtUri("/two").HandledBy(typeof(HandlerTwo));
}
}
}
class HandlerOne
{
public object Get() { return "returned from HandlerOne.Get"; }
}
class HandlerTwo
{
public object Get() { return "returned from HandlerTwo.Get"; }
}
Update
I have a feeling that I could accomplish what I want similar using UriNameHandlerMethodSelector as described on http://trac.caffeine-it.com/openrasta/wiki/Doc/Handlers/MethodSelection, but then I'd have to annotate each handler methods and also do AtUri().Named(), which looks like boilerplate to me and I'd like to avoid that. Isn't AtUri(X).HandledBy(Y) making the connection between X and Y clear?
Eugene,
You should never have multiple registrations like that on the same resource type, and you probably never need to have ResourcesOfType<object> ever associated with URIs, that'll completely screw with the resolution algorithms used in OpenRasta.
If you're mapping two different things, create two resource classes. Handlers and URIs are only associate by resource class, and if you fail at designing your resources OpenRasta will not be able to match the two, and this is by design.
If you want to persist down that route, and I really don't think you should, then you can register various URIs to have a name, and hint on each of your methods that the name ought to be handled using HttpOperation(ForUriName=blah). That piece of functionality is only there for those very, very rare scenarios where you do need to opt-out of the automatic method resolution.
Finally, as OpenRasta is a compsable framework, you shouldnt have to go and hack around existing classes, you ought to plug yourself into the framework to ensure you override the components you don't want and replace them by things you code yourself. In this case, you could simply write a contributor that replaces the handler selection with your own moel if you don't like the defaults and want an MVC-style selection system. Alternatively, if you want certain methods to be selected rather than others, you can remove the existing operation selectors and replace them (or complement them with) your own. That way you will rely on published APIs to extend OpenRasta and your code won't be broken in the future. I can't give that guarantee if you forked and hacked existing code.
As Seb explained, when you register multiple handlers with the same resource type OpenRasta treats the handlers as one large concatenated class. It therefore guesses (best way to describe it) which potential GET (or other HTTP verb) method to execute, which ever it thinks is most appropriate. This isn't going to be acceptable from the developers prospective and must be resolved.
I have in my use of OpenRasta needed to be able to register the same resource type with multiple handlers. When retrieving data from a well normalised relational database you are bound to get the same type response from multiple requests. This happens when creating multiple queries (in Linq) to retrieve data from either side of the one-to-many relation, which of course is important to the whole structure of the database.
Taking advice from Seb, and hoping I've implemented his suggestion correctly, I have taken the database model class, and built a derived class from it in a resources namespace for each instance of when a duplicating resource type might have been introduced.
ResourceSpace.Has.ResourcesOfType<IList<Client>>()
.AtUri("/clients").And
.AtUri("/client/{clientid}").HandledBy<ClientsHandler>().AsJsonDataContract();
ResourceSpace.Has.ResourcesOfType<IList<AgencyClient>>()
.AtUri("/agencyclients").And
.AtUri("/agencyclients/{agencyid}").HandledBy<AgencyClientsHandler>().AsJsonDataContract();
Client is my Model class which I have then derived AgencyClient from.
namespace ProductName.Resources
{
public class AgencyClient: Client { }
}
You don't even need to cast the base class received from your Linq-SQL data access layer into your derived class. The Linq cast method isn't intended for that kind of thing anyway, and although this code will compile it is WRONG and you will receive a runtime exception 'LINQ to Entities only supports casting Entity Data Model primitive types.'
Context.Set<Client>().Cast<AgencyClient>().ToList(); //will receive a runtime error
More conventional casts like (AgencyClient) won't work as conversion to a SubClass isn't easily possible in C#. Convert base class to derived class
Using the AS operator will again compile and will even run, but will give a null value in the returned lists and therefore won't retrieve the data intended.
Context.Set<Client>().ToList() as IEnumerable<AgencyClient>; //will compile and run but will return null
I still don't understand how OpenRasta handles the differing return class from the handler to the ResourceType but it does, so let's take advantage of it. Perhaps Seb might be able to elaborate?
OpenRasta therefore treats these classes separately and the right handler methods are executed for the URIs.
I patched OpenRasta to make it work. These are the files I touched:
OpenRasta/Configuration/MetaModel/Handlers/HandlerMetaModelHandler.cs
OpenRasta/Handlers/HandlerRepository.cs
OpenRasta/Handlers/IHandlerRepository.cs
OpenRasta/Pipeline/Contributors/HandlerResolverContributor.cs
The main change is that now the handler repository gets the registered URIs in the initializing call to AddResourceHandler, so when GetHandlerTypesFor is called later on during handler selection, it can also check the URI. Interface-wise, I changed this:
public interface IHandlerRepository
{
void AddResourceHandler(object resourceKey, IType handlerType);
IEnumerable<IType> GetHandlerTypesFor(object resourceKey);
to that:
public interface IHandlerRepository
{
void AddResourceHandler(object resourceKey, IList<UriModel> resourceUris, IType handlerType);
IEnumerable<IType> GetHandlerTypesFor(object resourceKey, UriRegistration selectedResource);
I'll omit the implementation for brevity.
This change also means that OpenRasta won't waste time on further checking of handlers (their method signatures etc.) that are not relevant to the request at hand.
I'd still like to get other opinions on this issue, if possible. Maybe I just missed something.

Elegantly reducing the number of dependencies in ASP.NET MVC controllers

We are developing what is becoming a sizable ASP.NET MVC project and a code smell is starting to raise its head.
Every controller has 5 or more dependencies, some of these dependencies are only used for 1 of the action methods on the controller but obviously are created for every instance of the controller.
I'm struggling to think of a good way to reduce the number of objects that are created needlessly for 90% of calls.
Here are a few ideas I'm toying around with:
Splitting the controllers down into smaller, more targeted ones.
Currently we have roughly a controller per domain entity, this has led to nice looking URLs which we would like to emulate, meaning we would end up with a much more complicated routing scheme.
Passing in an interface wrapping the IoC container.
This would mean the objects would only be created when they were explicitly required. However, this just seems like putting lipstick on a pig.
Extending the framework in some way to achieve some crazy combination of the two.
I feel that others must have come across this same problem; so how did you solve this or did you just live with it because it isn't really that big a problem in your eyes?
I've been pondering solutions to this very problem, and this is what I've come up with:
Inject your dependencies into your controller actions directly, instead of into the controller constructor. This way you are only injecting what you need to.
I've literally just whipped this up, so its slightly naive and not tested in anger, but I intend to implement this asap to try it out. Suggestions welcome!
Its of course StructureMap specific, but you could easily use a different container.
in global.asax:
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(
new StructureMapControllerFactory());
}
here is structuremapcontrollerfactory:
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
try
{
var controller =
ObjectFactory.GetInstance(controllerType) as Controller;
controller.ActionInvoker =
new StructureMapControllerActionInvoker();
return controller;
}
catch (StructureMapException)
{
System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
throw;
}
}
}
and structuremapcontrolleractioninvoker (could do with being a bit more intelligent)
public class StructureMapControllerActionInvoker : ControllerActionInvoker
{
protected override object GetParameterValue(
ControllerContext controllerContext,
ParameterDescriptor parameterDescriptor)
{
object parameterValue;
try
{
parameterValue = base.GetParameterValue(
controllerContext, parameterDescriptor);
}
catch (Exception e)
{
parameterValue =
ObjectFactory.TryGetInstance(
parameterDescriptor.ParameterType);
if (parameterValue == null)
throw e;
}
return parameterValue;
}
}
There is the concept of "service locator" that has been added to works like Prism. It has the advantage of reducing that overhead.
But, as you say, it's just hiding things under the carpet. The dependencies do not go away, and you just made them less visible, which goes against one of the goals of using DI (clearly stating what you depend on), so I'd be careful not to overuse it.
Maybe you'd be better served by delegating some of the work. If there is some way you were intending to re-partition your controller, you might just want to create that class and make your controller obtain an instance of it through DI.
It will not reduce the creation cost, since the dependencies would still be resolved at creation time, but at least you'd isolate those dependencies by functionality and keep your routing scheme simple.
I would consider separately the problem of dependencies and creation of dependent objects. The dependency is simply the fact that the controller source code references a certain type. This has a cost in code complexity, but no runtime cost to speak of. The instantiation of the object, on the other hand, has a runtime cost.
The only way to reduce the number of code dependencies is to break up the controllers. Anything else is just making the dependencies a bit prettier, as you say. But making the dependencies (as opposed to instantiation of the dependent objects, which I'll cover in a second) prettier may well be enough of a solution that you don't need to break up the controllers. So IoC is a decent solution for this, I think.
Re: creating the objects, you write, "...some of these dependencies are only used for 1 of the action methods on the controller but obviously are created for every instance of the controller." This strikes me as the real problem, rather than the dependency, per se. Because it's only going to get worse as your project expands. You can fix this problem by changing the instantiation of the objects so that it does not happen until they are needed. One way would be to use properties with lazy instantiation. Another way would be to use arguments to your action methods with model binders which instantiate the objects you need. Yet another way would be to write functions which return the instances you need. It's hard to say which way is best without knowing the purpose of the objects you're using.
Your controllers may be becoming too "Fat". I suggest creating an application tier which sit beneath your controllers. The application tier can encapsulate a lot of the orchestration going on inside your controller actions and is much more testable. It will also help you organize your code without the constraints of designated action methods.
Using ServiceLocation will also help (and yes, I'm essentially reiterating Denis Troller's answer- which probably isn't good but I did vote his answer up).

Resources