001    package org.apache.commons.contract.constraints;
002    
003    import java.util.Iterator;
004    import java.util.List;
005    import java.util.Locale;
006    
007    import org.apache.commons.contract.Context;
008    import org.apache.commons.i18n.bundles.ErrorBundle;
009    import org.apache.commons.i18n.bundles.TextBundle;
010    
011    public class ArrayConstraints implements Constraints {
012        public static final ArrayConstraints UNCONSTRAINED = new ArrayConstraints();
013    
014        protected Constraints entryValueDescriptor;
015    
016        public ArrayConstraints() {
017            entryValueDescriptor = Unconstrained.UNCONSTRAINED;
018        }
019    
020        public ArrayConstraints(Constraints entryValueDescriptor) {
021            this.entryValueDescriptor = entryValueDescriptor;
022        }
023    
024        public void setEntryValueDescriptor(Constraints entryValueDescriptor) {
025            this.entryValueDescriptor = entryValueDescriptor;
026        }
027    
028        public Constraints getEntryValueDescriptor() {
029            return entryValueDescriptor;
030        }
031    
032        public Object cast(Object value, Context context) throws CastException {
033            Object[] array = null;
034            if ( value instanceof String[] ) {
035                    array = new Object[((String[])value).length];
036                    for ( int i = 0; i < array.length; i++ ) {
037                            array[i] = entryValueDescriptor.cast(((String [])value)[i], context);
038                    }
039            } else if ( value instanceof List ) {
040                    array = new Object[((List)value).size()];
041                    int counter = 0;
042                    for ( Iterator i = ((List)value).iterator(); i.hasNext(); ) {
043                            Object entry = i.next();
044                    if ( entry instanceof Evaluatable ) {
045                        try {
046                            entry = ((Evaluatable)entry).evaluate(context);
047                        } catch (Exception e) {
048                            throw new CastException(new ErrorBundle("evaluatingAnyFailed"), e);
049                        }
050                    }
051                                    array[counter] = entryValueDescriptor.cast(entry, context);
052                            counter++;
053                    }
054            } else if ( value instanceof Object[] ) {
055                array = new Object[((Object[])value).length];
056                    for ( int i = 0; i < array.length; i++ ) {
057                            Object entry = ((Object[])value)[i];
058                    if ( entry instanceof Evaluatable ) {
059                        try {
060                            entry = ((Evaluatable)entry).evaluate(context);
061                        } catch (Exception e) {
062                            throw new CastException(new ErrorBundle("evaluatingAnyFailed"), e);
063                        }
064                    }
065                                    array[i] = entryValueDescriptor.cast(entry, context);
066                    }
067            } else {
068                    throw new CastException(new ErrorBundle("uncastableArray", new Object[] { value }));
069            }
070                    return array;
071        }
072        
073        public void validate(Object value, Context context) throws ValidationException {
074            try {
075                    Object[] array = (Object [])value;
076                    for ( int i = 0; i < array.length; i++ ) {
077                            if ( array[i] != null ) {
078                                    entryValueDescriptor.validate(array[i], context);
079                            }
080                    }
081            } catch ( ValidationException exception ) {
082                    throw new ValidationException(new ErrorBundle("invalidArrayEntry", new Object[] { value }), exception);
083            }
084        }
085        
086        public TextBundle verboseConstraints() {
087            if ( entryValueDescriptor == Unconstrained.UNCONSTRAINED ) {
088                return new TextBundle("unconstrainedArray");
089            } else {
090                TextBundle verbosedEntryContrstaints = entryValueDescriptor.verboseConstraints();
091                return new TextBundle("constrainedArray", new String[] {  verbosedEntryContrstaints.getText(Locale.getDefault()) });
092            }
093        }
094    }