blob: 2f09a8897ef631fd0945f36e87159302827e0efb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.myfaces.el.resolver;
import javax.el.ELContext;
import javax.faces.context.FacesContext;
import java.beans.FeatureDescriptor;
import java.util.Iterator;
import java.util.Map;
import java.util.Arrays;
/**
* <p>
* This composite el resolver will be used at the top level resolver for faces
* ({@link javax.faces.application.Application#getELResolver()})
* and jsp (the one we add with {@link javax.servlet.jsp.JspApplicationContext#addELResolver(javax.el.ELResolver)}.
* </p>
* <p>
* This implementation does nothing if there is no actual faces context. This is necessarry since we registered our
* resolvers into the jsp engine. Therefore we have to make sure that jsp only pages where no faces context is available
* are still working
* </p>
*
* @author Mathias Broekelmann (latest modification by $Author$)
* @version $Revision$ $Date$
*/
public final class FacesCompositeELResolver extends org.apache.myfaces.el.resolver.CompositeELResolver
{
public static final String SCOPE = FacesCompositeELResolver.class.getName() + ".Scope";
private final Scope _scope;
public enum Scope
{
Faces, JSP, NONE
}
public FacesCompositeELResolver(final Scope scope)
{
if (scope == null)
{
throw new IllegalArgumentException("scope must not be one of " + Arrays.toString(Scope.values()));
}
_scope = scope;
}
private static FacesContext facesContext(final ELContext context)
{
FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
if (facesContext == null)
{
facesContext = FacesContext.getCurrentInstance();
}
return facesContext;
}
@Override
public Class<?> getCommonPropertyType(final ELContext context, final Object base)
{
final FacesContext facesContext = facesContext(context);
if (facesContext == null)
{
return null;
}
final Map<Object, Object> requestMap = facesContext.getAttributes();
Scope prevScope = null;
try
{
prevScope = getScope(requestMap);
setScope(requestMap);
return super.getCommonPropertyType(context, base);
}
finally
{
if (prevScope != null)
{
setScope(requestMap, prevScope);
}
else
{
unsetScope(requestMap);
}
}
}
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(final ELContext context, final Object base)
{
final FacesContext facesContext = facesContext(context);
if (facesContext == null)
{
return null;
}
final Map<Object, Object> requestMap = facesContext.getAttributes();
Scope prevScope = null;
try
{
prevScope = getScope(requestMap);
setScope(requestMap);
return super.getFeatureDescriptors(context, base);
}
finally
{
if (prevScope != null)
{
setScope(requestMap, prevScope);
}
else
{
unsetScope(requestMap);
}
}
}
@Override
public Class<?> getType(final ELContext context, final Object base, final Object property)
{
final FacesContext facesContext = facesContext(context);
if (facesContext == null)
{
return null;
}
final Map<Object, Object> requestMap = facesContext.getAttributes();
Scope prevScope = null;
try
{
prevScope = getScope(requestMap);
setScope(requestMap);
return super.getType(context, base, property);
}
finally
{
if (prevScope != null)
{
setScope(requestMap, prevScope);
}
else
{
unsetScope(requestMap);
}
}
}
@Override
public Object getValue(final ELContext context, final Object base, final Object property)
{
final FacesContext facesContext = facesContext(context);
if (facesContext == null)
{
return null;
}
final Map<Object, Object> requestMap = facesContext.getAttributes();
Scope prevScope = null;
try
{
prevScope = getScope(requestMap);
setScope(requestMap);
return super.getValue(context, base, property);
}
finally
{
if (prevScope != null)
{
setScope(requestMap, prevScope);
}
else
{
unsetScope(requestMap);
}
}
}
@Override
public boolean isReadOnly(final ELContext context, final Object base, final Object property)
{
final FacesContext facesContext = facesContext(context);
if (facesContext == null)
{
return false;
}
final Map<Object, Object> requestMap = facesContext.getAttributes();
Scope prevScope = null;
try
{
prevScope = getScope(requestMap);
setScope(requestMap);
return super.isReadOnly(context, base, property);
}
finally
{
if (prevScope != null)
{
setScope(requestMap, prevScope);
}
else
{
unsetScope(requestMap);
}
}
}
@Override
public void setValue(final ELContext context, final Object base, final Object property, final Object val)
{
final FacesContext facesContext = facesContext(context);
if (facesContext == null)
{
return;
}
final Map<Object, Object> requestMap = facesContext.getAttributes();
Scope prevScope = null;
try
{
prevScope = getScope(requestMap);
setScope(requestMap);
super.setValue(context, base, property, val);
}
finally
{
if (prevScope != null)
{
setScope(requestMap, prevScope);
}
else
{
unsetScope(requestMap);
}
}
}
private void setScope(final Map<Object, Object> attributes)
{
attributes.put(SCOPE, _scope);
}
private Scope getScope(final Map<Object, Object> attributes)
{
return (Scope) attributes.get(SCOPE);
}
private void setScope(final Map<Object, Object> attributes, Scope prevScope)
{
attributes.put(SCOPE, prevScope);
}
private static void unsetScope(final Map<Object, Object> attributes)
{
//attributes.remove(SCOPE);
attributes.put(SCOPE, Scope.NONE);
}
}