Replace null or empty strings with a specified value while outputting using a JSF converter
<p>The following is a converter basically intended to trim leading and trailing white spaces and replace more than one space between words in a sentence or text with a single space. The converter is now modified to replace <code>null</code> or empty strings with "Not available" (may be localized dynamically, if needed).</p>

<pre><code>@FacesConverter(forClass = String.class)
public class StringTrimmer implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        return Boolean.TRUE.equals(component.getAttributes().get("skipConverter")) ? value : value == null ? null : value.trim().replaceAll("\\s+", " ");
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return Boolean.TRUE.equals(component.getAttributes().get("skipConverter")) ? value == null ? null : value.toString() : value == null || ((String) value).trim().length() == 0 ? "Not available" : ((String) value).trim().replaceAll("\\s+", " ");
    }
}
</code></pre>

<p>Since converters are not invoked, when a model value is <code>null</code> based on <a href="https://stackoverflow.com/q/35347001/1391249">the previous question</a>, <code>com.sun.faces.renderkit.html_basic.TextRenderer</code> has been extended with the intention of invoking converters, when a property value in the associated model is <code>null</code>.</p>

<pre><code>public final class HtmlBasicRenderer extends TextRenderer {

    @Override
    public String getCurrentValue(FacesContext context, UIComponent component) {

        if (component instanceof UIInput) {
            Object submittedValue = ((UIInput) component).getSubmittedValue();

            if (submittedValue != null) {
                return submittedValue.toString();
            }
        }

        return getFormattedValue(context, component, getValue(component));
    }
}
</code></pre>

<p>The <a href="https://github.com/bleathem/mojarra/blob/master/jsf-ri/src/main/java/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java#L356" rel="nofollow noreferrer">following</a> conditional test has been removed so that the <code>getFormattedValue()</code> method can be invoked, even if a <code>null</code> value is encountered.</p>

<pre><code>Object currentObj = getValue(component);

if (currentObj != null) {
    currentValue = getFormattedValue(context, component, currentObj);
}
</code></pre>

<p>This has been registered in <code>faces-config.xml</code> as follows.</p>

<pre><code>&lt;render-kit&gt;
    &lt;renderer&gt;
        &lt;component-family&gt;javax.faces.Output&lt;/component-family&gt;
        &lt;renderer-type&gt;javax.faces.Text&lt;/renderer-type&gt;
        &lt;renderer-class&gt;com.example.renderer.HtmlBasicRenderer&lt;/renderer-class&gt;
    &lt;/renderer&gt;
&lt;/render-kit&gt;
</code></pre>

<p>The converter <code>StringTrimmer</code> is still not invoked (<code>getAsString()</code>), when a property value in the target model returns <code>null</code>.</p>

<p>Putting a conditional test in EL like <code>#{empty bean.value ? 'Not available' : bean.value}</code> everywhere throughout the application is insanity. Any suggestion?</p>

<p>It is Mojarra 2.2.12.</p>

<hr>

<p><strong>Update :</strong></p>

<p>Converted values are available, when one of the return statements inside the <a href="https://github.com/bleathem/mojarra/blob/master/jsf-ri/src/main/java/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java#L474" rel="nofollow noreferrer"><code>getFormattedValue()</code></a> method returning an empty string <code>""</code>, when <code>currentValue</code> is <code>null</code>, is modified to return a converted value in call to </p>

<pre><code>javax.​faces.​convert.​Converter.getAsString(FacesContext context, UIComponent component, Object value)
</code></pre>

<p>inside that method <code>getFormattedValue()</code>.</p>

<p>Thus, the <a href="https://github.com/bleathem/mojarra/blob/master/jsf-ri/src/main/java/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java#L498" rel="nofollow noreferrer">following</a>,</p>

<pre><code>if(currentValue == null) {
    return "";
}
</code></pre>

<p>needs to be replaced with,</p>

<pre><code>if (currentValue == null) {
    converter = Util.getConverterForClass("".getClass(), context);
    return converter == null ? "" : converter.getAsString(context, component, currentValue);
}
</code></pre>

<p>(Needs suggestions).</p>