001 /*
002 * Databinder: a simple bridge from Wicket to Hibernate
003 * Copyright (C) 2008 Nathan Hamblen nathan@technically.us
004
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either
008 * version 2.1 of the License, or (at your option) any later version.
009 *
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013 * Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public
016 * License along with this library; if not, write to the Free Software
017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
018 */
019 package net.databinder.valid.hib;
020
021 import java.io.Serializable;
022
023 import net.databinder.components.hib.DataForm;
024 import net.databinder.models.hib.HibernateObjectModel;
025 import net.databinder.valid.hib.DatabinderValidator.UnrecognizedModelException;
026
027 import org.apache.wicket.markup.html.form.FormComponent;
028 import org.apache.wicket.validation.IValidatable;
029 import org.apache.wicket.validation.IValidator;
030 import org.hibernate.Hibernate;
031 import org.hibernate.validator.ClassValidator;
032 import org.hibernate.validator.InvalidValue;
033
034 /**
035 * Form that adds a {@link DatabinderValidator} to all its components that
036 * do not have any other validator in place. To exempt a component from
037 * this validation, add to it the dummy validator returned by {@link #nonValidator()}.
038 * Components are inspected in {@link #onBeforeRender()}. Those that do not have
039 * a usable model (see {@link DatabinderValidator#DatabinderValidator()}
040 * at that time are ignored.
041 * @author Nathan Hamblen
042 * @see DatabinderValidator
043 */
044 public class ValidDataForm extends DataForm {
045 /**
046 * Instantiates this form and a new, blank instance of the given class as a persistent model
047 * object. By default the model object created is serialized and retained between requests until
048 * it is persisted.
049 * @param id
050 * @param modelClass for the persistent object
051 * @see HibernateObjectModel#setRetainUnsaved(boolean)
052 */
053 public ValidDataForm(String id, Class modelClass) {
054 super(id, modelClass);
055 }
056
057 public ValidDataForm(String id, HibernateObjectModel model) {
058 super(id, model);
059 }
060
061 /**
062 * Instantiates this form with a persistent object of the given class and id.
063 * @param id Wicket id
064 * @param modelClass for the persistent object
065 * @param persistentObjectId id of the persistent object
066 */
067 public ValidDataForm(String id, Class modelClass, Serializable persistentObjectId) {
068 super(id, modelClass, persistentObjectId);
069 }
070
071 /**
072 * Form that is nested below a component with a compound model containing a Hibernate
073 * model.
074 * @param id
075 */
076 public ValidDataForm(String id) {
077 super(id);
078 }
079
080 @SuppressWarnings("unchecked")
081 protected void validateModelObject() {
082 Object o = getPersistentObjectModel().getObject();
083 for (InvalidValue iv : new ClassValidator(Hibernate.getClass(o)).getInvalidValues(o))
084 error(iv.getPropertyName() + " " + iv.getMessage());
085 }
086
087 /**
088 * Add a validator to any form components that have no existing validator
089 * and whose model is recognized by {@link DatabinderValidator#addTo(FormComponent)}.
090 */
091 @Override
092 protected void onBeforeRender() {
093 super.onBeforeRender();
094 visitFormComponents(new FormComponent.AbstractVisitor() {
095 @Override
096 protected void onFormComponent(FormComponent formComponent) {
097 if (formComponent.getValidators().isEmpty()) try {
098 DatabinderValidator.addTo(formComponent);
099 } catch (UnrecognizedModelException e) { }
100 }
101 });
102 }
103
104 /**
105 * @return dummy validator that can be used to exempt a component
106 * from this form's inspection in {@link #onBeforeRender()}
107 */
108 public static IValidator nonValidator() {
109 return new IValidator() {
110 public void validate(IValidatable validatable) { }
111 };
112 }
113 }