вложение строк выражения JSF

Я хочу добиться этого, используя динамические параметры для выражений значений:

<h:dataTable value="#{someBean.someValue}" var="field">
    <h:column>#{anotherBean[field]}</h:column>
</h:dataTable>

гдеfield является'user.name' или же'location.address.zip' или же...

Является ли это возможным?

Обратите внимание, что это простой пример, который мне интересенValueExpression не вdataTable составная часть.

UPDATE Теперь вопрос: как заменить стандартный BeanELResolver?

смотря в ELUtils:

    ...
    composite.addRootELResolver(IMPLICIT_RESOLVER);
    composite.add(FLASH_RESOLVER);
    composite.addPropertyELResolver(COMPOSITE_COMPONENT_ATTRIBUTES_EL_RESOLVER);
    addELResolvers(composite, associate.getELResolversFromFacesConfig());
    addVariableResolvers(composite, FacesCompositeELResolver.ELResolverChainType.Faces,
            associate);
    addPropertyResolvers(composite, associate);
    composite.add(associate.getApplicationELResolvers());
    composite.addRootELResolver(MANAGED_BEAN_RESOLVER);
    composite.addPropertyELResolver(RESOURCE_RESOLVER);
    composite.addPropertyELResolver(BUNDLE_RESOLVER);
    ...

но я еще не полностью понимаю цепочку резольвера ... так что я пойду изучать :)

UPDATE 2

этот код работает;)

public class ExtendedBeanELResolver extends BeanELResolver
{
    @Override
    public Object getValue(ELContext context, Object base, Object property) throws NullPointerException, PropertyNotFoundException, ELException
    {
        try
        {
            return super.getValue(context, base, property);
        }
        catch(PropertyNotFoundException e)
        {
            try
            {
                Object value = base;

                for(String part : property.toString().split("\\."))
                {
                    value = super.getValue(context, value, part);
                }

                return value;
            }
            catch(PropertyNotFoundException e1)
            {
                context.setPropertyResolved(false);
            }
        }

        return null;
    }
}
 Michele Mariotti22 мая 2012 г., 09:38
нет, я говорю правильно:public List<String> getSomeValue() { ... }

Ответы на вопрос(2)

Работа над этой темой очень интересная, но не полная.

В случае, если вы передаете значение в составной компонент, который установлен в этом компоненте, он не работает.

Пример :

<composite:interface>
    <composite:attribute name="value" type="java.lang.Boolean" required="true"  />
</composite:interface>
<composite:implementation>
        <h:inputText id="inputValue" value="#{cc.attrs.value}" 
        </h:inputText>
</composite:implementation>

С ExtendedBeanElResolver он выдает исключение PropertyNotFoundException, когда я устанавливаю значение.

Итак, я трачу несколько часов, чтобы найти решение, и вот рабочее решение, чтобы иметь возможность использовать ExtendedBeanElResolver с возможностью устанавливать значения внутри составных компонентов:

public class ExtendedBeanELResolver extends BeanELResolver {

    private static final String PRIMEFACES_RESOURCE_PREFIX = "primefaces:";
    private static final String RESOURCES_HANDLER = "class org.omnifaces.resourcehandler.GraphicResourceHandler";
    private static final String PRIMEFACES_EXT_RESOURCES_HANDLER = "class org.primefaces.extensions.application.PrimeFacesExtensionsResourceHandler";

    @Override
    public Object getValue(ELContext context, Object base, Object property) {

            if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map || base instanceof Collection
                    || property.toString().startsWith(PRIMEFACES_RESOURCE_PREFIX) || base.getClass().toString().equals(RESOURCES_HANDLER)
                    || base.getClass().toString().equals(PRIMEFACES_EXT_RESOURCES_HANDLER)) {
                return null;
            }
            String propertyString = property.toString();
            if (propertyString.contains(".")) {
                Object value = base;

                for (String propertyPart : propertyString.split("\\.")) {
                    value = super.getValue(context, value, propertyPart);
                }

                return value;
            } else {
                Object v = super.getValue(context, base, property);
               return v;
            }
    }

    @Override
    public void setValue(ELContext context, Object base, Object property, Object val) {
        if (base != null && !(base instanceof ResourceBundle) && !(base instanceof Map) && !(base instanceof Collection))
            super.setValue(context, base, property, val);
    }
}

(Я добавил часть «setValue»).

И теперь это работает. Не стесняйтесь дать мне свой отзыв, так как это мой первый пост на этом сайте!

Решение Вопроса

Это по умолчанию не поддерживается. Вам нужен кастомELResolver Вот. Проще всего продлить существующийBeanELResolver.

Вот пример запуска:

public class ExtendedBeanELResolver extends BeanELResolver {

    @Override
    public Object getValue(ELContext context, Object base, Object property)
        throws NullPointerException, PropertyNotFoundException, ELException
    {
        if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map || base instanceof Collection) {
            return null;
        }

        String propertyString = property.toString();

        if (propertyString.contains(".")) {
            Object value = base;

            for (String propertyPart : propertyString.split("\\.")) {
                value = super.getValue(context, value, propertyPart);
            }

            return value;
        }
        else {
            return super.getValue(context, base, property);
        }
    }

}

Чтобы запустить его, зарегистрируйте его следующим образом вfaces-config.xml:

<application>
    <el-resolver>com.example.ExtendedBeanELResolver</el-resolver>
</application>
 22 мая 2012 г., 15:01
Какую именно проблему это вызвало у вас? Изменение должно быть прозрачным, поскольку оно последовательно делегирует супер.
 Michele Mariotti22 мая 2012 г., 12:30
Однако объявив это вfaces-config.xml переопределяет значение по умолчаниюCompositeELResolver, как заменить стандартBeanELResolver вCompositeELResolver.elResolvers?
 Michele Mariotti22 мая 2012 г., 12:52
упс, я был не прав. он не переопределяет, но вставляется раньше. см обновление вопроса.
 Michele Mariotti22 мая 2012 г., 09:41
это именно то, что я искал, чтобы решить эту и некоторые другие мелочи. спасибо @BalusC, вы экономите мне столько времени, что заслуживаете часть моей зарплаты;)
 Michele Mariotti22 мая 2012 г., 16:15
причиныPropertyNotFoundException пытаюсь прочитать пачки свойств. Однако Док утверждаетBecause this resolver handles base objects of any type, it should be placed near the end of a composite resolver. Otherwise, it will claim to have resolved a property before any resolvers that come after it get a chance to test if they can do so as well. так что я решил эту ловлюPropertyNotFoundException и настройкаcontext.setPropertyResolved(false);

Ваш ответ на вопрос