001/*
002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *    mcedica@nuxeo.com
018 *
019 * $Id$
020 */
021package org.nuxeo.ecm.webapp.widgets;
022
023import java.io.Serializable;
024import java.util.Date;
025import java.util.Map;
026
027import javax.faces.application.FacesMessage;
028import javax.faces.component.UIComponent;
029import javax.faces.component.UIInput;
030import javax.faces.context.FacesContext;
031import javax.faces.validator.ValidatorException;
032
033import org.apache.commons.logging.Log;
034import org.apache.commons.logging.LogFactory;
035import org.jboss.seam.ScopeType;
036import org.jboss.seam.annotations.In;
037import org.jboss.seam.annotations.Name;
038import org.jboss.seam.annotations.Scope;
039
040/**
041 * Compares two dates in a date range widget and throws a validation error if the second date is not superior to the
042 * first date.
043 * <p>
044 * Looks up component ids by reytrieving attributes on the validated component, named "startDateComponentId" and
045 * "endDateComponentId".
046 *
047 * @since 5.7
048 */
049@Name("dateRangeValidator")
050@Scope(ScopeType.CONVERSATION)
051public class DateRangeValidator implements Serializable {
052
053    private static final long serialVersionUID = 1L;
054
055    @In(create = true)
056    protected Map<String, String> messages;
057
058    private static final Log log = LogFactory.getLog(DateRangeValidator.class);
059
060    public void validateDateRange(FacesContext context, UIComponent component, Object value) {
061        Map<String, Object> attributes = component.getAttributes();
062        String startDateComponentId = (String) attributes.get("startDateComponentId");
063        String endDateComponentId = (String) attributes.get("endDateComponentId");
064        if (startDateComponentId == null || endDateComponentId == null) {
065            return;
066        }
067
068        UIInput startDateComp = (UIInput) component.findComponent(startDateComponentId);
069        UIInput endDateComp = (UIInput) component.findComponent(endDateComponentId);
070        if (startDateComp == null) {
071            log.error("Can not find component with id " + startDateComponentId);
072            return;
073        }
074
075        if (endDateComp == null) {
076            log.error("Can not find component with id " + endDateComponentId);
077            return;
078        }
079        Date stratDate = (Date) startDateComp.getLocalValue();
080        Date endDate = (Date) endDateComp.getLocalValue();
081
082        if (stratDate != null && endDate != null && endDate.compareTo(stratDate) < 0) {
083            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, String.format(
084                    messages.get("error.dateRangeValidator.invalidDateRange"), stratDate, endDate), null);
085            throw new ValidatorException(message);
086        }
087    }
088}