commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pierre Post (JIRA)" <j...@apache.org>
Subject [jira] Created: (BEANUTILS-330) DefaultResolver being able to handle parenthesis "(" and ")" in mapped property key names
Date Wed, 12 Nov 2008 15:35:44 GMT
DefaultResolver being able to handle parenthesis "(" and ")" in mapped property key names
-----------------------------------------------------------------------------------------

                 Key: BEANUTILS-330
                 URL: https://issues.apache.org/jira/browse/BEANUTILS-330
             Project: Commons BeanUtils
          Issue Type: Improvement
          Components: Expression Syntax
         Environment: java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode, sharing)
            Reporter: Pierre Post
             Fix For: 1.8.0


Unfortunately, the new {{org.apache.commons.beanutils.expression.DefaultResolver}} class is
unable to handle mapped property key names that contain parenthesis "(" and ")". Following
properties cause an exception when using {{BeanUtils.populate()}}.

{code:title=Bean.properties}job[0].param(anotherParam(key))=value{code}

{code:title=Bean.java}// JavaBean class
public class Bean {
   private List<Job> job;

   public static class Job {
      private Map<String, String> param;

      // appropriate public getters and setters here
   }

   // appropriate public getters and setters here
}{code}

{noformat}
java.lang.IllegalArgumentException: No bean specified
	at org.apache.commons.beanutils.PropertyUtilsBean.getPropertyDescriptor(PropertyUtilsBean.java:874)
	at org.apache.commons.beanutils.BeanUtilsBean.setProperty(BeanUtilsBean.java:933)
	at org.apache.commons.beanutils.BeanUtilsBean.populate(BeanUtilsBean.java:830)
...
{noformat}

I slightly modified the {{getKey()}} and {{next()}} methods so that they can handle multiple
nested mapped delimiters. Now, when using a {{BeanUtilsBean}} instance with a {{PropertyUtilsBean}}
and my new resolver, the above properties are accepted without exception:

{code:title=MyResolver.java}public class MyResolver extends DefaultResolver {
   // delimiter constants here

   public String getKey(String expression) {
        if (expression == null || expression.length() == 0) {
            return null;
        }
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (c == NESTED || c == INDEXED_START) {
                return null;
            } else if (c == MAPPED_START) {
                int end = getMappedEnd(expression, i);
                if (end < 0) {
                    throw new IllegalArgumentException("Missing End Delimiter");
                }
                return expression.substring(i + 1, end);
            }
        }
        return null;
    }
    
    public String next(String expression) {
        if (expression == null || expression.length() == 0) {
            return null;
        }
        boolean indexed = false;
        int mappedCount = 0;
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (indexed) {
                if (c == INDEXED_END) {
                    return expression.substring(0, i + 1);
                }
            } else if (mappedCount > 0) {
                if (c == MAPPED_START) {
                    mappedCount++;
                } else if (c == MAPPED_END) {
                    mappedCount--;
                    if (mappedCount == 0) {
                        return expression.substring(0, i + 1);
                    }
                }                
            } else {
                if (c == NESTED) {
                    return expression.substring(0, i);
                } else if (c == MAPPED_START) {
                    mappedCount++;
                } else if (c == INDEXED_START) {
                    indexed = true;
                }
            }
        }
        return expression;
    }
    
    private int getMappedEnd(String expression, int start) {
        int count = 0;
        for (int i = start; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (c == MAPPED_START) {
                count++;
            } else if (c == MAPPED_END) {
                count--;
                if (count == 0) {
                    return i;
                }
            }            
        }
        return -1;
    }
}{code}

If the changes don't affect the other uses of a resolver, I would recommend to adapt {{DefaultResolver}}
accordingly as nothing forbids to have "(" and ")" in a key name if I correctly understand.

Best regards,
Pierre

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message