You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Niall Pemberton (JIRA)" <ji...@apache.org> on 2008/11/14 00:26:44 UTC
[jira] Commented: (BEANUTILS-330) DefaultResolver being able to
handle parenthesis "(" and ")" in mapped property key names
[ https://issues.apache.org/jira/browse/BEANUTILS-330?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12647460#action_12647460 ]
Niall Pemberton commented on BEANUTILS-330:
-------------------------------------------
This has been requested before (BEANUTILS-109), but I'm not sure there a straightforward solution that works all the time - for example I don't believe your implementation would cope with a key of "ABC(DEF".
> 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
>
> Original Estimate: 2h
> Remaining Estimate: 2h
>
> 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.