Search code examples
jsfmojarra

Substitute myfaces RedererUtils with jakarta.faces-api


At the moment, using myfaces, we get the value from a component like this:

RendererUtils.getStringValue(FacesContext.getCurrentInstance, component));

We want to get rid of myfaces and use mojarra:

<dependency>
<groupId>javax.faces</groupId>
<version>javax.faces-api</version>
<version>2.3</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.sun.faces</groupId>
<version>jsf-impl</version>
<version>2.3.14.SP07-redhat-00001</version>
<scope>provided</scope>
</dependency>

What is the substitute for the above code using those dependencies?


Solution

  • There's no such thing in standard Faces API.

    You was using a MyFaces implementation-specific utility method which thus made your code unportable when you use a different implementation of the Faces API, such as Mojarra.

    The com.sun.faces:jsf-impl artifact is the Mojarra implementation. Ideally you shouldn't be needing this dependency in your pom.xml when the implementation is already provided by the target runtime. The sole javax.faces-api dependency should have been sufficient in order to make your application portable across different Faces API implementations. Better yet, a sole javax.javaee-api dependency for everything Java EE as you apparently already have a normal Java EE server as target runtime in form of WildFly instead of a barebones servletcontainer such as Tomcat.

    Nonetheless, the Mojarra-specific utility method you're looking for does not exist either. The closest is com.sun.faces.renderkit.html_basic.HtmlBasicRenderer#getCurrentValue(), but this is not a static utility method.

    Your best bet is writing an utility method yourself. It can look like this:

    public static String getRenderedValue(FacesContext context, UIComponent component) {
        if (!(component instanceof ValueHolder)) {
            throw new IllegalArgumentException("UIComponent must be an instance of ValueHolder");
        }
    
        if (component instanceof EditableValueHolder) {
            Object submittedValue = ((EditableValueHolder) component).getSubmittedValue();
    
            if (submittedValue != null) {
                return submittedValue.toString();
            }
        }
    
        Object value = ((ValueHolder) component).getValue();
        Converter converter = ((ValueHolder) component).getConverter();
    
        if (converter == null && value != null) {
            converter = context.getApplication().createConverter(value.getClass());
        }
    
        if (converter != null) {
            return converter.getAsString(context, component, value);
        }
    
        return Objects.toString(value, "");
    }
    

    Nope, this does not exist in OmniFaces either. Yet.

    See also: