001    /*
002     * Copyright (c) 2008, Your Corporation. All Rights Reserved.
003     */
004    
005    package org.chenillekit.tapestry.core.factories;
006    
007    import java.util.ArrayList;
008    import java.util.Arrays;
009    import java.util.List;
010    
011    import org.apache.tapestry5.Binding;
012    import org.apache.tapestry5.BindingConstants;
013    import org.apache.tapestry5.ComponentResources;
014    import org.apache.tapestry5.ioc.Location;
015    import org.apache.tapestry5.ioc.internal.util.TapestryException;
016    import org.apache.tapestry5.services.BindingFactory;
017    import org.apache.tapestry5.services.BindingSource;
018    
019    import org.chenillekit.tapestry.core.bindings.ListBinding;
020    
021    /**
022     * Binding factory where the expression is a collection type.
023     *
024     * @version $Id: LoopBindingFactory.java 594 2009-12-05 15:17:26Z mlusetti $
025     */
026    public class LoopBindingFactory implements BindingFactory
027    {
028        private final BindingSource _bindingSource;
029    
030        public LoopBindingFactory(BindingSource bindingSource)
031        {
032            _bindingSource = bindingSource;
033        }
034    
035        public Binding newBinding(String description, ComponentResources container, ComponentResources component,
036                                  String expression, Location location)
037        {
038            List<String> parts = Arrays.asList(expression.split(","));
039            ArrayList<Binding> bindings = new ArrayList<Binding>(parts.size());
040    
041            int startBy = 0;
042            int endBy = 0;
043            int stepBy = 1;
044    
045            if (parts.size() < 1)
046                throw new TapestryException("not enough parameters for loop binding", this, null);
047    
048            if (parts.size() >= 3)
049                stepBy = Integer.parseInt(parts.get(2));
050    
051            if (parts.size() >= 2)
052            {
053                endBy = Integer.parseInt(parts.get(1));
054                startBy = Integer.parseInt(parts.get(0));
055            }
056            else if (parts.size() == 1)
057                endBy = Integer.parseInt(parts.get(0));
058    
059            try
060            {
061                for (int x = startBy; x <= endBy; x += stepBy)
062                    bindings.add(_bindingSource.newBinding(description, container, component, BindingConstants.LITERAL, Integer.toString(x), location));
063            }
064            catch (OutOfMemoryError e)
065            {
066                throw new TapestryException(e.getLocalizedMessage(), this, null);
067            }
068    
069            boolean invariant = true;
070            for (Binding binding : bindings)
071            {
072                if (!binding.isInvariant())
073                {
074                    invariant = false;
075                    break;
076                }
077            }
078    
079            return new ListBinding(location, bindings, invariant);
080        }
081    }