Skip to content

Commit

Permalink
Merge #5431, #5434 and #5444 from 4.1 into 5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
BalusC committed May 26, 2024
2 parents b8a0530 + 16fdf9c commit 410b7ea
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 64 deletions.
55 changes: 24 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,28 @@
[//]: # " SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 "
-->

# Eclipse Mojarra
# Mojarra 5.0

Eclipse's implementation of the Jakarta Faces specification
Eclipse's implementation of the Jakarta Faces 5.0 specification

* Mojarra 5.0 - under development
* Mojarra 5.0 - this branch, under development
* [Mojarra 4.1](https://github.com/eclipse-ee4j/mojarra/blob/4.1/README.md) - stable release
* [Mojarra 4.0](https://github.com/eclipse-ee4j/mojarra/blob/4.0/README.md) - stable release
* [Mojarra 3.0](https://github.com/eclipse-ee4j/mojarra/blob/3.0/README.md) - legacy release
* [Mojarra 2.3](https://github.com/eclipse-ee4j/mojarra/blob/2.3/README.md) - legacy release

For Mojarra 2.3 and earlier please contact your vendor for support (RedHat, IBM,
For support on Mojarra 2.3 and earlier please contact your vendor for support (RedHat, IBM,
Oracle, Omnifish, Payara, etceteras)

## Minimum Requirements

- Java 11
- Jakarta Servlet 6.0
- Jakarta Expression Language 5.0
- CDI 4.0
- Jakarta Standard Tag Library 2.0
- Jakarta Web Socket 2.0 (optional, only when `<f:websocket>` is used)
- Jakarta JSON Processing 2.0 (optional, only when `<f:websocket>` is used)
- Jakarta Validation 3.0 (optional, only when `<f:validateBean>` or `<f:validateWholeBean>` is used)

CDI is explicitly required because since Jakarta Faces 2.3 the `javax.faces.bean.*` annotations such as `@ManagedBean` are deprecated, and in 4.0 these have been removed. Several implicit Jakarta Expression Language objects are produced via CDI producers, and `<f:websocket>` manages the Jakarta WebSocket sessions and events via CDI.
- Java 17
- Jakarta Servlet 6.1
- Jakarta Expression Language 6.0
- Jakarta CDI 4.1
- Jakarta Web Socket 2.2 (optional, only when `<f:websocket>` is used)
- Jakarta JSON Processing 2.1 (optional, only when `<f:websocket>` is used)
- Jakarta Validation 3.1 (optional, only when `<f:validateBean>` or `<f:validateWholeBean>` is used)


## Installation
Expand All @@ -56,12 +55,11 @@ In case you're manually carrying around JARs:

Add below JARs to `/WEB-INF/lib`:

- [`jakarta.faces.4.0.x.jar`][9]
- [`weld-servlet-shaded-4.0.0.Final.jar`][10]
- [`jstl-2.0.jar`][11]
- [`jakarta.json-api-2.0.jar`][12] (optional, only when `<f:websocket>` is used)
- [`jakarta.json-2.0.jar`][12a] (optional, only when `<f:websocket>` is used)
- [`validation-api-3.0.0.Final.jar`][13] (optional, only when `<f:validateBean|validateWholeBean>` is used)
- [`jakarta.faces.4.1.x.jar`][9]
- [`weld-servlet-shaded-4.1.0.Final.jar`][10]
- [`jakarta.json-api-2.1.0.jar`][12] (optional, only when `<f:websocket>` is used)
- [`jakarta.json-2.1.0.jar`][12a] (optional, only when `<f:websocket>` is used)
- [`jakarta.validation-api-3.1.0.jar`][13] (optional, only when `<f:validateBean|validateWholeBean>` is used)
- [`hibernate-validator-8.0.x.Final.jar`][14] (optional, only when `<f:validateBean|validateWholeBean>` is used)

Substitute `x` with latest version number available.
Expand All @@ -76,7 +74,7 @@ In case you're using Maven, you can find below the necessary coordinates:
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>10.0.0</version>
<version>11.0.0</version>
<scope>provided</scope>
</dependency>
```
Expand All @@ -94,17 +92,12 @@ In case of WildFly/JBoss EAP, [you need to manually package `jsf-api.jar` and `j
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet-shaded</artifactId>
<version>4.0.0.Final</version>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>2.0.0</version>
<version>4.1.0.Final</version>
</dependency>
<dependency> <!-- Optional, only when <f:websocket> is used. -->
<groupId>org.glassfish</groupId>
<artifactId>jakarta.json</artifactId>
<version>2.0.0</version>
<version>2.1.0</version>
</dependency>
<dependency> <!-- Optional, only when <f:validateBean> or <f:validateWholeBean> is used. -->
<groupId>org.hibernate.validator</groupId>
Expand Down Expand Up @@ -232,9 +225,9 @@ Finally create a [Facelets][20] file `/hello.xhtml` as below:

Start the server and open it by `http://localhost:8080/contextname/hello.xhtml`.

## Activating CDI in Jakarta Faces 4.0
## Activating CDI in Jakarta Faces 4.1

CDI is activated by default in Jakarta Faces 4.0 and can´t be deactivated.
CDI is activated by default in Jakarta Faces 4.1 and can´t be deactivated.
It´s not required anymore to add `@FacesConfig` to a CDI managed bean to accomplish this.
As of Jakarta Faces 4.0 `@FacesConfig` still removes the need to explicitly add a `FacesServlet` entry to `web.xml`.

Expand All @@ -244,7 +237,7 @@ In case you want to checkout this repository and manually build from source your

### Jakarta Faces.Next

1. Make sure that you have JDK 11, Ant and Maven installed.
1. Make sure that you have JDK 17, Ant and Maven installed.
2. Checkout branch [`master`][28].
3. Run the following commands from the root directory of the project:

Expand Down
12 changes: 6 additions & 6 deletions impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,20 @@
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.1.0-M2</version>
<version>6.1.0</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.2.0-M1</version>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-client-api</artifactId>
<version>2.2.0-M1</version>
<version>2.2.0</version>
<scope>provided</scope>
</dependency>

Expand Down Expand Up @@ -96,7 +96,7 @@
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.1.0-M1</version>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>

Expand Down Expand Up @@ -130,7 +130,7 @@
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.2.0-M2</version>
<version>3.2.0</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
Expand Down Expand Up @@ -226,7 +226,7 @@
<plugin>
<groupId>com.github.blutorange</groupId>
<artifactId>closure-compiler-maven-plugin</artifactId>
<version>2.28.0</version>
<version>2.30.0</version>
<executions>
<!-- Process all files in the "includes" directory individually-->
<execution>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1674,11 +1674,21 @@ public void flush() {
* @param context the Faces context.
* @param clientId the client id of the component to find.
*/
private UIComponent locateComponentByClientId(final FacesContext context, final UIComponent parent, final String clientId) {
private UIComponent locateComponentByClientId(final FacesContext context, final UIComponent parent, final String clientId, final boolean dynamic) {
final List<UIComponent> found = new ArrayList<>(1);
UIComponent result = null;

parent.invokeOnComponent(context, clientId, (context1, target) -> found.add(target));
try {
parent.invokeOnComponent(context, clientId, (context1, target) -> found.add(target));
} catch (FacesException e) {
if (dynamic) {
LOGGER.log(FINE, e, () -> "Cannot find dynamic component " + clientId + " in " + parent.getClientId(context)
+ "; assuming it just doesn't exist anymore"
+ "; it will most likely emit a 'WARNING: Unable to save dynamic action' log later on anyway");
} else {
throw e;
}
}

/*
* Since we did not find it the cheaper way we need to assume there is a UINamingContainer that does not prepend its ID.
Expand Down Expand Up @@ -1733,11 +1743,11 @@ private void reapplyDynamicActions(FacesContext context) {
* @param struct the component struct.
*/
private void reapplyDynamicAdd(FacesContext context, ComponentStruct struct) {
UIComponent parent = locateComponentByClientId(context, context.getViewRoot(), struct.getParentClientId());
UIComponent parent = locateComponentByClientId(context, context.getViewRoot(), struct.getParentClientId(), false);

if (parent != null) {

UIComponent child = locateComponentByClientId(context, parent, struct.getClientId());
UIComponent child = locateComponentByClientId(context, parent, struct.getClientId(), true);
StateContext stateContext = StateContext.getStateContext(context);

if (child == null) {
Expand Down Expand Up @@ -1775,7 +1785,7 @@ private void reapplyDynamicAdd(FacesContext context, ComponentStruct struct) {
* @param struct the component struct.
*/
private void reapplyDynamicRemove(FacesContext context, ComponentStruct struct) {
UIComponent child = locateComponentByClientId(context, context.getViewRoot(), struct.getClientId());
UIComponent child = locateComponentByClientId(context, context.getViewRoot(), struct.getClientId(), true);
if (child != null) {
StateContext stateContext = StateContext.getStateContext(context);
stateContext.getDynamicComponents().put(struct.getClientId(), child);
Expand Down
20 changes: 10 additions & 10 deletions impl/src/main/java/com/sun/faces/config/WebConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,6 @@
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.sun.faces.application.ApplicationAssociate;
import com.sun.faces.application.view.FaceletViewHandlingStrategy;
import com.sun.faces.facelets.util.Classpath;
import com.sun.faces.lifecycle.HttpMethodRestrictionsPhaseListener;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.Util;

import jakarta.faces.FactoryFinder;
import jakarta.faces.application.ResourceHandler;
import jakarta.faces.application.StateManager;
Expand All @@ -60,6 +53,13 @@
import jakarta.faces.lifecycle.LifecycleFactory;
import jakarta.servlet.ServletContext;

import com.sun.faces.application.ApplicationAssociate;
import com.sun.faces.application.view.FaceletViewHandlingStrategy;
import com.sun.faces.facelets.util.Classpath;
import com.sun.faces.lifecycle.HttpMethodRestrictionsPhaseListener;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.Util;

/**
* Class Documentation
*/
Expand Down Expand Up @@ -102,7 +102,7 @@ public class WebConfiguration {
private FaceletsConfiguration faceletsConfig;

private boolean hasFlows;

private String specificationVersion;

// ------------------------------------------------------------ Constructors
Expand All @@ -118,7 +118,7 @@ private WebConfiguration(ServletContext servletContext) {
if (canProcessJndiEntries()) {
processJndiEntries(contextName);
}

specificationVersion = getClass().getPackage().getSpecificationVersion();
}

Expand Down Expand Up @@ -820,7 +820,7 @@ public enum BooleanWebContextInitParameter {
EnableHttpMethodRestrictionPhaseListener("com.sun.faces.ENABLE_HTTP_METHOD_RESTRICTION_PHASE_LISTENER", false),
PartialStateSaving(StateManager.PARTIAL_STATE_SAVING_PARAM_NAME, true),
GenerateUniqueServerStateIds("com.sun.faces.generateUniqueServerStateIds", true),
AutoCompleteOffOnViewState("com.sun.faces.autoCompleteOffOnViewState", true),
AutoCompleteOffOnViewState("com.sun.faces.autoCompleteOffOnViewState", false),
EnableThreading("com.sun.faces.enableThreading", false),
AllowTextChildren("com.sun.faces.allowTextChildren", false),
CacheResourceModificationTimestamp("com.sun.faces.cacheResourceModificationTimestamp", false),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,11 @@ public Object getState(FacesContext ctx, String viewId) {
}

int sep = compoundId.indexOf(':');
assert sep != -1;
assert sep < compoundId.length();

if (sep == -1) {
LOGGER.log(FINE, "Unable to restore server side state for view ID {0} as no state ID is available", viewId);
return null;
}

String idInLogicalMap = compoundId.substring(0, sep);
String idInActualMap = compoundId.substring(sep + 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,6 @@
import java.util.SortedSet;
import java.util.TreeSet;

import com.sun.faces.RIConstants;
import com.sun.faces.io.FastStringWriter;
import com.sun.faces.renderkit.Attribute;
import com.sun.faces.renderkit.AttributeManager;
import com.sun.faces.renderkit.RenderKitUtils;
import com.sun.faces.renderkit.SelectItemsIterator;
import com.sun.faces.util.RequestStateManager;
import com.sun.faces.util.Util;

import jakarta.el.ELException;
import jakarta.el.ExpressionFactory;
import jakarta.el.ValueExpression;
Expand All @@ -74,13 +65,24 @@
import jakarta.faces.component.UISelectMany;
import jakarta.faces.component.UISelectOne;
import jakarta.faces.component.ValueHolder;
import jakarta.faces.component.html.HtmlSelectManyListbox;
import jakarta.faces.component.html.HtmlSelectOneListbox;
import jakarta.faces.context.FacesContext;
import jakarta.faces.context.ResponseWriter;
import jakarta.faces.convert.Converter;
import jakarta.faces.convert.ConverterException;
import jakarta.faces.model.SelectItem;
import jakarta.faces.model.SelectItemGroup;

import com.sun.faces.RIConstants;
import com.sun.faces.io.FastStringWriter;
import com.sun.faces.renderkit.Attribute;
import com.sun.faces.renderkit.AttributeManager;
import com.sun.faces.renderkit.RenderKitUtils;
import com.sun.faces.renderkit.SelectItemsIterator;
import com.sun.faces.util.RequestStateManager;
import com.sun.faces.util.Util;

/**
* <B>MenuRenderer</B> is a class that renders the current value of <code>UISelectOne</code> or <code>UISelectMany</code>
* component as a list of menu options.
Expand Down Expand Up @@ -652,7 +654,7 @@ protected void renderSelect(FacesContext context, UIComponent component) throws
context.setResponseWriter(writer);

// If "size" is *not* set explicitly, we have to default it correctly
Integer size = (Integer) component.getAttributes().get("size");
Integer size = getSizeAttribute(component);
if (size == null || size == MIN_VALUE) {
size = count;
}
Expand All @@ -670,6 +672,18 @@ protected void renderSelect(FacesContext context, UIComponent component) throws
writer.endElement("select");
}

protected Integer getSizeAttribute(UIComponent component) {
if (component instanceof HtmlSelectOneListbox) {
return ((HtmlSelectOneListbox) component).getSize();
}
else if (component instanceof HtmlSelectManyListbox) {
return ((HtmlSelectManyListbox) component).getSize();
}
else {
return null;
}
}

protected Object coerceToModelType(FacesContext ctx, Object value, Class<?> itemValueType) {

Object newValue;
Expand Down
Loading

0 comments on commit 410b7ea

Please sign in to comment.