I've done something similar a couple months ago addressing a different problem. I have an abstract class for many of my JPA entity classes. Every entity converter of that type had almost the same logic and I wanted to use a single converter for that.
After a little research I was able to find a solution for an abstract converter for my entities where I could place the common logic. The only problem is that now I need to reference-it by its name (converter="entity"). This solution was found somewhere else (I can't remember where) so I can't take any credits here.
The abstract converter:
import java.util.HashMap;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
public abstract class AbstractConverter implements Converter {
private static final String key = "any.key.you.want";
protected Map<String, Object> getViewMap(FacesContext context) {
Map<String, Object> viewMap = context.getViewRoot().getViewMap();
Map<String, Object> idMap = (Map) viewMap.get(key);
if (idMap == null) {
idMap = new HashMap<String, Object>();
viewMap.put(key, idMap);
}
return idMap;
}
@Override
public final Object getAsObject(FacesContext context, UIComponent c,String value) {
if (value == null || value.isEmpty()) {
return null;
}
return getViewMap(context).get(value);
}
@Override
public final String getAsString(FacesContext context, UIComponent c, Object value) {
if (value != null) {
String id = getConversionId(value);
if (id == null || id.isEmpty()) {
throw new IllegalArgumentException("Object can't be converted.");
}
getViewMap(context).put(id, value);
return id;
}
return null;
}
public abstract String getConversionId(Object value);
}
The concrete converter:
import javax.faces.convert.FacesConverter;
import entity.AbstractEntity;
@FacesConverter("entity")
public class EntityConverter extends AbstractConverter {
@Override
public String getConversionId(Object value) {
if (value instanceof AbstractEntity) {
AbstractEntity entity = (AbstractEntity) value;
StringBuilder sb = new StringBuilder();
sb.append(entity.getClass().getSimpleName());
sb.append("@");
sb.append(entity.getId());
return sb.toString();
}
return null;
}
}
Assuming that this could solve you problem you would need something like a ParameterConverter annotated with @FacesConverter("parameter")
and then use it as follows:
<p:spinner id="numberInput"
rendered="#{parameter.type=='NUMBER'}"
stepFactor="#{parameter.resolution}"
value="#{parameter.value}"
parameter="#{parameter.name}"
validator="#{metricModuleManager.validateParameter}"
converter="parameter"
>
<p:ajax update="numberMessage" />
<p:message id="numberMessage" for="numberInput" />
</p:spinner>