blob: 762d4c6b2be22700e9811b5896f89ca9d705b615 [file] [log] [blame]
/* 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);
}
}
}
}