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.util.ArrayList;
018    import java.util.Collections;
019    import java.util.HashMap;
020    import java.util.Iterator;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.apache.commons.logging.Log;
025    import org.apache.commons.logging.LogFactory;
026    
027    import net.sf.beanform.prop.BeanProperty;
028    
029    /**
030     * Represents a chain of integration elements, the makeup of which will vary according to
031     * the execution environment.
032     *
033     * Note: If <a href="http://jcp.org/en/jsr/detail?id=303">JSR 303: Bean Validation</a> ever
034     * gets added to Java SE, add it to the integration chain.
035     *
036     * @author Daniel Gredler
037     */
038    public final class IntegratorChain {
039    
040        private final static Log LOG = LogFactory.getLog( IntegratorChain.class );
041        private final static List<Integrator> INTEGRATORS;
042    
043        static {
044            // Important note: The methods below are coded such that in the case of
045            // conflicting contributions, the last of the contributions is used.
046            List<Integrator> list = new ArrayList<Integrator>();
047            if( isSupported( "Hibernate", "org.hibernate.validator.Max" ) ) {
048                list.add( new HibernateIntegrator() );
049            }
050            if( isSupported( "EJB3", "javax.persistence.Column" ) ) {
051                list.add( new Ejb3Integrator() );
052            }
053            INTEGRATORS = Collections.unmodifiableList( list );
054        }
055    
056        static boolean isSupported( String featureName, String className ) {
057            Class c;
058            try {
059                c = Class.forName( className );
060            }
061            catch( ClassNotFoundException e ) {
062                c = null;
063            }
064            catch( NoClassDefFoundError e ) {
065                c = null;
066            }
067            boolean supported = ( c != null );
068            if( supported ) LOG.debug( featureName + " support detected." );
069            return supported;
070        }
071    
072        IntegratorChain() {
073            // Empty.
074        }
075    
076        public static String getValidation( BeanProperty prop ) {
077            Map<String, String> validations = new HashMap<String, String>();
078            for( Integrator integrator : INTEGRATORS ) {
079                Map<String, String> temp = integrator.getValidation( prop );
080                validations.putAll( temp );
081            }
082            StringBuilder sb = new StringBuilder();
083            for( Iterator<String> i = validations.values().iterator(); i.hasNext(); ) {
084                sb.append( i.next() );
085                if( i.hasNext() ) sb.append( "," );
086            }
087            if( sb.length() == 0 ) return null;
088            else return sb.toString();
089        }
090    
091        public static Integer getMaxLength( BeanProperty prop ) {
092            Integer maxLength = null;
093            for( Integrator integrator : INTEGRATORS ) {
094                Integer temp = integrator.getMaxLength( prop );
095                if( temp != null ) maxLength = temp;
096            }
097            return maxLength;
098        }
099    
100        public static boolean isNullable( BeanProperty prop ) {
101            boolean nullable = true;
102            for( Integrator integrator : INTEGRATORS ) {
103                boolean temp = integrator.isNullable( prop );
104                nullable = nullable && temp;
105            }
106            return nullable;
107        }
108    
109    }