Does omnifaces have pagination related components? - jsf

I searched in omnifaces' showcase without success for any component that helps with JSF (datatable) real pagination.
Do you guys know if there is any?
It would be a great feature.
I worked a bit the aproach taken here https://rogerkeays.com/blog/paging-large-data-sets-with-a-lazylist and came with the code below.
It's very generic and could be used with any JSF component library or persistence API.
The developer must implement the lazy list in his JSF managed bean (backing bean), which has access to the business facade or entity manager to do the queries.
import java.util.AbstractList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class AbstractLazyList extends AbstractList {
/**
* Current page cache.
*/
private final Map<Integer, Object> currentPage = new HashMap<Integer, Object>();
/**
* Page size. Default 50.
*/
private int pageSize = 50;
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
#Override
public Object get(int index) {
if (currentPage.containsKey(index)) {
return currentPage.get(index);
}
queryNewPage(index);
return currentPage.get(index);
}
/**
* Clears cache and queries new page's itens.
*
* #param firstItemIndex
* first item index
*/
private void queryNewPage(int firstItemIndex) {
currentPage.clear();
final List<Object> pageResults = queryNextPage(firstItemIndex, pageSize);
for (int j = 0; j < pageResults.size(); j++) {
currentPage.put(firstItemIndex + j, pageResults.get(j));
}
}
#Override
public int size() {
return queryResultsSize();
}
/**
* Queries next page itens.
*
* #param firstRowIndex
* first row index
* #param pageSize
* maximum resuts of the query
* #return list of results
*/
protected abstract List<Object> queryNextPage(int firstRowIndex,
int pageSize);
/**
* Counts the total results of the query.
*
* #return query's total results
*/
protected abstract int queryResultsSize();
}
}
Maybe an aproach like this could fit in omnifaces.

OmniFaces is not geared to visually oriented UI components, but more to utilities which do its work "behind the scenes" and can be used in combination with any other JSF component library.
Consider looking at visually oriented UI component libraries such as PrimeFaces and RichFaces. They offer data table components with pagination possibilities.
PrimeFaces <p:dataTable> showcase
RichFaces <rich:dataTable>+<rich:dataScroller> showcase

Related

Avoid Doctrine to return all entities

Using Symfony2 / doctrine2, while we use the find() function to get a specific object based on the entity selected if there are relations (like OneToMany), Doctrine return all other object.
For example :
$em = $this->get(
'doctrine.orm.entity_manager',
$request->getSession()->get('entity_manager')
);
$product = $em->getRepository('MyBundle:Product')->find($id);
The result on $product will be the Product object + other linked objects like (Store, Category, ...etc.)
How can we control doctrine to determinate which object we need to be returned.
I can use Querybuilder, but i am looking if there are any function all determinate.
Doctrine return all other object
This is not how it works, at least by default.
Doctrine uses what is called lazy loading.
From the official documentation, you have the following example:
<?php
/** #Entity */
class Article
{
/** #Id #Column(type="integer") #GeneratedValue */
private $id;
/** #Column(type="string") */
private $headline;
/** #ManyToOne(targetEntity="User") */
private $author;
/** #OneToMany(targetEntity="Comment", mappedBy="article") */
private $comments;
public function __construct {
$this->comments = new ArrayCollection();
}
public function getAuthor() { return $this->author; }
public function getComments() { return $this->comments; }
}
$article = $em->find('Article', 1);
And the following explanation:
Instead of passing you back a real Author instance and a collection of
comments Doctrine will create proxy instances for you. Only if you
access these proxies for the first time they will go through the
EntityManager and load their state from the database.
Reference: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#entity-object-graph-traversal
More information about the topic: http://www.doctrine-project.org/blog/doctrine-lazy-loading.html
You can configure extra lazy associations to avoid loading of relations in general.
/**
* #ManyToMany(targetEntity="CmsUser", mappedBy="groups", fetch="EXTRA_LAZY")
*/
protected $property;

JaxB reference resolving

For the follwing example XML input:
<Participants course="someCourse">
<workers>
<Worker ref="p3">
<Worker ref="p2">
</workers>
<Trainer ref="p1"/>
</Participants>
<Group id="group1" name="some mixed Person group">
<trainers>
<Trainer id="p1" name="John Doe">
</trainers>
<workers>
<Worker id="p2" name="Jim Scott">
<Worker id="p3" name="Walter Peace">
</workers>
</Group>
I am trying to make sure that the PersonList in Participants points to the Persons read from group1. (see code snipptes below for the JaxB annotations used). This is just an example for the more generic
approach I am seeking. I need to be generally able to follow id="" and ref="" attributes in a way
that the list elements are correctly unmarshalled as references.
With an UnmarshalListener and Unmarshalling twice I get around the problem of the references from the ref attribute to the id attribute. In the first phase the lookup Map is filled from the id attributes. In the second phase the refs are looked up. Unfortunately this solution will create copies instead of references. I could use the parent object to fix this but I am looking for a more generic solution. What would be a good way to achieve the proper dereferencing using ref/id attributes in the manner shown?
/**
* intercept the unmarshalling
*/
public static class ModelElementMarshallerListener extends javax.xml.bind.Unmarshaller.Listener {
public Map<String,Person> lookup=new HashMap<String,Person>();
#Override
public void afterUnmarshal(java.lang.Object target, java.lang.Object parent) {
if (target instanceof Person) {
person=(Person) target;
if (person.getId()!=null) {
lookup.put(person.getId(), person);
}
if (person.getRef()!=null) {
if (lookup.containsKey(person.getRef())) {
Person personRef=lookup.get(person.getRef());
person.copyFrom(personRef);
person.setRef(null);
}
}
}
}
}
#XmlRootElement(name="Participants")
public class Participants {
private List<Worker> workers;
/**
* getter for List<Worker> workers
* #return workers
*/
#XmlElementWrapper(name="workers")
#XmlElement(name="Worker", type=Worker.class)
public List<Worker> getWorkers() {
return workers;
}
...
}
#XmlRootElement(name="Group")
public class Group {
private List<Worker> workers;
/**
* getter for List<Worker> workers
* #return workers
*/
#XmlElementWrapper(name="workers")
#XmlElement(name="Worker", type=Worker.class)
public List<Worker> getWorkers() {
return workers;
}
...
}
#XmlRootElement(name="Trainer")
public class Trainer extends Person {}
#XmlRootElement(name="Worker")
public class Worker extends Person {}
#XmlRootElement(name="Person")
public class Person {
private String name;
/**
* getter for xsd:string/String name
* #return name
*/
#XmlAttribute(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
private String ref;
/**
* getter for xsd:string/String id
* #return id
*/
#XmlAttribute(name="ref")
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref=ref;
}
private String id;
/**
* getter for xsd:string/String id
* #return id
*/
#XmlAttribute(name="id")
#XmlID
public String getId() {
this.id;
}
/**
* setter for xsd:string/String id
* #param pid - new value for id
*/
public void setId(String pid) {
this.id=pid;
}
}
To better illustrate the point I have modified the question to fit his answer. There is now a generic base class Person and I am trying to use it as per Can generic XmlAdapter be written
I solved the issue of being able to actually make sure the Adapters are used by writing specific derived Classes and using them with #XmlJavaTypeAdapter. I preregister the adapters using:
JAXBContext context = JAXBContext.newInstance(type);
Unmarshaller u = context.createUnmarshaller();
u.setAdapter(Worker.WorkerAdapter.class,new Worker.WorkerAdapter());
u.setAdapter(Trainer.TrainerAdapter.class,new Trainer.TrainerAdapter());
and then unmarshalling twice. The debug shows that the Adapter instance for both passes is the same. Still the lookup somehow seemed to fail ... The reason was the way the #XmlJavaTypeAdapter annotation works see:
What package-info do I annotate with XmlJavaTypeAdapters?
There seem to be multiple modes for #XmlJavaTypeAdapter:
it can be an annotation for a class
it can be an annotation for a field (getter)
it can be used in a package-info.java file to annotate a whole package
At this point I am using all three annotations and now have to debug which ones are necessary. I assume the global annotations (class,package) are not working as expected. The reason might be the type= usage in the #XmlElementWrapper which explicitly calls for a type. Personally I do not understand what is going on yet. At least things are now working as expected.
the local field annotation is now e.g.:
#XmlElementWrapper(name="workers")
#XmlElement(name="Worker", type=Worker.class)
#XmlJavaTypeAdapter(WorkerAdapter.class)
the package-info.java annotation is:
#XmlJavaTypeAdapters({
#XmlJavaTypeAdapter(value=WorkerAdapter.class,type=Worker.class),
#XmlJavaTypeAdapter(value=TrainerAdapter.class,type=Trainer.class),
})
package com.bitplan.jaxb.refidtest;
import javax.xml.bind.annotation.adapters.*;
the class annotation is:
#XmlJavaTypeAdapter(Worker.WorkerAdapter.class)
public class Worker extends Person {
...
/**
* Worker Adapter
* #author wf
*
*/
public static class WorkerAdapter extends PersonAdapter<Worker>{
#Override
public Worker marshal(Worker me)
throws Exception {
return super.marshal(me);
}
#Override
public Worker unmarshal(Worker me) throws Exception {
return super.unmarshal(me);
}
}
/**
* https://stackoverflow.com/questions/7587095/can-jaxb-marshal-by-containment-at-first-then-marshal-by-xmlidref-for-subsequen/7587727#7587727
* #author wf
*
*/
public class PersonAdapter<T extends Person> extends XmlAdapter<T, T>{
public boolean debug=true;
/**
* keep track of the elements already seen
*/
public Map<String,T> lookup=new HashMap<String,T>();
#Override
public T marshal(T me)
throws Exception {
return me;
}
/**
* show debug information
* #param title
* #param key
* #param me
* #param found
*/
public void showDebug(String title,String key,T me, T found) {
String deref="?";
if (found!=null)
deref="->"+found.getId()+"("+found.getClass().getSimpleName()+")";
if (debug)
System.err.println(title+": "+key+"("+me.getClass().getSimpleName()+")"+deref+" - "+this);
}
#Override
public T unmarshal(T me) throws Exception {
if (me.getId()!=null) {
showDebug("id",me.getId(),me,null);
lookup.put(me.getId(), me);
return me;
}
if (me.getRef()!=null) {
if (lookup.containsKey(me.getRef())) {
T meRef=lookup.get(me.getRef());
showDebug("ref",me.getRef(),me,meRef);
me.setRef(null);
return meRef;
} else {
if (debug)
showDebug("ref",me.getRef(),me,null);
}
}
return me;
}
}

How to automatically escape variables in a Zend Framework 2 view

A lot of times in a Zend Framework 2 view I'll be calling $this->escapeHtml() to make sure my data is safe. Is there a way to switch this behaviour from a blacklist to a whitelist?
PS: Read an article from Padraic Brady that suggests that automatic escaping is a bad idea. Additional thoughts?
You could write your own ViewModel class which escapes data when variables are assigned to it.
Thanks to Robs comment, I extended the ZF2 ViewModel as follows:
namespace Application\View\Model;
use Zend\View\Model\ViewModel;
use Zend\View\Helper\EscapeHtml;
class EscapeViewModel extends ViewModel
{
/**
* #var Zend\View\Helper\EscapeHtml
*/
protected $escaper = null;
/**
* Proxy to set auto-escape option
*
* #param bool $autoEscape
* #return ViewModel
*/
public function autoEscape($autoEscape = true)
{
$this->options['auto_escape'] = (bool) $autoEscape;
return $this;
}
/**
* Property overloading: get variable value;
* auto-escape if auto-escape option is set
*
* #param string $name
* #return mixed
*/
public function __get($name)
{
if (!$this->__isset($name)) {
return;
}
$variables = $this->getVariables();
if($this->getOption('auto_escape'))
return $this->getEscaper()->escape($variables[$name]);
return $variables[$name];
}
/**
* Get instance of Escaper
*
* #return Zend\View\Helper\EscapeHtml
*/
public function getEscaper()
{
if (null === $this->escaper) {
$this->escaper = new EscapeHtml;
}
return $this->escaper;
}
}
In a Controller it could be used like this:
public function fooAction()
{
return new EscapeViewModel(array(
'foo' => '<i>bar</i>'
));
//Turn off auto-escaping:
return new EscapeViewModel(array(
'foo' => '<i>bar</i>'
),['auto_escape' => false]);
}
Question:
I would appreciate it if soemebody would comment, if this is best practice or if there is a better and ecp. more efficient and resource-saving way?

How it works the filterMatchMode from PrimeFaces DataTable?

Primefaces Datatable let you configure the filtering type you use for a column, using the property filterMatchMode.
Nonetheless, if you use LazyDataModel you have to implement your own search method, which doesn't receive that property at all. is this feature only useful for normal DataModels?
Currently this feature is not supported for LazyDataModel out-of-box, however you can still use it with relatively little effort. blemasle posted corresponding patch on primefaces forum, unfortunately there is still no response from the developers.
If you want to use non code-invasive solution, you can try mine.
Filter constraints are obtained with:
/**
* #param tableSearchExpr expression, starting from the view root,
* which identifies the datatable to retrieve information from
* #return map, containing pairs of {#code <filtered field id, match mode>}.
* Filtered field id is evaluated from the 'filterBy'
* attribute of the column in the following way:
* #{item.name} -> name
* #{item.category.name} -> category.name
*/
public Map<String, FilterMatchMode> getFiltersMatchMode(String tableSearchExpr) {
FacesContext context = FacesContext.getCurrentInstance();
Object component = context.getViewRoot().findComponent(tableSearchExpr);
if (null == component) {
throw new IllegalArgumentException(
"No component found for search expression: "
+ tableSearchExpr);
}
if (!(component instanceof DataTable)) {
throw new IllegalArgumentException(
"Component is not a DataTable: " + tableSearchExpr);
}
DataTable table = (DataTable) component;
Map<String, FilterMatchMode> constraints =
new HashMap<String, FilterMatchMode>(table.getColumns().size());
for (UIColumn column : table.getColumns()) {
ValueExpression filterExpression =
column.getValueExpression("filterBy");
if (null != filterExpression) {
String filterExpressionString = filterExpression.
getExpressionString();
//evaluating filtered field id
String filteredField = filterExpressionString.substring(
filterExpressionString.indexOf('.') + 1,
filterExpressionString.indexOf('}'));
FilterMatchMode matchMode =
FilterMatchMode.fromUiParam(column.getFilterMatchMode());
constraints.put(filteredField, matchMode);
}
}
return constraints;
}
Where FilterMatchMode is:
public enum FilterMatchMode {
STARTS_WITH("startsWith"), ENDS_WITH("endsWith"),
CONTAINS("contains"), EXACT("exact");
/**
* Value of p:column's filterMatchMode attribute
* which corresponds to this math mode
*/
private final String uiParam;
FilterMatchMode(String uiParam) {
this.uiParam = uiParam;
}
/**
* #param uiParam value of p:column's filterMatchMode attribute
* #return MatchMode which corresponds to given UI parameter
* #throws IllegalArgumentException if no MatchMode
* is corresponding to given UI parameter
*/
public static FilterMatchMode fromUiParam(String uiParam) {
for (FilterMatchMode matchMode : values()) {
if (matchMode.uiParam.equals(uiParam)) {
return matchMode;
}
}
throw new IllegalArgumentException("No MatchMode found for " + uiParam);
}
}

What the difference between JAXB and CXF?

I have tried to generate java classes from a schema xsd with JAXB2.1 and run XJC and it works.
I have included the schema in a wsdl file and i generate java classes with wsdl2java command using CXF.
The problem is abouta java class where there are difference:
The difference is the content attribute and its getter and setter which is missing with wsdl2java command.
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.1-b02-fcs
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
//
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "BIN", **propOrder = {
"content"**
})
#XmlSeeAlso({
ED.class
})
public abstract class BIN {
**#XmlValue
protected String content;**
#XmlAttribute
protected BinaryDataEncoding representation;
/**
public String getContent() {
return content;
}
/**
*
* Binary data is a raw block of bits. Binary data is a
* protected type that MUST not be used outside the data
* type specification.
*
*
* #param value
* allowed object is
* {#link String }
*
*/
**public void setContent(String value) {
this.content = value;
}**
/**
* Gets the value of the representation property.
*
* #return
* possible object is
* {#link BinaryDataEncoding }
*
*/
public BinaryDataEncoding getRepresentation() {
if (representation == null) {
return BinaryDataEncoding.TXT;
} else {
return representation;
}
}
/**
* Sets the value of the representation property.
*
* #param value
* allowed object is
* {#link BinaryDataEncoding }
*
*/
public void setRepresentation(BinaryDataEncoding value) {
this.representation = value;
}
}
I need this attribute into this class.
Is there a way to do this like add a parameter?
This is my wsdl2java command:
call wsdl2java -Debug -verbose -exsh true -autoNameResolution -p %PACKAGE_BASE%.pa -p "urn:hl7-org:v3"=%PACKAGE_BASE%.patient.hl -d %PROJECT_HOME%\src\main\java\ %WSDL_HOME%\Test.wsdl
thanks

Resources