JSF FileUploadEvent getSource what kind of Object? - jsf

When I get my FileUploadEvent event event, it is possible to extract the source object via .getSource(). I debugged it and I know it contains the id of rich:fileUpload. So I want to use the same listener for several fileUploads and need to switch this objects id. But what kind of Object is it, so I can acces this member?

It's an UIComponent and the ID is available by getId(). You can easily figure the exact class by looking at its getClass().

Related

How to access certain EStructuralFeatures of an EMF Model?

I know that there are ways to access an EAttribute of an Eclipse EMF model by its featureID or by its name via different indirect approaches. For that I found the following: Eclipse EMF: How to get access EAttribute by name?
But what if I don't know the name of the attribute I want to get? Let's say, based on the design, the model has some fixed attributes by the developer, along with the features that can be set dynamically by the user.
So, for the time being I use the getEAllStructuralFeatures() and use indexes via get() to reach to the by-the-user-created attributes, since I know that the list I get will have the fixed attributes of the model as its first elements beginning with the index 0. But I find this solution unclear and inefficient. Also in some cases, that I want to work, not suitable.
E.g: IEMFEditProperty prop = EMFEditProperties.list(editingDomain, EMFMODELPackage.Literals.EMFMODEL.getEAllStructuralFeatures().get(X));
Do you know a solution or a workaround for this problem? As far as I can see, there are no direct methods to get such dynamically created features of the model.
Every help will be appreciated.
I have been working on a similar case recently where I first tried to define an EStructuralFeature to access exactly the setting/attribute of the object that I needed.
But if you look at how things work internally in ECore, you will find out, that there is no way this will ever work, since the indices are bound to the object identity of the EStructuralFeature objects created at runtime for the specific context (i.e. EClass instance).
My approach was then to either inspect the features proposed by EClass.getEAllStructuralFeatures or to iterate over the features and inspect the object returned by EObject.eGet for this very feature (where EClass eClass = eObject.eClass()).
Example: In a UML profile I have defined a UML Stereotype called "Bean" with a property called FactoryEntity. The property shall reference a UML Class with the Stereotype "Entity" that is closest to this very bean and for which a static factory method will be generated.
In the model I would then have one UML Class typed as Bean and one as Entity.
And for the Class typed as "Bean" I would then set a value for the attribute/property factoryEntity defined in the profile.
The question was then how the property value would be accessible in ECore. I ended up iterating the List of available EStructuralFeature of the EClass of the EObject and checking the type of the object returned by eGet.
final EObject eObject = (EObject) holdingClass.getValue(stereotype, stereoTypePropertyName);
final EList<EStructuralFeature> allEStructFeats = eObject.eClass().getEAllStructuralFeatures();
for(EStructuralFeature esf : allEStructFeats)
{
final Object o = eobject.eGet(esf);
if(o instanceof org.eclipse.uml2.uml.Class)
{
return (org.eclipse.uml2.uml.Class) o;
}
}
Maybe that is not the most elegant way to access structural features but it is the only one I thought was robust enough to last.
Please let me know if you have any suggestions on how to improve this.

Persisting ViewScoped beans across multiple views

Ok I know scope questions come up all the time but I'm interested in a slightly different approach to the solution. The #ViewScope is a fantastic bridge between the #RequestScope and the #SessionScope.
However there is still a common use case (at least for me) where I really don't want to use #SessionScope but I need the data over a couple of views. A really simple case is when I have multiple datatables chained together each one depending on previous selections.
It's perfectly possible to use <f:paramView> and pass a single or even a couple of pieces of data as params in the address and then retrieve everything from the database again. I am more interested in finding a way of creating a 'snapshot' of the beans state / variables, creating the new #ViewScope and then 'restoring' the 'snapshot state' to the new bean.
Does such a thing exist? Ideas? Opinions?
I don't know if this is the 'accepted solution' but I've implemented an idea that works for me. (Feedback appreciated!)
So I have created a #SessionScoped class with a couple of static maps:
private static Map<String, Object> objectVariableMap;
// Getters, setters and methods etc. are omitted for simplicity
The idea being that I have specified a map that accepts a String as the key and an Object as the value. I've specifically not set the type of object to allow me to store any type of object in there. The caveat is that you need to be sure of the type of object when retrieving it so you can cast it back into its original type.
Now comes the time to set the data from the first #ViewScoped. I generate a random UUID (or what ever you want) as the Map key and then set the value to the object I'm working with (ie. this, or indeed any other objects you might want to pass to the next view). Save the key, value into the map and set the URL param to the key.
I'm never keen on passing data like user id's etc. in URL params (even when its encrypted). This idea has the added benefit of offering disposable URL values that have a specifiable life span.
On the receiving end (ie. The new #ViewScoped bean, or any other scope for that matter) you read in the URL param (the map key) using <f:paramView> and then use a preRenderView event to retrieve and set the Object where working with.
At this point you can choose to remove the key pair from the Map and invalidate the ability to retrieve that object or you can keep keep the key pair for a longer duration by simply updating the object if there are any changes.
UPDATE: Conceptually this has been really successful (for me at least). I've created a handfull of useful methods and classes surrounding the concept to make it more universal. If anybody wants more specific instructions or I might even create a small library if anybody wants.
You can use the CDI "Conversation Scope" for this. This is narrower than the session scope but wider than the view scope.
If the pages between which you pass parameters are a unit, you can also make them a flow in JSF 2.2 and use the flow scope.
Projects like CODI offer various other scopes that can be used between pages.

Custom Control Custom Methods?

I have been making good use of custom properties withing custom controls. Is there such thing as custom methods? Say I want something to happen in a CC. A good example is the show method of the dialog box extension. If I have a cc with a extension dialog inside, I want my custom control to have a Show method which insulates the end user programmer from the extension pages Shoe method.
Is there anyway to do this?
At runtime, all Custom Control elements become instances of the UIIncludeComposite class; as such, there are many built in methods that you can call against any given control instance, but there is no way to specify custom methods, as opposed to custom properties.
There are, however, at least two ways you could achieve the result you're after:
Convert your Custom Control to a component (this NotesIn9 episode describes the simplest approach to this process). Once you've migrated the class that Designer generated to one that won't get overridden every time you build your NSF, you can add custom methods without fear that the next build will just wipe them out again. Since Custom Controls are essentially just IBM's implementation of the JSF 2.0 notion of "composite components", you could also create a component from scratch that has the same behavior as your existing Custom Control but also supports custom behavior. Note that either approach does not necessarily require that you create an OSGi library... you can define these components directly in an NSF; you only need to push them to a library if you want to reuse them across multiple NSFs without having to copy the various files to each.
In the custom properties for your control, include one property that accepts an API object. In other words, you could create any object (say, a Java class or SSJS object) that supports the custom methods you wish to define, and pass that object to the control. You could then call those methods by getting a handle on the object via the CC's property map.
For example:
<myCC id="myCustomControl" API="#{someObject}" />
Assuming whatever #{someObject} resolves to includes a show() method, you can call that method by getting a handle on the instance that has been passed to the control:
var cc = getComponent("myCustomControl");
var ccProperties = cc.getPropertyMap();
var ccAPI = ccProperties.get("API");
ccAPI.show(cc);
In the above example, I'm passing the actual Custom Control to the show() method, because the object itself isn't aware of the Custom Control it was passed to. So if that method needs to get a handle on its children to toggle their rendered property, for example, then it needs some other way of determining its context.
Tim's solution with passing in the object is a great solution to that.
Just something that popped into my head, would be easy to make a property similar to the rendered property on a control. Pass in a value and inside the custom control do something based on its value ie. if true display dialog, else hide, in the XPage during run time modify this value and partial refresh the control, the logic will be re run by this and the control will display etc.
Another solution could be to include a JavaScript library in your custom control providing functions (your custom control methods) where you'd have to pass in the id of the custom control instance.

Core Data - NSFetchedResultsController bug

It seems controllerDidChangeContent: is being called as soon as I create a new managed object in my context. The documentation seems to suggest this method is called only once you save: the context.
This "bug" if it is one, is causing my application to crash because as part of my table view cell, I need to load other managed objects that don't exist at the time of creating the main managed object.
Someone seems to have spotted this too, please check out the following link and I would love to hear your opinions on this: http://openradar.appspot.com/10207615
More information
Although the link I added to this post showcases an example using two NSManagedObjectContext, my application is using one context, but the controllerDidChangeContent: is being messaged none the less as soon as an object is created in the one and only context, and controllerDidChangeContent: is being called a second time when I save: this context. It is to my understanding that this method should only be messaged when the context is saved.
The solution is to avoid dealing with more than one managedObjectContext. If your cell needs to load other managed objects, it should still use the same managed object context as the main managed object.
I have yet to see a use case where it is absolutely unavoidable to use more than one managed object context referring to the same model active at the same time.

JSF: How do I include parameters in an action method's return string?

I'm writing an action method that will store a new object in a database. Once this is done, I want to navigate to view that newly created object. To do this, I was planning to include a querystring or some sort of parameter in the return String of the action method, but I can't figure out how. If I append a query string manually, it appears that it's being ignored. Also, manually adding parameters by concatenating strings doesn't seem like a good idea to me. Is it possible to do this in a type-safe manner?
The way I've always handled this is to get a reference to the bean which provides the content for the page you'll be displaying, and just set its properties directly. The navigation string returned from an action method isn't meant for passing parameters, but you don't need it to; all they'd be used for is setting bean properties anyway.

Resources