[ 
http://issues.apache.org/jira/browse/IBATIS-281?page=comments#action_12378050 ] 

Christian Poitras commented on IBATIS-281:
------------------------------------------

The best way to correct this issue is to change the IterateContext class to add 
a "public IterateContext getParent()" method.
Or the SqlTagContext class could be changed to add a "public IterateContext 
getIterateContext(int i)" or a "public IterateContext 
getParentIterateContext(IterateContext ic)".

Another way to fix this in a convenient way would be to allow access to any 
parent tag we want based on the JSP model of java. The method "public static 
final Tag findAncestorWithClass(Tag from, Class klass)" from class 
javax.servlet.jsp.tagext.TagSupport gives a good way to search for any parent 
class we want to look at and will simplify my patch and make it readable for 
most people.
This part of code from IterateTagHandler could be simplified since it only 
searches for the parent IterateContext.

For example, the patch.
                  // Add iteration number to property.
                  Object parentContext = ctx.getAttribute(parentTag);
                  while (!(parentContext instanceof IterateContext)) {
                      parentTag = parentTag.getParent();
                      parentContext = ctx.getAttribute(parentTag);
                  }
                  IterateContext parentIterateContext = (IterateContext) 
parentContext;


could be changed to:
                  // Add iteration number to property.
                  IterateContext parentIterate = 
ctx.getAttribute(parentIterate);


Also a utility class could handle the problem of adding the value of many 
IterateContext to any property value of any tags or any replacement value 
contained in a sql request (like #list[].id#) by executing the code in the 
patch in only one place.

Considering this, it would make correcting this bug in any very easy since we 
could also handle the current problem of my patch which is having the following 
tag <isEqual property="list[].list[3].list[].id" value="someValue"/>. It throws 
an exception when processing the "list[3]" part. By putting this logic in one 
place, we could check if a number is already between the "[]" and skip the 
corresponding IterateContext (if it is linked to an iterateContext).
But we must be carreful that the following example will not cause a problem, so 
we can't automatically skip an IterateContext without first checking if the 
"[]" is linked to an iterate tag.
<select>
  <iterate property="list">
    <iterate property="list[].list[3].list">
    </iterate>
  </iterate>
</select>

> Nested iterate tags does not work
> ---------------------------------
>
>          Key: IBATIS-281
>          URL: http://issues.apache.org/jira/browse/IBATIS-281
>      Project: iBatis for Java
>         Type: Bug

>   Components: SQL Maps
>     Versions: 2.1.7
>     Reporter: Christian Poitras
>  Attachments: ConditionalTagHandler.java, DynamicSql.java, 
> IterateTagHandler.java
>
> No nested iterate tags work. The second iterate tag is not supported and 
> produces the following error.
> java.lang.NumberFormatException: For input string: ""
> at 
> java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
> at java.lang.Integer.parseInt(Integer.java:489)
> at java.lang.Integer.parseInt(Integer.java:518)
> at com.ibatis.common.beans.BaseProbe.getIndexedProperty(BaseProbe.java:51)
> at 
> com.ibatis.common.beans.ComplexBeanProbe.getProperty(ComplexBeanProbe.java:297)
> at 
> com.ibatis.common.beans.ComplexBeanProbe.getObject(ComplexBeanProbe.java:188)
> at com.ibatis.common.beans.GenericProbe.getObject(GenericProbe.java:76)
> at 
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements.IterateTagHandler.doStartFragment(IterateTagHandler.java:34)
> at 
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:157)
> at 
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:160)
> at 
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.processBodyChildren(DynamicSql.java:99)
> at 
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.process(DynamicSql.java:79)
> at 
> com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql.getParameterMap(DynamicSql.java:61)
> at 
> com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:156)
> at 
> com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123)
> at 
> com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:610)
> at 
> com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:584)
> at 
> com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:101)
> at 
> com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForList(SqlMapClientImpl.java:78)
> at 
> com.ibatis.dao.client.template.SqlMapDaoTemplate.queryForList(SqlMapDaoTemplate.java:203)
> at 
> ca.qc.ircm.lana.persistence.sqlmapdao.SpotSqlMapDao.getSpotsInter(SpotSqlMapDao.java:159)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:324)
> at com.ibatis.dao.engine.impl.DaoProxy.invoke(DaoProxy.java:72)
> at $Proxy14.getSpotsInter(Unknown Source)
> at 
> ca.qc.ircm.lana.service.InterpretationService.getSpotsInter(InterpretationService.java:82)
> at TEST.testInterpretation.main(testInterpretation.java:111)
> It seems the second iterate tag cannot have a property of this type.
> <iterate property="list" >
>   <iterate property="list[].list">
>   <iterate>
> </iterate>
> On the nested iterate, SQL Maps does not add the number in attribute property 
> "list[].list" and tries to call a getter for parameterClass.getList[]() and 
> this is not allowed and produces the error.
> This could be prevented in the IterateTagHandler class (doStartFragment 
> method) by adding code that replaces "[]" in the property attribute by values 
> of IterateContext that are parents of the current tag (for multiple nested 
> iterate).
> Other code would need to be updated since using a property in the second list 
> also causes SQL Map to crash even it IterateTagHandler is patched.
> <iterate property="list" >
>   <iterate property="list[].list">
>     #list[].list[].someProperty#
>   <iterate>
> </iterate>
> I produced a patch that can correct the problem. I will include it in a 
> future message.

-- 
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

Reply via email to