All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.seam.faces.component.ValueExpressionAnalyzer Maven / Gradle / Ivy

The newest version!
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2010, Red Hat, Inc., and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.seam.faces.component;

import java.beans.FeatureDescriptor;
import java.util.Iterator;
import java.util.Locale;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ELResolver;
import javax.el.FunctionMapper;
import javax.el.ValueExpression;
import javax.el.ValueReference;
import javax.el.VariableMapper;
import javax.faces.el.CompositeComponentExpressionHolder;

/**
 * 

Analyzes a {@link ValueExpression} and provides access to the base object and property name * referenced by the expression.

* *

The getValueReference(ELContext) method returns a {@link ValueReference} object, which * encapsulates the base object and property name to which the expression maps. This process * works by resolving the expression up until the last segment.

* *

Although access to the ValueReference was added in EL 2.2, the feature * does not work correctly, which is why this custom class is required.

* * @author Dan Allen */ class ValueExpressionAnalyzer { private ValueExpression expression; public ValueExpressionAnalyzer(ValueExpression expression) { this.expression = expression; } public ValueReference getValueReference(ELContext elContext) { InterceptingResolver resolver = new InterceptingResolver(elContext.getELResolver()); try { expression.setValue(decorateELContext(elContext, resolver), null); } catch (ELException ele) { return null; } ValueReference reference = resolver.getValueReference(); if (reference != null) { Object base = reference.getBase(); if (base instanceof CompositeComponentExpressionHolder) { ValueExpression ve = ((CompositeComponentExpressionHolder) base).getExpression((String) reference.getProperty()); if (ve != null) { this.expression = ve; reference = getValueReference(elContext); } } } return reference; } private ELContext decorateELContext(final ELContext context, final ELResolver resolver) { return new ELContext() { // punch in our new ELResolver @Override public ELResolver getELResolver() { return resolver; } // The rest of the methods simply delegate to the existing context @Override public Object getContext(Class key) { return context.getContext(key); } @Override public Locale getLocale() { return context.getLocale(); } @Override public boolean isPropertyResolved() { return context.isPropertyResolved(); } @Override public void putContext(Class key, Object contextObject) { context.putContext(key, contextObject); } @Override public void setLocale(Locale locale) { context.setLocale(locale); } @Override public void setPropertyResolved(boolean resolved) { context.setPropertyResolved(resolved); } @Override public FunctionMapper getFunctionMapper() { return context.getFunctionMapper(); } @Override public VariableMapper getVariableMapper() { return context.getVariableMapper(); } }; } private static class InterceptingResolver extends ELResolver { private ELResolver delegate; private ValueReference valueReference; public InterceptingResolver(ELResolver delegate) { this.delegate = delegate; } public ValueReference getValueReference() { return valueReference; } // Capture the base and property rather than write the value @Override public void setValue(ELContext context, Object base, Object property, Object value) { if (base != null && property != null) { context.setPropertyResolved(true); valueReference = new ValueReference(base, property.toString()); } } // The rest of the methods simply delegate to the existing context @Override public Object getValue(ELContext context, Object base, Object property) { return delegate.getValue(context, base, property); } @Override public Class getType(ELContext context, Object base, Object property) { return delegate.getType(context, base, property); } @Override public boolean isReadOnly(ELContext context, Object base, Object property) { return delegate.isReadOnly(context, base, property); } @Override public Iterator getFeatureDescriptors(ELContext context, Object base) { return delegate.getFeatureDescriptors(context, base); } @Override public Class getCommonPropertyType(ELContext context, Object base) { return delegate.getCommonPropertyType(context, base); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy