Skip to content

Commit

Permalink
Migrate page session variable resolver to EL
Browse files Browse the repository at this point in the history
Signed-off-by: avpinchuk <alexander.v.pinchuk@gmail.com>
  • Loading branch information
avpinchuk committed Oct 23, 2022
1 parent 90ef15b commit 7090e45
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,27 @@

package com.sun.jsftemplating.el;

import jakarta.el.ELContext;
import jakarta.el.ELResolver;
import jakarta.el.PropertyNotFoundException;
import jakarta.faces.component.UIViewRoot;
import jakarta.faces.context.FacesContext;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import jakarta.faces.component.UIViewRoot;
import jakarta.faces.context.FacesContext;
import jakarta.faces.el.EvaluationException;
import jakarta.faces.el.VariableResolver;

/**
* <p>
* This <code>VariableResolver</code> exists to resolve "page session" attributes. This concept, borrowed from
* This <code>ELResolver</code> exists to resolve "page session" attributes. This concept, borrowed from
* NetDynamics / JATO, stores data w/ the page so that it is available throughout the life of the page. This is longer
* than request scope, but usually shorter than session. This implementation stores the attributes on the
* <code>UIViewRoot</code>.
* </p>
*
* @author Ken Paulsen (ken.paulsen@sun.com)
*/
public class PageSessionResolver extends VariableResolver {
public class PageSessionResolver extends ELResolver {

/**
* <p>
Expand All @@ -44,13 +45,6 @@ public class PageSessionResolver extends VariableResolver {
*/
public static final String PAGE_SESSION = "pageSession";

/**
* <p>
* The original <code>VariableResolver</code>.
* </p>
*/
private VariableResolver _origVariableResolver = null;

/**
* <p>
* The attribute key in which to store the "page" session Map.
Expand All @@ -60,48 +54,66 @@ public class PageSessionResolver extends VariableResolver {

/**
* <p>
* Constructor.
* </p>
*/
public PageSessionResolver(VariableResolver orig) {
super();
_origVariableResolver = orig;
}

/**
* <p>
* This first delegates to the original <code>VariableResolver</code>, it then checks "page session" to see if the value
* exists.
* Checks "page session" to see if the value exists.
* </p>
*/
@Override
public Object resolveVariable(FacesContext context, String name) throws EvaluationException {
Object result = null;
public Object getValue(ELContext elContext, Object base, Object property) {
if (base != null) {
return null;
}

if (property == null) {
throw new PropertyNotFoundException();
}

FacesContext facesContext = (FacesContext) elContext.getContext(FacesContext.class);
UIViewRoot viewRoot = facesContext.getViewRoot();
Map<String, Serializable> pageSession = getPageSession(facesContext, viewRoot);

Object value = null;
// Check to see if expression explicitly asks for PAGE_SESSION
if (name.equals(PAGE_SESSION)) {
if (property.equals(PAGE_SESSION)) {
// It does, return the Map
UIViewRoot root = context.getViewRoot();
result = getPageSession(context, root);
if (result == null) {
if (pageSession == null) {
// No Map! That's ok, create one...
result = createPageSession(context, root);
pageSession = createPageSession(facesContext, viewRoot);
}
value = pageSession;
} else {
if (_origVariableResolver != null) {
// Not explicit, let original resolver do its thing first...
result = _origVariableResolver.resolveVariable(context, name);
if (pageSession != null) {
// Check page session
value = pageSession.get(property.toString());
}
}

if (result == null) {
// Original resolver couldn't find anything, check page session
Map<String, Serializable> map = getPageSession(context, (UIViewRoot) null);
if (map != null) {
result = map.get(name);
}
}
if (value != null || (pageSession != null && pageSession.containsKey(property.toString()))) {
elContext.setPropertyResolved(true);
}

return result;
return value;
}

@Override
public Class<?> getType(ELContext elContext, Object base, Object property) {
checkPropertyFound(base, property);
return null;
}

@Override
public void setValue(ELContext elContext, Object base, Object property, Object value) {
checkPropertyFound(base, property);
}

@Override
public boolean isReadOnly(ELContext elContext, Object base, Object property) {
checkPropertyFound(base, property);
return false;
}

@Override
public Class<?> getCommonPropertyType(ELContext elContext, Object base) {
return base == null ? String.class : null;
}

/**
Expand All @@ -111,11 +123,12 @@ public Object resolveVariable(FacesContext context, String name) throws Evaluati
* used.
* </p>
*/
public static Map<String, Serializable> getPageSession(FacesContext ctx, UIViewRoot root) {
if (root == null) {
root = ctx.getViewRoot();
@SuppressWarnings("unchecked")
public static Map<String, Serializable> getPageSession(FacesContext facesContext, UIViewRoot viewRoot) {
if (viewRoot == null) {
viewRoot = facesContext.getViewRoot();
}
return (Map<String, Serializable>) root.getAttributes().get(PAGE_SESSION_KEY);
return (Map<String, Serializable>) viewRoot.getAttributes().get(PAGE_SESSION_KEY);
}

/**
Expand All @@ -124,19 +137,24 @@ public static Map<String, Serializable> getPageSession(FacesContext ctx, UIViewR
* <code>Map</code>, so be careful.
* </p>
*/
public static Map<String, Serializable> createPageSession(FacesContext ctx, UIViewRoot root) {
if (root == null) {
root = ctx.getViewRoot();
public static Map<String, Serializable> createPageSession(FacesContext facesContext, UIViewRoot viewRoot) {
if (viewRoot == null) {
viewRoot = facesContext.getViewRoot();
}

// Create it...
Map<String, Serializable> map = new HashMap<>(4);
Map<String, Serializable> pageSession = new HashMap<>(4);

// Store it...
root.getAttributes().put(PAGE_SESSION_KEY, map);
viewRoot.getAttributes().put(PAGE_SESSION_KEY, pageSession);

// Return it...
return map;
return pageSession;
}


private static void checkPropertyFound(Object base, Object property) {
if (base == null && property == null) {
throw new PropertyNotFoundException();
}
}
}
2 changes: 1 addition & 1 deletion jsftemplating/src/main/resources/META-INF/faces-config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<application>
<!-- -->
<view-handler>com.sun.jsftemplating.layout.LayoutViewHandler</view-handler>
<variable-resolver>com.sun.jsftemplating.el.PageSessionResolver</variable-resolver>
<el-resolver>com.sun.jsftemplating.el.PageSessionResolver</el-resolver>
<!-- -->
<locale-config>
<default-locale>en</default-locale>
Expand Down

0 comments on commit 7090e45

Please sign in to comment.