001    // Copyright 2006-2007 Daniel Gredler
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package net.sf.beanform.integration;
016    
017    import java.text.SimpleDateFormat;
018    import java.util.Date;
019    import java.util.SortedMap;
020    import java.util.TreeMap;
021    
022    import net.sf.beanform.prop.BeanProperty;
023    
024    import org.hibernate.validator.Email;
025    import org.hibernate.validator.Future;
026    import org.hibernate.validator.Length;
027    import org.hibernate.validator.Max;
028    import org.hibernate.validator.Min;
029    import org.hibernate.validator.NotNull;
030    import org.hibernate.validator.Past;
031    import org.hibernate.validator.Pattern;
032    import org.hibernate.validator.Range;
033    
034    /**
035     * Provides integration with Hibernate Validator annotations.
036     *
037     * Hibernate Validator annotations that are ignored:
038     * <ul>
039     *  <li>Size</li>
040     *  <li>AssertFalse</li>
041     *  <li>AssertTrue</li>
042     *  <li>Valid</li>
043     * </ul>
044     *
045     * @see http://www.hibernate.org/hib_docs/annotations/reference/en/html/validator.html
046     * @see http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/api/org/hibernate/validator/package-summary.html
047     * @author Daniel Gredler
048     */
049    public class HibernateIntegrator implements Integrator {
050    
051        public static final int LENGTH_MAX_DEFAULT = Integer.MAX_VALUE;
052        public static final int LENGTH_MIN_DEFAULT = 0;
053    
054        private static final String DATE_FORMAT = "MM/dd/yyyy";
055    
056        public SortedMap<String, String> getValidation( BeanProperty prop ) {
057    
058            SortedMap<String, String> validations = new TreeMap<String, String>();
059    
060            Length length = prop.getAnnotation( Length.class );
061            if( length != null ) {
062                int minLength = length.min();
063                if( minLength > LENGTH_MIN_DEFAULT ) {
064                    validations.put( MIN_LENGTH, MIN_LENGTH + "=" + minLength );
065                }
066                int maxLength = length.max();
067                if( maxLength < LENGTH_MAX_DEFAULT ) {
068                    validations.put( MAX_LENGTH, MAX_LENGTH + "=" + maxLength );
069                }
070            }
071    
072            Min min = prop.getAnnotation( Min.class );
073            if( min != null ) {
074                long minValue = min.value();
075                validations.put( MIN, MIN + "=" + minValue );
076            }
077    
078            Max max = prop.getAnnotation( Max.class );
079            if( max != null ) {
080                    long maxValue = max.value();
081                validations.put( MAX, MAX + "=" + maxValue );
082            }
083    
084            NotNull notNull = prop.getAnnotation( NotNull.class );
085            if( notNull != null ) {
086                validations.put( REQUIRED, REQUIRED );
087            }
088    
089            Past past = prop.getAnnotation( Past.class );
090            if( past != null ) {
091                SimpleDateFormat sdf = new SimpleDateFormat( DATE_FORMAT );
092                String date = sdf.format( new Date() );
093                validations.put( MAX_DATE, MAX_DATE + "=" + date );
094            }
095    
096            Future future = prop.getAnnotation( Future.class );
097            if( future != null ) {
098                SimpleDateFormat sdf = new SimpleDateFormat( DATE_FORMAT );
099                String date = sdf.format( new Date() );
100                validations.put( MIN_DATE, MIN_DATE + "=" + date );
101            }
102    
103            Pattern pattern = prop.getAnnotation( Pattern.class );
104            if( pattern != null ) {
105                String regex = pattern.regex();
106                validations.put( PATTERN, PATTERN + "=" + regex );
107            }
108    
109            Range range = prop.getAnnotation( Range.class );
110            if( range != null ) {
111                long minValue = range.min();
112                long maxValue = range.max();
113                validations.put( MIN, MIN + "=" + minValue );
114                validations.put( MAX, MAX + "=" + maxValue );
115            }
116    
117            Email email = prop.getAnnotation( Email.class );
118            if( email != null ) {
119                validations.put( EMAIL, EMAIL );
120            }
121    
122            return validations;
123        }
124    
125        public Integer getMaxLength( BeanProperty prop ) {
126    
127            Integer maxLength = null;
128    
129            Length length = prop.getAnnotation( Length.class );
130            if( length != null ) {
131                maxLength = length.max();
132            }
133    
134            return maxLength;
135        }
136    
137        public boolean isNullable( BeanProperty prop ) {
138    
139            boolean nullable = true;
140    
141            NotNull notNull = prop.getAnnotation( NotNull.class );
142            if( notNull != null ) {
143                nullable = false;
144            }
145    
146            return nullable;
147        }
148    
149    }