/*
 * Copyright 2001-2010 Remi Vankeisbelck
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package woko.facets.builtin.hibernate;

import net.sourceforge.jfacets.annotations.FacetKey;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.validation.LocalizableError;
import net.sourceforge.stripes.validation.SimpleError;
import net.sourceforge.stripes.validation.ValidationErrors;
//import org.hibernate.validator.ClassValidator;
//import org.hibernate.validator.InvalidValue;
import woko.actions.WokoActionBean;
import woko.facets.BaseFacet;
import woko.facets.WokoFacetContext;
import woko.facets.builtin.WokoFacets;
import woko.util.WLogger;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.Validator;
import javax.validation.constraints.Min;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@FacetKey(name= WokoFacets.validate,profileId="all")
public class HibernateValidateFacet extends BaseFacet implements woko.facets.builtin.Validate {

    private static final Map<String, String> keyMapping = new HashMap<String, String>();
    static{
        keyMapping.put("javax.validation.constraints.AssertFalse.message", "validation.assertFalse");
        keyMapping.put("javax.validation.constraints.AssertTrue.message", "validation.assertTrue");
        keyMapping.put("javax.validation.constraints.DecimalMax.message", "validation.maxvalue.valueAboveMaximum");
        keyMapping.put("javax.validation.constraints.DecimalMin.message", "validation.minvalue.valueBelowMinimum");
        keyMapping.put("javax.validation.constraints.Digits.message", "validation.digits");
        keyMapping.put("javax.validation.constraints.Future.message", "validation.future");
        keyMapping.put("javax.validation.constraints.Max.message", "validation.maxvalue.valueAboveMaximum");
        keyMapping.put("javax.validation.constraints.Min.message", "validation.minvalue.valueBelowMinimum");
        keyMapping.put("javax.validation.constraints.NotNull.message", "validation.required.valueNotPresent");
        keyMapping.put("javax.validation.constraints.Null.message", "validation.null");
        keyMapping.put("javax.validation.constraints.Past.message", "validation.past");
        keyMapping.put("javax.validation.constraints.Pattern.message", "validation.pattern");
        keyMapping.put("javax.validation.constraints.Size.message", "validation.size");
        keyMapping.put("org.hibernate.validator.constraints.CreditCardNumber.message", "validator.creditCardNumber");
        keyMapping.put("org.hibernate.validator.constraints.Email.message", "validator.email");
        keyMapping.put("org.hibernate.validator.constraints.Length.message", "validator.length");
        keyMapping.put("org.hibernate.validator.constraints.NotBlank.message", "validator.notBlank");
        keyMapping.put("org.hibernate.validator.constraints.NotEmpty.message", "validator.notEmpty");
        keyMapping.put("org.hibernate.validator.constraints.Range.message", "validator.range");
        keyMapping.put("org.hibernate.validator.constraints.SafeHtml.message", "validator.safeHtml");
        keyMapping.put("org.hibernate.validator.constraints.ScriptAssert.message", "validator.scriptAssert");
        keyMapping.put("org.hibernate.validator.constraints.URL.message", "validator.url");
    }

    private static final String OBJECT_PREFIX = "object.";

    private static final WLogger log = WLogger.getLogger(HibernateValidateFacet.class);

    public boolean validate(ActionBeanContext abc) {
        // call hibernate validator and translate errors
        boolean hasErrors = false;
        ValidationErrors errs = abc.getValidationErrors();
        WokoFacetContext facetContext = getFacetContext();
        Object targetObject = facetContext.getTargetObject();
        ActionBean ab = (ActionBean)abc.getRequest().getAttribute("actionBean");
        Class<? extends ActionBean> abClass = ab!=null ? ab.getClass() : WokoActionBean.class;

        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(targetObject);

        for (ConstraintViolation<Object> c : constraintViolations){
            hasErrors = true;
            String fieldName = OBJECT_PREFIX + c.getPropertyPath();
            LocalizableError stripesError = new LocalizableError(getStripesKey(c.getMessageTemplate()), c.getConstraintDescriptor().getAttributes().values().toArray());
            stripesError.setFieldName(fieldName);
            stripesError.setBeanclass(abClass);
            errs.add(fieldName, stripesError);
        }
        return !hasErrors;
    }

    private String getStripesKey(String hibernateKey){
        hibernateKey = hibernateKey.replaceAll("\\{", "");
        hibernateKey = hibernateKey.replaceAll("\\}", "");
        if (keyMapping.containsKey(hibernateKey))
            return keyMapping.get(hibernateKey);
        else
            return "hibernate.error.with.no.equivalence.in.stripes";
    }

}

@@ -1105,24 +1105,66 @@
 ActionBean;%0A
+import woko.actions.WokoLocalizableError;%0A
 import woko.
@@ -5094,16 +5094,115 @@
         
+String fieldKey = targetObject.getClass().getSimpleName()+%22.%22+c.getPropertyPath();%0A            Woko
 Localiza
@@ -5210,23 +5210,20 @@
 leError 
-stripes
+woko
 Error = 
@@ -5226,16 +5226,20 @@
 r = new 
+Woko
 Localiza
@@ -5285,16 +5285,26 @@
 late()),
+ fieldKey,
  c.getCo
@@ -5365,39 +5365,36 @@
 ));%0A            
-stripes
+woko
 Error.setFieldNa
@@ -5420,23 +5420,20 @@
         
-stripes
+woko
 Error.se
@@ -5485,23 +5485,20 @@
 ldName, 
-stripes
+woko
 Error);%0A

Use new WokoLocalizableError to display errors