Trouble binding a rich:dataTable - java

I'm having some problems with defining a binding bean for my rich:dataTable.
The contents of the datatable are already defined in the XHTML, I just want to use the binding to read the rows back later so that the table contents can be exported into a PDF.
In my XHTML file, I put
<rich:dataTable ... binding="#{backingBean.tableBinding}">
Then, in my backing bean, I declare a member:
import org.richfaces.component.html.HtmlDataTable;
class BackingBean {
private HtmlDataTable tableBinding ;
public BackingBean() {
tableBinding = new HtmlDataTable() ;
}
// ... (incl. getters and setters for binding)
} ;
However, this results in:
java.lang.NullPointerException
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:809)
when I try to load the page. Is there something I need to do with the HtmlDataTable variable besides simply constructing it? Is it even possible to use the binding attribute in the way I intend here?

Don't create an instance of HtmlDataTable yourself in the constructor. RichFaces will create an instance and inject it to your BackingBean. All you need is an public getter and setter.

Related

Access public final static field from tml page

I have a grid where I would like to load the data from method. This method is taking String as a parameter and produce necessary List as output.
For example, it can look like this:
public List<SomeObject> getContactBasedOnType(final String type)
{
final List<SomeObject> returnList = new ArrayList<>();
...//based on "type" list will be populated by different data
return returnList;
}
and then in my tml page I will use it as follows:
<t:grid t:source="getSomeData('STRING')"...
>...</t:grid>
Now, I would like to replace 'STRING' with a public static String field from a class other than component class, for example:
<t:grid t:source="getSomeData(com.example.Class.STATIC_FINAL_FIELD)"...
>...</t:grid>
Is there any way I can do that directly? So without using any additional methods in a component class or annotated fields?
There is a way to achieve what you asked, but it's an awful hack.
<t:grid
t:source="getSomeData(getClass().getClassLoader().loadClass('com.example.Class').getField('STATIC_FINAL_FIELD').get(getClass().getClassLoader().loadClass('com.example.Class').getField('STATIC_FINAL_FIELD').getType().newInstance()))">
...
</t:grid>
Note that, in your question, the method in the component class is named getContactBasedOnType while in your tmls you are referencing getSomeData. The method names must match, of course.
Again, the above is a terrible hack, but the only solution I got to work under the constraint that the component class may not be touched.
Making the list a property of the component class and populating it in the setupRender() method would be a much better design.

JavaBeanBooleanPropertyBuilder for "Beans" without setters

I found this post for connecting a Java Bean as property binding with an existing JavaFX property. The binding should target a boolean property:
class MyClass {
private boolean loaded;
public boolean isLoaded() {
return loaded;
}
// Value changed internally
}
For real beans, meaning beans with setters the following works like a charm. But I've the problem that there's no setter for the loaded property, just because it's set internally and shouldn't be modifyable for external classes.
BooleanProperty loadedProeprty = new JavaBeanBooleanPropertyBuilder()
.bean(bean)
.name("loaded")
.getter("isLoaded")
.build();
Is there any way to create still a property for such "beans" without a setter? For now I just get a NoSuchMethodException for the expected setter MyClass.setLoaded(boolean).
Use ReadOnlyJavaBeanBooleanPropertyBuilder instead.
Normal properties in JavaFX are always read/write and thus require a setter. The read only variant creates a read only property and thus does not require a setter.

CDI: Dynamical injection of a group of classes how to?

I need to dynamically Inject a variable group of classes in my application. The purpose is, as the application grows, only have to add more classes inheriting the same interface. This is easy to do with tradicional java as I just need to search for all classes in a package and perform a loop to instantiate them. I want to do it in CDI. For example:
public MyValidatorInterface {
public boolean validate();
}
#Named
MyValidator1 implements MyValidatorInterface
...
#Named
MyValidator2 implements MyValidatorInterface
...
Now the ugly non real java code just to get the idea of what I want to do:
public MyValidatorFactory {
for (String className: classNames) {
#Inject
MyValidatorInterface<className> myValidatorInstance;
myValidatorInstance.validate();
}
}
I want to loop over all implementations found in classNames list (all will be in the same package BTW) and Inject them dynamically so if next week I add a new validator, MyValidator3, I just have to code the new class and add it to the project. The loop in MyValidatorFactory will find it, inject it and execute the validate() method on the new class too.
I have read about dynamic injection but I can't find a way to loop over a group of class names and inject them just like I used to Instantiate them the old way.
Thanks
What you are describing is what Instance<T> does.
For your sample above, you would do:
`#Inject Instance<MyValidatorInterface> allInstances`
Now, allInstances variable contains all your beans which have the given Type (MyValidatorInterface). You can further narrow down the set by calling select(..) based on qualifiers and/or class of bean. This will again return an Instance but with only a subset of previously fitting beans. Finally, you call get() which retrieves the bean instance for you.
NOTE: if you call get() straight away (without select) in the above case, you will get an exception because you have two beans of given type and CDI cannot determine which one should be used. This is implied by rules of type-safe resolution.
What you most likely want to know is that Instance<T> also implements Iterable so that's how you get to iterate over the beans. You will want to do something like this:
#Inject
Instance<MyValidatorInterface> allInstances;
public void validateAll() {
Iterator<MyValidatorInterface> iterator = allInstances.iterator();
while (iterator.hasNext()) {
iterator.next().callYourValidationMethod();
}}
}

richfaces keepAlive not working

I have a mediaOutput tag which, in its createContent attribute, requires the backing bean to be in a certain state. A list of values, which is filled in an init method, must be available.
I therefore added a keepAlive tag for the whole backing bean. I now indeed see the backingBean in stead of some (richfaces) proxy bean, but the filled list is null again.
How to make this possible?
I checked that the init method was called and that the list is filled in in the init method.
<a4j:keepAlive beanName="myBean" />
<a4j:mediaOutput createContent="#{myBean.writeChart}" ... />
The backing bean
public class MyBean implements Serializable {
public List list;
public void init(ActionEvent event) {
// call some resource to fill the list
list = service.getItems();
}
public void writeChart(final OutputStream out, final Object data) throws IOException {
// list is null
}
// getters & setters
}
Declare your bean to be in session scope.
If you have other request-only information in the bean, then just create a new request-scoped bean and move all the other stuff there. It's perfectly legible.
This is not a problem. You don't have to keep the Mediabean alive, and you can't. The bean which is given in the createContent parameter will be created by the MediaOutput component. The "bean" prefix is the disturbing one - this is only a simple java class which contains the paint(...) method. You have to get the keepalived bean (for example a backing bean) in this simple "bean" as a ManagedProperty, and it can contain the keepalived information too.
Example:
abc.xhtml and ABC.java with #ManagedBean(name = "ABCBean") and #RequestScoped annotation.
You use ABCBean as a Backing Bean with the abc.xhtml, but NOT in the mediaOutput.createContent parameter! But you can create MediaBean.java with #ManagedBean(name="MediaBean") annotation, and it has a #ManagedProperty which gets the ABCBean instance in the MediaBean. And the ABCBean instance is keepalived...

Receiving an array of Object from a web form using Spring framework

I have a form JSP web page, this form contains multiple instances of the same Java object,
I am using Java Spring Framework to control the "communication" with the controller and the view.
My problem is that I would like to be able to receive from the view a simple array containing the instances of my objects which are currently on the page (on which were probably modified).
When I want a specific kind of item, I usually just name it in my controller's method declaration, however for an array (or any Collection), this won't work.
so something like:
#RequestMapping
public String edit(...SomeObject[] objectName, ...){
}
would just return me an error, I can however receive an array of String, so this works:
#RequestMapping
public String edit(...String[] objectString, ...){
}
the goal would be to be able to make Spring automatically map the object.
thanks for your answers!
This is certainly possible; while I've not done it using #RequestMapping, I know that you can retrieve a collection it can be done with a "command" object (or #ModelAttribute)
Define a POJO with a collection attribute as your command
public class FooCommand {
private List<String> myCollection;
// Getter & Setter
}
Then access it in your controller
#RequestMapping(value = "/foo", method = RequestMethod.POST)
public String processSubmit(#ModelAttribute("fooCommand") FooCommand fooCmd) {
// do stuff with fooCmd.getMyCollection()
}
That make any sense?
Spring does not know how to create your custom object from a String so you will need to create your own PropertyEditor for your custom object.
Chapter 5 of the Spring Reference explains data binding and there is an example in Chapter 13 of how to register custom property editors in your controller.

Categories

Resources