Change IAutocompleterModel semantics to be object friendly instead of string 
friendly
-------------------------------------------------------------------------------------

                 Key: TAPESTRY-1171
                 URL: http://issues.apache.org/jira/browse/TAPESTRY-1171
             Project: Tapestry
          Issue Type: Improvement
    Affects Versions: 4.1.1
            Reporter: Ron Piterman


The semantics of the IAutocompleterModel is unclear.
According to bugfix of http://issues.apache.org/jira/browse/TAPESTRY-1169 the 
following is the scenario:
The Objects returned in the map from filterValues(String) are toString()ed to 
get the label.
The same objects are used to extract the primaryKey.
A method should be implemented - getLabelFor( Object ).

Now - if one uses toString() - why implement getLabelFor(Object) - which object 
is passed to getLabelFor() ? only the current value? why ? why not use 
getLabelFor() also on the map values?generic 

So, the current use of the model can be represented as :

public interface IAutocompleteModel<VAL,KEY> // extends IPrimaryKeyConverter
{
  
  String getLabelFor(VAL value);
     
  Map<KEY,String> filterValues(String match);    

 @Override
 KEY getPrimaryKey(VAL value);

 @Override
 VAL getValue(KEY primaryKey);

}

Where it should be :

public interface IAutocompleteModel<VAL,KEY> // extends IPrimaryKeyConverter
{
  
  String getLabelFor(VAL value);
     
  Map<KEY,VAL> filterValues(String match);    

 @Override
 KEY getPrimaryKey(VAL mapValue);

 @Override
 VAL getValue(KEY primaryKey);

}

Currently, one have to wrap entities in a custom class in order them to be used 
in the Autocompleter :

I have an Autocmpleter which should search over Equities - as one could expect, 
there are alot of them,

So instead of a straightforward implementation:
public class EquityModel implements IAutocompleteModel
{
    private OrderFacade orderFacade;
    
    private static final int MAX_RESULTS = 20;
    
    private Log log = LogFactory.getLog( EquityModel.class );

    public Map filterValues(String match)
    {
        log.debug("Searching equity for: " + match);
        
        Collection<Equity> list = this.orderFacade.findEquitiesByName( match );
        
        log.debug("Found " + list.size() + "equities" );
        
        Map<Long,Equity> map = new HashMap<Long,Equity>();
        if ( list == null )
            return map;
        
        int i = 0;
        for ( Equity e : list ) {
            map.put( e.getId() , e );
            if ( i++ >= MAX_RESULTS )
                break;
        }
        return map;
    }

    public String getLabelFor(Object value)
    {
        return ((Equity)value).getName();
    }

    public Object getPrimaryKey(Object value)
    {
        return ((Equity)value).getId();
    }

    public Object getValue(Object primaryKey)
    {
        return this.orderFacade.getEquity( (Long)primaryKey );
    }
    
    public void init() {
        this.orderFacade = EJBResolver.getBean( OrderFacade.class );
    }

}

Now either I have to change the Equity.toString() method - but why should I ? 
what is the getLabelFor() method for ? also, the backend needs the toString() 
for logging - I can not just change an entity toString() just because tapestry 
uses it for the forntend...

Or, I have to use a wrapper class, which is actually obsolete, if the 
Autocompleter would have used the map as it "should"tag:

public class EquityModel implements IAutocompleteModel
{
    ...

    public Map filterValues(String match)
    {
        log.debug("Searching equity for: " + match);
        
        Collection<Equity> list = this.orderFacade.findEquitiesByName( match );
        
        log.debug("Found " + list.size() + "equities" );
        
        Map<Long,EquityWrapper> map = new HashMap<Long,EquityWrapper>();
        if ( list == null )
            return map;
        
        int i = 0;
        for ( Equity e : list ) {
            map.put( e.getId() , new EquityWrapper(e) );
            if ( i++ >= MAX_RESULTS )
                break;
        }
        return map;
    }

    public String getLabelFor(Object value)
    {
        // is this ever called ?
        return ((Equity)value).getName();
    }

    public Object getPrimaryKey(Object value)
    {
        return ((EquityWrapper)value).getEquity().getId();
    }

    public Object getValue(Object primaryKey)
    {
        return this.orderFacade.getEquity( (Long)primaryKey );
    }
    
    public void init() {
        this.orderFacade = EJBResolver.getBean( OrderFacade.class );
    }

}


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to