cancel
Showing results for 
Search instead for 
Did you mean: 

How to create a custom Constraint on a d:date Property

ipirat
Champ in-the-making
Champ in-the-making
Hi all,

I have a custom model with two custom properties of type d:date (my:fromDate and my:toDate), both are mandatory
Now I'd like to ensure that that the my:toDate is equal or later than the my:fromDate.

<ol>
<li>My first goal is to implement a custom Constraint class, which takes two (constant) constraint properties: minDate and maxDate
<li>My second goal is to implement a custom Constraint class, which compares to content properties.
</ol>

<strong>To achieve my first goal,</strong> I created a class my.package.constraints.DateMinMaxConstraint (see code below) and defined my content model:

                <property name="my:fromDate">
                    <title>From Date</title>
                    <type>d:date</type>
                    <mandatory enforced="true">true</mandatory>
                    <constraints>
                        <constraint name="my:minMaxDateConstraint" type="my.package.constraints.DateMinMaxConstraint">
                            <parameter name="minDate">
                                <value>2014-01-01</value>
                            </parameter>
                            <parameter name="maxDate">
                                <value>2014-01-01</value>
                            </parameter>
                        </constraint>
                    </constraints>
                </property>



Now, that complaints along the lines of

llegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'minDate': no matching editors or conversion strategy found


apparently, I need to give it a PropertyEditor. => First Question: How can I specify a PropertyEditor to be used with a constraint??? Do I need to edit one of the spring xml files?


public class DateMinMaxConstraint extends AbstractConstraint {

    private Date minDate;
    private Date maxDate;

    public Date getMinDate() {
        return this.minDate;
    }

    public void setMinDate(Date minDate) {
        this.minDate = minDate;
    }

    public Date getMaxDate() {
        return this.maxDate;
    }

    public void setMaxDate(Date maxDate) {
        this.maxDate = maxDate;
    }

    @Override
    public Map<String, Object> getParameters() {
        Map<String, Object> params = new HashMap<String, Object>(2);
        params.put("minDate", this.minDate);
        params.put("maxDate", this.maxDate);
        return params;
    }

    @Override
    protected void evaluateSingleValue(Object val) {
        // TODO this is just to be able to set a break point for the moment
        @SuppressWarnings("unused")
        int i = 0;
        i++;

    }

}



For my second goal: I have no idea, to be honest: is it possible at all, to compare two document properties in one constraint
1 REPLY 1

ipirat
Champ in-the-making
Champ in-the-making
To overcome the Date-String-Conversions, I modified the constraint class to be
<java>
public class DateMinMaxConstraint extends AbstractConstraint {

    private static final String DATE_FORMAT = "yyyy-MM-dd";

    private Date minDate;
    private Date maxDate;

    public String getMinDate() {
        DateFormat df = new SimpleDateFormat(DATE_FORMAT);
        return df.format(this.minDate);
    }

    public void setMinDate(String dateStr) {
        DateFormat df = new SimpleDateFormat(DATE_FORMAT);
        try {
            this.minDate = df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    public String getMaxDate() {
        DateFormat df = new SimpleDateFormat(DATE_FORMAT);
        return df.format(this.maxDate);
    }

    public void setMaxDate(String dateStr) {
        DateFormat df = new SimpleDateFormat(DATE_FORMAT);
        try {
            this.maxDate = df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Map<String, Object> getParameters() {
        Map<String, Object> params = new HashMap<String, Object>(2);
        params.put("minDate", this.minDate);
        params.put("maxDate", this.maxDate);
        return params;
    }

    protected void evaluateSingleValue(Date val) {

    }

    @Override
    protected void evaluateSingleValue(Object val) {

        if (!(val instanceof Date)) {
            throw new ConstraintException("the property is not of type d:date");
        } else {
            Date dateVal = (Date) val;
            if (dateVal.after(this.maxDate) || dateVal.before(this.minDate)) {
                throw new ConstraintException(MessageFormat.format("the date {0,date," + DATE_FORMAT + "} must be between {1,date," + DATE_FORMAT
                        + "} and {2,date," + DATE_FORMAT + "} ", val, this.minDate, this.maxDate));
            }
        }

    }
}
</java>

which basically overcomes the conversion problem by defining the parameters as Strings and doing the conversion in the setters…