Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  // Copyright 2004, 2005 The Apache Software Foundation
  //
  // 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.apache.tapestry.components;
 
 import java.util.List;
 import java.util.Map;
 
 import  org.apache.hivemind.ApplicationRuntimeException;
 import  org.apache.hivemind.HiveMind;

Author(s):
mb
Since:
4.0
See also:
org.apache.tapestry.components.IPrimaryKeyConverter
org.apache.tapestry.util.DefaultPrimaryKeyConverter
 
 public abstract class ForBean extends AbstractFormComponent
 {
     // constants
     
    
Prefix on the hidden value stored into the field to indicate the the actual value is stored (this is used when there is no primary key converter). The remainder of the string is a squeezed representation of the value.
 
     private static final char DESC_VALUE = 'V';

    
Prefix on the hidden value stored into the field that indicates the primary key of the iterated value is stored; the remainder of the string is a squeezed representation of the primary key. The converter is used to obtain the value from this key.
 
     private static final char DESC_PRIMARY_KEY = 'P';
 
     private final RepSource _completeRepSource = new CompleteRepSource();
 
     private final RepSource _keyExpressionRepSource = new KeyExpressionRepSource();
 
     // intermediate members
     private Object _value;
 
     private int _index;
 
     private boolean _rendering;
     
     private boolean _hasNext = false;
     
     // parameters
     public abstract boolean getRenderTag();
     
     public abstract String getElement();
     
     public abstract String getKeyExpression();
 
     public abstract IPrimaryKeyConverter getConverter();
 
     public abstract Object getDefaultValue();
 
     public abstract boolean getMatch();
 
     public abstract boolean getVolatile();
 
     // injects
     public abstract DataSqueezer getDataSqueezer();
 
     public abstract ValueConverter getValueConverter();
 
     public abstract ExpressionEvaluator getExpressionEvaluator();
    
    public abstract ComponentRenderWorker getRenderWorker();
    
    public abstract ResponseBuilder getResponseBuilder();
    
    public boolean hasNext()
    {
        return ;
    }
    
    
Gets the source binding and iterates through its values. For each, it updates the value binding and render's its wrapped elements.
    protected void renderComponent(IMarkupWriter writerIRequestCycle cycle)
    {
        // form may be null if component is not located in a form
        IForm form = (IFormcycle.getAttribute(.);
        
        // If the cycle is rewinding, but not this particular form,
        // then do nothing (don't even render the body).
        
        boolean cycleRewinding = cycle.isRewinding();
        if (cycleRewinding && form != null && !form.isRewinding())
            return;
        
        setForm(form);
        
        // Get the data to be iterated upon. Store in form if needed.
        
        Iterator dataSource = getData(cycleform);
        // Do not iterate if dataSource is null.
        // The dataSource was either not convertable to Iterator, or was empty.
        
        if (dataSource == null)
            return;
        
        if (!cycleRewinding && form != null && !NullWriter.class.isInstance(writer))
            form.setFormFieldUpdating(true);
        
        String element = HiveMind.isNonBlank(getElement()) ? getElement() : getTemplateTagName();
        
        boolean render = !cycleRewinding && HiveMind.isNonBlank(element) && getRenderTag();
        
        IMarkupWriter loopWriter = writer;
        
        // Perform the iterations
        try
        {
             = 0;
             = true;
            
            while (dataSource.hasNext())
            {
                 = true;
                
                // Get current value
                 = dataSource.next();
                
                // Update output component parameters
                updateOutputParameters();
                
                // Render component
                // swap out writers if necessary
                
                if (getResponseBuilder().isDynamic()
                        && getResponseBuilder().contains(this
                        && !NestedMarkupWriterImpl.class.isInstance(writer)) {
                    
                    loopWriter = getResponseBuilder().getWriter(getClientId(), .);
                }
                
                if (render) {
                    
                    loopWriter.begin(element);
                    
                    renderInformalParameters(loopWritercycle);
                    renderIdAttribute(loopWritercycle);
                }
                
                renderBody(loopWritercycle);
                
                if (render) {
                    
                    loopWriter.end(element);
                }
                
                ++;
                
                 = dataSource.hasNext();
                
                // TODO: Fragile / messy
                // Cause unique client id to be generated as well as event connection
                // works or other after render workers. (basically reproduce what happens
                // inside of AbstractComponent.render() . Perhaps this means it's time for
                // refactoring of this logic, like deferring rendering to an actual component
                // that can have its proper render() method invoked multiple times.
                
                getRenderWorker().renderComponent(cyclethis);
                generateClientId();
                
                // set loopWriter back to original as the client ids/ etc change on each loop
                
                loopWriter = writer;
            }
        }
        finally
        {
             = false;
             = null;
        }
    }
    
    
Overriden so that RenderWorker doesn't get run as we've been invoking it manually already.
    protected void cleanupAfterRender(IRequestCycle cycle)
    {
    }
    
    protected void generateClientId()
    {
        String id = getSpecifiedId();
        
        if (id != null && getPage() != null && getPage().getRequestCycle() != null)
             setClientId(getPage().getRequestCycle().getUniqueId(TapestryUtils.convertTapestryIdToNMToken(id)));
    }
    
    
Returns the most recent value extracted from the source parameter.
    public final Object getValue()
    {
        if (!)
            throw Tapestry.createRenderOnlyPropertyException(this"value");
        return ;
    }

    
The index number, within the , of the the current value.
    public int getIndex()
    {
        if (!)
            throw Tapestry.createRenderOnlyPropertyException(this"index");
        return ;
    }
    public boolean isDisabled()
    {
        return false;
    }

    
Updates the index and value output parameters if bound.
    protected void updateOutputParameters()
    {
        IBinding indexBinding = getBinding("index");
        if (indexBinding != null)
            indexBinding.setObject(new Integer());
        IBinding valueBinding = getBinding("value");
        if (valueBinding != null)
            valueBinding.setObject();
    }

    
Updates the primaryKeys parameter if bound.
    protected void updatePrimaryKeysParameter(String[] stringReps)
    {
        IBinding primaryKeysBinding = getBinding("primaryKeys");
        if (primaryKeysBinding == null)
            return;
        DataSqueezer squeezer = getDataSqueezer();
        int repsCount = stringReps.length;
        List primaryKeys = new ArrayList(repsCount);
        for (int i = 0; i < stringReps.lengthi++)
        {
            String rep = stringReps[i];
            if (rep.length() == 0 || rep.charAt(0) != )
                continue;
            Object primaryKey = squeezer.unsqueeze(rep.substring(1));
            primaryKeys.add(primaryKey);
        }
        primaryKeysBinding.setObject(primaryKeys);
    }
    // Do nothing in those methods, but make the JVM happy
    protected void renderFormComponent(IMarkupWriter writerIRequestCycle cycle)
    {
    }
    protected void rewindFormComponent(IMarkupWriter writerIRequestCycle cycle)
    {
    }

    
Returns a list with the values to be iterated upon. The list is obtained in different ways: - If the component is not located in a form or 'volatile' is set to true, then the simply the values passed to 'source' are returned (same as Foreach) - If the component is in a form, and the form is rewinding, the values stored in the form are returned -- rewind is then always the same as render. - If the component is in a form, and the form is being rendered, the values are stored in the form as Hidden fields.

Parameters:
cycle The current request cycle
form The form within which the component is located (if any)
Returns:
An iterator with the values to be cycled upon
    private Iterator getData(IRequestCycle cycleIForm form)
    {
        if (form == null || getVolatile())
            return evaluateSourceIterator();
        
        String name = form.getElementId(this);
        
        if (cycle.isRewinding())
            return getStoredData(cyclename);
        
        return storeSourceData(formname);
    }

    
Returns a list of the values stored as Hidden fields in the form. A conversion is performed if the primary key of the value is stored.

Parameters:
cycle The current request cycle
name The name of the HTTP parameter whether the values
Returns:
an iterator with the values stored in the provided Hidden fields
    protected Iterator getStoredData(IRequestCycle cycleString name)
    {
        String[] stringReps = cycle.getParameters(name);
        if (stringReps == null)
            return null;
        updatePrimaryKeysParameter(stringReps);
        return new ReadSourceDataIterator(stringReps);
    }

    
Pulls data from successive strings (posted by client-side hidden fields); each string representation may be either a value or a primary key.
    private class ReadSourceDataIterator implements Iterator
    {
        private final Iterator _sourceIterator = evaluateSourceIterator();
        private final Iterator _fullSourceIterator = evaluateFullSourceIterator();
        private final String[] _stringReps;
        private int _index = 0;
        private final Map _repToValueMap = new HashMap();
        ReadSourceDataIterator(String[] stringReps)
        {
             = stringReps;
        }
        public boolean hasNext()
        {
            return  < .;
        }
        public Object next()
        {
            String rep = [++];
        }
        public void remove()
        {
            throw new UnsupportedOperationException("remove()");
        }
    }

    
Stores the provided data in the form and then returns the data as an iterator. If the primary key of the value can be determined, then that primary key is saved instead.

Parameters:
form The form where the data will be stored
name The name under which the data will be stored
Returns:
an iterator with the bound values stored in the form
    protected Iterator storeSourceData(IForm formString name)
    {
        return new StoreSourceDataIterator(formnameevaluateSourceIterator());
    }

    
Iterates over a set of values, using ForBean.getStringRepFromValue(Object) to obtain the correct client-side string representation, and working with the form to store each successive value into the form.
    private class StoreSourceDataIterator implements Iterator
    {
        private final IForm _form;
        private final String _name;
        private final Iterator _delegate;
        StoreSourceDataIterator(IForm formString nameIterator delegate)
        {
             = form;
             = name;
             = delegate;
        }
        public boolean hasNext()
        {
            return .hasNext();
        }
        public Object next()
        {
            Object value = .next();
            
            
            String rep = getStringRepFromValue(value);
            .addHiddenValue(rep);
            return value;
        }
        public void remove()
        {
            throw new UnsupportedOperationException("remove()");
        }
    }

    
Returns the string representation of the value. The first letter of the string representation shows whether a value or a primary key is being described.

Parameters:
value
Returns:
The string representation of the given value.
    protected String getStringRepFromValue(Object value)
    {
        String rep;
        
        DataSqueezer squeezer = getDataSqueezer();
        
        // try to extract the primary key from the value
        
        Object pk = getPrimaryKeyFromValue(value);
        
        try {
            if (pk != null) {
                // Primary key was extracted successfully.
                rep =  + squeezer.squeeze(pk);
            } else {
                // primary key could not be extracted. squeeze value.
                rep =  + squeezer.squeeze(value);
            }
            
        } catch (Exception e) {
            throw new ApplicationRuntimeException(ComponentMessages.keySqueezeError(thisvaluee), thisgetLocation(), e);
        }
        
        return rep;
    }

    
Returns the primary key of the given value. Uses the 'keyExpression' or the 'converter' (if either is provided).

Parameters:
value The value from which the primary key should be extracted
Returns:
The primary key of the value, or null if such cannot be extracted.
    protected Object getPrimaryKeyFromValue(Object value)
    {
        if (value == null)
            return null;
        
        Object primaryKey = getKeyExpressionFromValue(value);
        
        if (primaryKey == null)
            primaryKey = getConverterFromValue(value);
        return primaryKey;
    }

    
Uses the 'keyExpression' parameter to determine the primary key of the given value.

Parameters:
value The value from which the primary key should be extracted
Returns:
The primary key of the value as defined by 'keyExpression', or null if such cannot be extracted.
    protected Object getKeyExpressionFromValue(Object value)
    {
        String keyExpression = getKeyExpression();
        if (keyExpression == null)
            return null;
        Object primaryKey = getExpressionEvaluator().read(valuekeyExpression);
        return primaryKey;
    }

    
Uses the 'converter' parameter to determine the primary key of the given value.

Parameters:
value The value from which the primary key should be extracted
Returns:
The primary key of the value as provided by the converter, or null if such cannot be extracted.
    protected Object getConverterFromValue(Object value)
    {
        IPrimaryKeyConverter converter = getConverter();
        if (converter == null)
            return null;
        Object primaryKey = converter.getPrimaryKey(value);
        
        return primaryKey;
    }

    
Determines the value that corresponds to the given string representation. If the 'match' parameter is true, attempt to find a value in 'source' or 'fullSource' that generates the same string representation. Otherwise, create a new value from the string representation.

Parameters:
rep the string representation for which a value should be returned
Returns:
the value that corresponds to the provided string representation
    protected Object getValueFromStringRep(Iterator sourceIteratorIterator fullSourceIterator,
            Map repToValueMapString rep)
    {
        Object value = null;
        DataSqueezer squeezer = getDataSqueezer();
        // Check if the string rep is empty. If so, just return the default value.
        if (rep == null || rep.length() == 0)
            return getDefaultValue();
        
        // If required, find a value with an equivalent string representation and return it
        boolean match = getMatch();
        if (match)
        {
            value = findValueWithStringRepsourceIteratorfullSourceIteratorrepToValueMap,
                    rep);
            
            if (value != null)
                return value;
        }
        // Matching of the string representation was not successful or was disabled.
        // Use the standard approaches to obtain the value from the rep.
        
        char desc = rep.charAt(0);
        String squeezed = rep.substring(1);
        switch (desc)
        {
            case :
                // If the string rep is just the value itself, unsqueeze it
                value = squeezer.unsqueeze(squeezed);
                break;
                
            case :
                // Perform keyExpression match if not already attempted
                if (!match && getKeyExpression() != null)
                    value = findValueWithStringRep(
                            sourceIterator,
                            fullSourceIterator,
                            repToValueMap,
                            rep,
                            );
                // If 'converter' is defined, try to perform conversion from primary key to value
                if (value == null)
                {
                    IPrimaryKeyConverter converter = getConverter();
                    if (converter != null)
                    {
                        Object pk = squeezer.unsqueeze(squeezed);
                        value = converter.getValue(pk);
                    }
                }
                break;
        }
        if (value == null)
            value = getDefaultValue();
        return value;
    }

    
Attempt to find a value in 'source' or 'fullSource' that generates the provided string representation. Use the RepSource interface to determine what the string representation of a particular value is.

Parameters:
rep the string representation for which a value should be returned
repSource an interface providing the string representation of a given value
Returns:
the value in 'source' or 'fullSource' that corresponds to the provided string representation
    protected Object findValueWithStringRep(Iterator sourceIteratorIterator fullSourceIterator,
            Map repToValueMapString repRepSource repSource)
    {
        Object value = repToValueMap.get(rep);
        if (value != null)
            return value;
        value = findValueWithStringRepInIterator(sourceIteratorrepToValueMapreprepSource);
        if (value != null)
            return value;
        
        value = findValueWithStringRepInIterator(fullSourceIteratorrepToValueMapreprepSource);
        return value;
    }

    
Attempt to find a value in the provided collection that generates the required string representation. Use the RepSource interface to determine what the string representation of a particular value is.

Parameters:
rep the string representation for which a value should be returned
repSource an interface providing the string representation of a given value
it the iterator of the collection in which a value should be searched
Returns:
the value in the provided collection that corresponds to the required string representation
    protected Object findValueWithStringRepInIterator(Iterator itMap repToValueMapString rep,
            RepSource repSource)
    {
        while (it.hasNext())
        {
            Object sourceValue = it.next();
            if (sourceValue == null)
                continue;
            
            String sourceRep = repSource.getStringRep(sourceValue);
            repToValueMap.put(sourceRepsourceValue);
            
            if (rep.equals(sourceRep))
                return sourceValue;
        }
        return null;
    }

    
Returns a new iterator of the values in 'source'.

Returns:
the 'source' iterator
    protected Iterator evaluateSourceIterator()
    {
        Iterator it = null;
        Object source = null;
        IBinding sourceBinding = getBinding("source");
        if (sourceBinding != null)
            source = sourceBinding.getObject();
        
        if (source != null)
            it = (IteratorgetValueConverter().coerceValue(sourceIterator.class);
        
        if (it == null)
            it = ..iterator();
        return it;
    }

    
Returns a new iterator of the values in 'fullSource'.

Returns:
the 'fullSource' iterator
    {
        Iterator it = null;
        Object fullSource = null;
        IBinding fullSourceBinding = getBinding("fullSource");
        if (fullSourceBinding != null)
            fullSource = fullSourceBinding.getObject();
        if (fullSource != null)
            it = (IteratorgetValueConverter().coerceValue(fullSourceIterator.class);
        if (it == null)
            it = ..iterator();
        return it;
    }

    
An interface that provides the string representation of a given value.
    protected interface RepSource
    {
        String getStringRep(Object value);
    }

    
An implementation of RepSource that provides the string representation of the given value using all methods.
    protected class CompleteRepSource implements RepSource
    {
        public String getStringRep(Object value)
        {
            return getStringRepFromValue(value);
        }
    }

    
An implementation of RepSource that provides the string representation of the given value using just the 'keyExpression' parameter.
    protected class KeyExpressionRepSource implements RepSource
    {
        public String getStringRep(Object value)
        {
            Object pk = getKeyExpressionFromValue(value);
            return  + getDataSqueezer().squeeze(pk);
        }
    }

    
For component can not take focus.
    protected boolean getCanTakeFocus()
    {
        return false;
    }
    public String getDisplayName()
    {
        return null;
    }
New to GrepCode? Check out our FAQ X