| /* Copyright 2004-2005 the original author or authors. |
| * |
| * 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 org.codehaus.groovy.grails.orm.hibernate.validation; |
| |
| import java.sql.SQLException; |
| import java.text.MessageFormat; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.codehaus.groovy.grails.validation.ConstrainedProperty; |
| import org.codehaus.groovy.grails.validation.Constraint; |
| |
| import org.hibernate.HibernateException; |
| import org.hibernate.Session; |
| import org.hibernate.criterion.Restrictions; |
| import org.springframework.orm.hibernate3.HibernateCallback; |
| import org.springframework.orm.hibernate3.HibernateTemplate; |
| import org.springframework.validation.Errors; |
| /** |
| * Extends ConstrainedProperty to provide additional validation against database specific constraints |
| * |
| * @author Graeme Rocher |
| * @since 10-Nov-2005 |
| */ |
| public class ConstrainedPersistentProperty extends ConstrainedProperty { |
| |
| public static final String UNIQUE_CONSTRAINT = "unique"; |
| |
| |
| private static final String DEFAULT_NOT_UNIQUE_MESSAGE = bundle.getString("default.not.unique.message"); |
| private HibernateTemplate hibernateTemplate; |
| |
| static { |
| constraints.put( UNIQUE_CONSTRAINT, UniqueConstraint.class ); |
| } |
| |
| static protected abstract class AbstractPersistentConstraint extends AbstractConstraint implements PersistentConstraint { |
| |
| protected HibernateTemplate constraintHibernateTemplate; |
| |
| /* (non-Javadoc) |
| * @see org.codehaus.groovy.grails.orm.hibernate.validation.PersistentConstraint#setHibernateTemplate(org.springframework.orm.hibernate3.HibernateTemplate) |
| */ |
| public void setHibernateTemplate(HibernateTemplate template) { |
| this.constraintHibernateTemplate = template; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.codehaus.groovy.grails.validation.ConstrainedProperty.AbstractConstraint#validate(java.lang.Object, org.springframework.validation.Errors) |
| */ |
| public void validate(Object propertyValue, Errors errors) { |
| if(constraintHibernateTemplate == null) |
| throw new IllegalStateException("PersistentConstraint requires an instance of HibernateTemplate."); |
| |
| super.validate(propertyValue, errors); |
| } |
| } |
| |
| /** |
| * |
| * A constraint that validates the uniqueness of a property |
| */ |
| static private class UniqueConstraint extends AbstractPersistentConstraint { |
| |
| private boolean unique; |
| |
| /** |
| * @return Returns the unique. |
| */ |
| public boolean isUnique() { |
| return unique; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.codehaus.groovy.grails.validation.ConstrainedProperty.AbstractConstraint#setParameter(java.lang.Object) |
| */ |
| public void setParameter(Object constraintParameter) { |
| if(!(constraintParameter instanceof Boolean)) |
| throw new IllegalArgumentException("Parameter for constraint ["+UNIQUE_CONSTRAINT+"] of property ["+constraintPropertyName+"] of class ["+constraintOwningClass+"] must be a boolean value"); |
| |
| this.unique = ((Boolean)constraintParameter).booleanValue(); |
| super.setParameter(constraintParameter); |
| } |
| |
| protected void processValidate(final Object propertyValue, Errors errors) { |
| |
| if(unique) { |
| List results = this.constraintHibernateTemplate.executeFind( new HibernateCallback() { |
| |
| public Object doInHibernate(Session session) throws HibernateException, SQLException { |
| return session.createCriteria( constraintOwningClass ) |
| .add( Restrictions.eq( constraintPropertyName, propertyValue ) ) |
| .list(); |
| |
| } |
| |
| }); |
| if(results.size() > 0) { |
| Object[] args = new Object[] { constraintPropertyName, constraintOwningClass, propertyValue }; |
| super.rejectValue(errors,UNIQUE_CONSTRAINT,args,MessageFormat.format( DEFAULT_NOT_UNIQUE_MESSAGE, args )); |
| } |
| } |
| } |
| |
| public boolean supports(Class type) { |
| return true; |
| } |
| |
| } |
| |
| |
| public ConstrainedPersistentProperty(Class clazz, String propertyName, Class propertyType) { |
| super(clazz, propertyName, propertyType); |
| } |
| |
| |
| /** |
| * @return Returns the hibernateTemplate. |
| */ |
| public HibernateTemplate getHibernateTemplate() { |
| return hibernateTemplate; |
| } |
| |
| |
| /** |
| * @param hibernateTemplate The hibernateTemplate to set. |
| */ |
| public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { |
| this.hibernateTemplate = hibernateTemplate; |
| } |
| |
| /** |
| * @return Returns the unique. |
| */ |
| public boolean isUnique() { |
| UniqueConstraint c = (UniqueConstraint)this.appliedConstraints.get( UNIQUE_CONSTRAINT ); |
| if(c == null) |
| return false; |
| |
| return c.isUnique(); |
| } |
| /** |
| * @param unique The unique to set. |
| */ |
| public void setUnique(boolean unique) { |
| |
| Constraint c = (Constraint)this.appliedConstraints.get( UNIQUE_CONSTRAINT ); |
| |
| if(c != null) { |
| c.setParameter( new Boolean(unique) ); |
| } |
| else { |
| c = new UniqueConstraint(); |
| c.setOwningClass(this.owningClass); |
| c.setPropertyName(this.propertyName); |
| c.setParameter(new Boolean(unique)); |
| this.appliedConstraints.put( UNIQUE_CONSTRAINT,c ); |
| } |
| } |
| /* (non-Javadoc) |
| * @see org.codehaus.groovy.grails.validation.ConstrainedProperty#validate(java.lang.Object, org.springframework.validation.Errors) |
| */ |
| public void validate(Object propertyValue, Errors errors) { |
| |
| for (Iterator i = this.appliedConstraints.values().iterator(); i.hasNext();) { |
| Constraint c = (Constraint) i.next(); |
| if(c instanceof PersistentConstraint) { |
| PersistentConstraint pc = (PersistentConstraint)c; |
| pc.setHibernateTemplate(this.hibernateTemplate); |
| pc.validate( propertyValue, errors ); |
| } |
| else { |
| c.validate( propertyValue, errors); |
| } |
| } |
| } |
| |
| |
| } |