From 62c654992b456f592c93c0029be35eaa990dbba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Pin=C4=8Duk?= Date: Sun, 8 Oct 2023 23:16:58 +0300 Subject: [PATCH 1/4] Revert restore view map MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexander Pinčuk --- .../jsftemplating/layout/LayoutViewHandler.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutViewHandler.java b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutViewHandler.java index 735e7e3a9..1b5f5982b 100644 --- a/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutViewHandler.java +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/layout/LayoutViewHandler.java @@ -247,21 +247,8 @@ public UIViewRoot createView(FacesContext context, String viewId) { } // Restore the current UIViewRoot. - // Because new UIViewRoot was temporary set, this will clear - // view map, which also contains our "page session". - // Thus we need reset a new view root's view map after restore original - // view root. - if (currentViewRoot != null) { - Map pageSession = viewRoot.getViewMap(false); - if (pageSession != null) { - pageSession = new HashMap<>(pageSession); - } - + if (currentViewRoot != null) { context.setViewRoot(currentViewRoot); - - if (pageSession != null) { - viewRoot.getViewMap().putAll(pageSession); - } } // Return the populated UIViewRoot From e5f6d64dcfa83fa52287bccd713f8646cd0bec0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Pin=C4=8Duk?= Date: Mon, 9 Oct 2023 00:08:58 +0300 Subject: [PATCH 2/4] Fallback to the custom scoped page session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexander Pinčuk --- .../jsftemplating/el/PageSessionResolver.java | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java b/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java index 0e45e9bbf..2cb87fa0a 100644 --- a/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Contributors to the Eclipse Foundation. All rights reserved. + * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation. All rights reserved. * Copyright (c) 2006, 2022 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -31,9 +31,11 @@ *

* This ELResolver 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 - * {@link UIViewRoot#getViewMap()}. Therefore it resolves exactly the same values as the `faces.ScopedAttributeELResolver`, which is - * specified in the Jakarta Faces specification, if there's nothing stored in lower scopes (request scope) and there are no other resolvers. + * than request scope, but usually shorter than session. + *

+ * + *

+ * This implementation stores the attributes on the {@link UIViewRoot}. *

* * @author Ken Paulsen (ken.paulsen@sun.com) @@ -47,6 +49,13 @@ public class PageSessionResolver extends ELResolver { */ public static final String PAGE_SESSION = "pageSession"; + /** + *

+ * The attribute key in which to store the "page" session Map. + *

+ */ + private static final String PAGE_SESSION_KEY = "_ps"; + /** *

* Checks "page session" to see if the value exists. @@ -97,20 +106,7 @@ public Class getType(ELContext elContext, Object base, Object property) { @Override public void setValue(ELContext elContext, Object base, Object property, Object value) { - if (base != null) { - return; - } - - if (property == null) { - throw new PropertyNotFoundException(); - } - - FacesContext facesContext = (FacesContext) elContext.getContext(FacesContext.class); - UIViewRoot viewRoot = facesContext.getViewRoot(); - Map pageSession = getPageSession(facesContext, viewRoot); - if (pageSession != null) { - pageSession.put(property.toString(), value); - } + checkPropertyFound(base, property); } @Override @@ -127,8 +123,8 @@ public Class getCommonPropertyType(ELContext elContext, Object base) { /** *

* This method provides access to the "page session" Map. If it doesn't exist, it returns - * null. If the given UIViewRoot is null, then the current UIViewRoot will be - * used. + * null. If the given UIViewRoot is null, then the current UIViewRoot + * will be used. *

*/ @SuppressWarnings("unchecked") @@ -136,20 +132,28 @@ public static Map getPageSession(FacesContext facesContext if (viewRoot == null) { viewRoot = facesContext.getViewRoot(); } - return (Map)viewRoot.getViewMap(false); + return (Map) viewRoot.getAttributes().get(PAGE_SESSION_KEY); } /** *

- * This method will create a new "page session" Map if it doesn't exist yet. If it exists, - * it will return it as if {@link #getPageSession(jakarta.faces.context.FacesContext, jakarta.faces.component.UIViewRoot)} was called. + * This method will create a new "page session" Map if it doesn't exist yet. + * It will overwrite any existing "page session" Map, so be careful. *

*/ public static Map createPageSession(FacesContext facesContext, UIViewRoot viewRoot) { if (viewRoot == null) { viewRoot = facesContext.getViewRoot(); } - return Map.class.cast(viewRoot.getViewMap()); + + // Create it... + Map pageSession = new HashMap<>(4); + + // Store it... + viewRoot.getAttributes().put(PAGE_SESSION_KEY, pageSession); + + // Return it... + return pageSession; } private static void checkPropertyFound(Object base, Object property) { From b623d740bd2b9094e0321326420861d8bfc02db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Pin=C4=8Duk?= Date: Mon, 9 Oct 2023 23:40:53 +0300 Subject: [PATCH 3/4] Improve page session attributes resolution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexander Pinčuk --- .../jsftemplating/el/PageSessionResolver.java | 52 +++++++++++++++---- .../main/resources/META-INF/faces-config.xml | 2 +- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java b/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java index 2cb87fa0a..c8f8a6814 100644 --- a/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java +++ b/jsftemplating/src/main/java/com/sun/jsftemplating/el/PageSessionResolver.java @@ -21,6 +21,7 @@ import jakarta.el.ELResolver; import jakarta.el.PropertyNotFoundException; import jakarta.faces.component.UIViewRoot; +import jakarta.faces.context.ExternalContext; import jakarta.faces.context.FacesContext; import java.io.Serializable; @@ -44,7 +45,7 @@ public class PageSessionResolver extends ELResolver { /** *

- * The name an expression must use when it explicitly specifies page session. ("pageSession") + * The name an expression must use when it explicitly specifies page session ("pageSession"). *

*/ public static final String PAGE_SESSION = "pageSession"; @@ -58,7 +59,7 @@ public class PageSessionResolver extends ELResolver { /** *

- * Checks "page session" to see if the value exists. + * Checks standard scopes and "page session" to see if the value exists. *

*/ @Override @@ -71,11 +72,14 @@ public Object getValue(ELContext elContext, Object base, Object property) { throw new PropertyNotFoundException(); } + elContext.setPropertyResolved(true); + FacesContext facesContext = (FacesContext) elContext.getContext(FacesContext.class); + ExternalContext externalContext = facesContext.getExternalContext(); UIViewRoot viewRoot = facesContext.getViewRoot(); Map pageSession = getPageSession(facesContext, viewRoot); + String attribute = (String) property; - Object value = null; // Check to see if expression explicitly asks for PAGE_SESSION if (property.equals(PAGE_SESSION)) { // It does, return the Map @@ -83,19 +87,45 @@ public Object getValue(ELContext elContext, Object base, Object property) { // No Map! That's ok, create one... pageSession = createPageSession(facesContext, viewRoot); } - value = pageSession; - } else { - if (pageSession != null) { - // Check page session - value = pageSession.get(property.toString()); + return pageSession; + } + + // Check page session exists and contains a property + if (pageSession == null || !pageSession.containsKey(attribute)) { + elContext.setPropertyResolved(false); + return null; + } + + // Check request map + Object value = externalContext.getRequestMap().get(attribute); + if (value != null) { + return value; + } + + // Check view map + Map viewMap = viewRoot.getViewMap(false); + if (viewMap != null) { + value = viewMap.get(attribute); + if (value != null) { + return value; } } - if (value != null || (pageSession != null && pageSession.containsKey(property.toString()))) { - elContext.setPropertyResolved(true); + // Check session map + value = externalContext.getSessionMap().get(attribute); + if (value != null) { + return value; + } + + // Check application map + value = externalContext.getApplicationMap().get(attribute); + if (value != null) { + return value; } - return value; + // Not found updated property in the standard scopes. + // Return value from page session. + return pageSession.get(attribute); } @Override diff --git a/jsftemplating/src/main/resources/META-INF/faces-config.xml b/jsftemplating/src/main/resources/META-INF/faces-config.xml index b56bb74f0..16c837930 100644 --- a/jsftemplating/src/main/resources/META-INF/faces-config.xml +++ b/jsftemplating/src/main/resources/META-INF/faces-config.xml @@ -1,7 +1,7 @@ - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_4_0.xsd" + version="4.0"> - - com.sun.jsftemplating.layout.LayoutViewHandler - com.sun.jsftemplating.layout.LayoutStateManager - com.sun.jsftemplating.el.PageSessionResolver - + com.sun.jsftemplating.layout.LayoutViewHandler + com.sun.jsftemplating.layout.LayoutStateManager + com.sun.jsftemplating.el.PageSessionResolver - en + en - com.sun.jsftemplating.EventComponent - com.sun.jsftemplating.component.EventComponent + com.sun.jsftemplating.EventComponent + com.sun.jsftemplating.component.EventComponent - com.sun.jsftemplating.If - com.sun.jsftemplating.component.If + com.sun.jsftemplating.If + com.sun.jsftemplating.component.If - com.sun.jsftemplating.While - com.sun.jsftemplating.component.While + com.sun.jsftemplating.While + com.sun.jsftemplating.component.While - com.sun.jsftemplating.ForEach - com.sun.jsftemplating.component.ForEach + com.sun.jsftemplating.ForEach + com.sun.jsftemplating.component.ForEach - com.sun.jsftemplating.AjaxRequest - com.sun.jsftemplating.component.AjaxRequest + com.sun.jsftemplating.AjaxRequest + com.sun.jsftemplating.component.AjaxRequest - com.sun.jsftemplating.StaticText - com.sun.jsftemplating.component.StaticText + com.sun.jsftemplating.StaticText + com.sun.jsftemplating.component.StaticText - - com.sun.jsftemplating.EventComponent - com.sun.jsftemplating.EventComponent - com.sun.jsftemplating.renderer.TemplateRenderer - - - com.sun.jsftemplating.If - com.sun.jsftemplating.If - com.sun.jsftemplating.renderer.TemplateRenderer - - - com.sun.jsftemplating.While - com.sun.jsftemplating.While - com.sun.jsftemplating.renderer.TemplateRenderer - - - com.sun.jsftemplating.ForEach - com.sun.jsftemplating.ForEach - com.sun.jsftemplating.renderer.TemplateRenderer - - - com.sun.jsftemplating.AjaxRequest - com.sun.jsftemplating.AjaxRequest - com.sun.jsftemplating.renderer.TemplateRenderer - - - com.sun.jsftemplating.StaticText - com.sun.jsftemplating.StaticText - com.sun.jsftemplating.renderer.TemplateRenderer - + + com.sun.jsftemplating.EventComponent + com.sun.jsftemplating.EventComponent + com.sun.jsftemplating.renderer.TemplateRenderer + + + com.sun.jsftemplating.If + com.sun.jsftemplating.If + com.sun.jsftemplating.renderer.TemplateRenderer + + + com.sun.jsftemplating.While + com.sun.jsftemplating.While + com.sun.jsftemplating.renderer.TemplateRenderer + + + com.sun.jsftemplating.ForEach + com.sun.jsftemplating.ForEach + com.sun.jsftemplating.renderer.TemplateRenderer + + + com.sun.jsftemplating.AjaxRequest + com.sun.jsftemplating.AjaxRequest + com.sun.jsftemplating.renderer.TemplateRenderer + + + com.sun.jsftemplating.StaticText + com.sun.jsftemplating.StaticText + com.sun.jsftemplating.renderer.TemplateRenderer + - + \ No newline at end of file