'Get composite component inputs' converted values

I have a composite component made of two p:calendars:

<cc:interface componentType="testComponent">
    <cc:attribute name="value" type="org.primefaces.test.DateRange" />
</cc:interface>

<cc:implementation>
    <c:set value="dd-MM-yyyy" var="pattern" />

    <p:panelGrid columns="2">
        <p:outputLabel for="from" value="From" />
        <p:calendar id="from" binding="#{cc.from}" pattern="#{pattern}" />

        <p:outputLabel for="to" value="To" />
        <p:calendar id="to" binding="#{cc.to}" pattern="#{pattern}" />
    </p:panelGrid>

</cc:implementation>

Class DateRange:

public class DateRange {

private Date from;
private Date to;

public DateRange() {
}

public DateRange(Date from, Date to) {
    this.from = from;
    this.to = to;
}

public Date getFrom() {
    return from;
}

public void setFrom(Date from) {
    this.from = from;
}

public Date getTo() {
    return to;
}

public void setTo(Date to) {
    this.to = to;
}

@Override
public String toString() {
    return from + " --> " + to;
}
}

Backing class:

@FacesComponent("testComponent")

public class TestComponent extends UIInput implements NamingContainer {

private UIInput from;
private UIInput to;
private static final String DELIMITER = "-->";

@Override
public String getFamily() {
    return UINamingContainer.COMPONENT_FAMILY;
}

@Override
public void encodeBegin(FacesContext context) throws IOException {
    DateRange range = (DateRange) getValue();
    System.out.println(range);
    if (range != null) {
        from.setValue(range.getFrom());
        to.setValue(range.getTo());
    }
    super.encodeBegin(context);
}

@Override
public Object getSubmittedValue() {
    if (from == null || to == null) return null;

    String submittedFrom = (String) from.getSubmittedValue();
    String submittedTo = (String) to.getSubmittedValue();

    if (submittedFrom == null) {
        submittedFrom = "";
    }
    if (submittedTo == null) {
        submittedTo = "";
    }

    return submittedFrom + DELIMITER + submittedTo;
}

@Override
protected Object getConvertedValue(FacesContext context, Object newSubmittedValue) throws ConverterException {
    String submitted = (String) newSubmittedValue;
    if (submitted == null || submitted.isEmpty()) {
        return null;
    }

    String[] split = submitted.split(DELIMITER);

    String fromStr = split.length > 0 ? split[0] : "";
    String toStr = split.length > 1 ? split[1] : "";

    // TODO: Do I need to perform a manual conversion of the inputs???

    return new DateRange((Date) fromObj, (Date) toObj);
}

getConvertedValue() should return an instance of DateRange. To get dates from calendars, I would need to call getConvertedValue() on each but this method is protected and I cannot access it.

Do I need to manually get the pattern from the p:calendar and convert the value myself? If yes, how do I even know how the conversion is really done in Calendaritself? I wonder how is this approached in more complex components where conversion on subcomponents is not that trivial.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source