com.sun.faces.cdi.CdiUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jakarta.faces Show documentation
Show all versions of jakarta.faces Show documentation
EE4J Compatible Implementation for Jakarta Faces API
The newest version!
/*
* Copyright (c) 1997, 2019 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.faces.cdi;
import static java.util.Optional.empty;
import static java.util.stream.Collectors.toSet;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sun.faces.application.ApplicationAssociate;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.Util;
import jakarta.enterprise.context.ContextNotActiveException;
import jakarta.enterprise.context.spi.Context;
import jakarta.enterprise.context.spi.CreationalContext;
import jakarta.enterprise.inject.spi.Annotated;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
import jakarta.enterprise.inject.spi.CDI;
import jakarta.enterprise.inject.spi.InjectionPoint;
import jakarta.enterprise.util.TypeLiteral;
import jakarta.faces.component.behavior.Behavior;
import jakarta.faces.component.behavior.FacesBehavior;
import jakarta.faces.context.FacesContext;
import jakarta.faces.convert.Converter;
import jakarta.faces.convert.FacesConverter;
import jakarta.faces.model.DataModel;
import jakarta.faces.model.FacesDataModel;
import jakarta.faces.validator.FacesValidator;
import jakarta.faces.validator.Validator;
/**
* A static utility class for CDI.
*/
public final class CdiUtils {
/**
* Stores the logger.
*/
private static final Logger LOGGER = FacesLogger.APPLICATION_VIEW.getLogger();
private final static Type CONVERTER_TYPE = new TypeLiteral>() {
private static final long serialVersionUID = 1L;
}.getType();
private final static Type VALIDATOR_TYPE = new TypeLiteral>() {
private static final long serialVersionUID = 1L;
}.getType();
/**
* Constructor.
*/
private CdiUtils() {
}
/**
* Create a converter using the FacesConverter value attribute.
*
* @param beanManager the bean manager.
* @param value the value attribute.
* @return the converter, or null if we could not match one.
*/
public static Converter> createConverter(BeanManager beanManager, String value) {
Converter> managedConverter = createConverter(beanManager, FacesConverter.Literal.of(value, Object.class, true));
if (managedConverter != null) {
ApplicationAssociate associate = ApplicationAssociate.getCurrentInstance();
associate.getAnnotationManager().applyConverterAnnotations(FacesContext.getCurrentInstance(), managedConverter); // #4913
return new CdiConverter(value, Object.class, managedConverter);
}
return null;
}
/**
* Create a converter using the FacesConverter forClass attribute.
*
* @param beanManager the bean manager.
* @param forClass the for class.
* @return the converter, or null if we could not match one.
*/
public static Converter> createConverter(BeanManager beanManager, Class> forClass) {
Converter> managedConverter = null;
for (Class> forClassOrSuperclass = forClass; managedConverter == null && forClassOrSuperclass != null
&& forClassOrSuperclass != Object.class; forClassOrSuperclass = forClassOrSuperclass.getSuperclass()) {
managedConverter = createConverter(beanManager, FacesConverter.Literal.of("", forClassOrSuperclass, true));
}
if (managedConverter != null) {
ApplicationAssociate associate = ApplicationAssociate.getCurrentInstance();
associate.getAnnotationManager().applyConverterAnnotations(FacesContext.getCurrentInstance(), managedConverter); // #4913
return new CdiConverter("", forClass, managedConverter);
}
return null;
}
private static Converter> createConverter(BeanManager beanManager, Annotation qualifier) {
// Try to find parameterized converter first
Converter> managedConverter = (Converter>) getBeanReferenceByType(beanManager, CONVERTER_TYPE, qualifier);
if (managedConverter == null) {
// No parameterized converter, try raw converter
managedConverter = getBeanReference(beanManager, Converter.class, qualifier);
}
return managedConverter;
}
/**
* Create a behavior using the FacesBehavior value attribute.
*
* @param beanManager the bean manager.
* @param value the value attribute.
* @return the behavior, or null if we could not match one.
*/
public static Behavior createBehavior(BeanManager beanManager, String value) {
Behavior delegatingBehavior = null;
Behavior managedBehavior = getBeanReference(beanManager, Behavior.class, FacesBehavior.Literal.of(value, true));
if (managedBehavior != null) {
delegatingBehavior = new CdiBehavior(value, managedBehavior);
}
return delegatingBehavior;
}
/**
* Create a validator using the FacesValidator value attribute.
*
* @param beanManager the bean manager.
* @param value the value attribute.
* @return the validator, or null if we could not match one.
*/
public static Validator> createValidator(BeanManager beanManager, String value) {
Annotation qualifier = FacesValidator.Literal.of(value, false, true);
// Try to find parameterized validator first
Validator> managedValidator = (Validator>) getBeanReferenceByType(beanManager, VALIDATOR_TYPE, qualifier);
if (managedValidator == null) {
// No parameterized validator, try raw validator
managedValidator = getBeanReference(beanManager, Validator.class, qualifier);
}
if (managedValidator == null) {
// Still nothing found, try default qualifier and value as bean name.
qualifier = FacesValidator.Literal.of("", false, true);
managedValidator = (Validator>) getBeanReferenceByType(
beanManager,
VALIDATOR_TYPE,
value,
qualifier);
}
if (managedValidator == null) {
// No parameterized validator, try raw validator
managedValidator = getBeanReference(
beanManager,
Validator.class,
value,
qualifier);
}
if (managedValidator != null) {
return new CdiValidator(value, managedValidator);
}
return null;
}
public static void addAnnotatedTypes(BeforeBeanDiscovery beforeBean, BeanManager beanManager, Class>... types) {
for (Class> type : types) {
beforeBean.addAnnotatedType(beanManager.createAnnotatedType(type), "Mojarra " + type.getName());
}
}
public static T getBeanReference(Class type, Annotation... qualifiers) {
return type.cast(getBeanReferenceByType(Util.getCdiBeanManager(FacesContext.getCurrentInstance()), type, qualifiers));
}
public static T getBeanReference(FacesContext facesContext, Class type, Annotation... qualifiers) {
return type.cast(getBeanReferenceByType(Util.getCdiBeanManager(facesContext), type, qualifiers));
}
/**
* @param the generic bean type
* @param beanManager the bean manager
* @param type the required bean type the reference must have
* @param qualifiers the required qualifiers the reference must have
* @return a bean reference adhering to the required type and qualifiers
*/
public static T getBeanReference(BeanManager beanManager, Class type, Annotation... qualifiers) {
return getBeanReference(beanManager, type, null, qualifiers);
}
public static Object getBeanReferenceByType(BeanManager beanManager, Type type, Annotation... qualifiers) {
return getBeanReferenceByType(beanManager, type, null, qualifiers);
}
private static T getBeanReference(BeanManager beanManager, Class type, String beanName, Annotation... qualifiers) {
return type.cast(getBeanReferenceByType(beanManager, type, beanName, qualifiers));
}
private static Object getBeanReferenceByType(BeanManager beanManager, Type type, String beanName, Annotation... qualifiers) {
Object beanReference = null;
Set> beans = beanManager.getBeans(type, qualifiers);
if (beanName != null) {
beans = beans.stream()
.filter(bean -> beanName.equals(getBeanName(bean)))
.collect(toSet());
}
Bean> bean = beanManager.resolve(beans);
if (bean != null) {
beanReference = beanManager.getReference(bean, type, beanManager.createCreationalContext(bean));
}
return beanReference;
}
private static String getBeanName(Bean> bean) {
String name = bean.getName();
if (name != null) {
return name;
}
String className = bean.getBeanClass().getSimpleName();
return Character.toLowerCase(className.charAt(0)) + className.substring(1);
}
/**
* Returns concrete (non-proxied) bean instance of given class in current context.
*
* @param the generic bean type
* @param type the required bean type the instance must have
* @param create whether to auto-create bean if not exist
* @return a bean instance adhering to the required type
*/
public static T getBeanInstance(Class type, boolean create) {
BeanManager beanManager = Util.getCdiBeanManager(FacesContext.getCurrentInstance());
@SuppressWarnings("unchecked")
Bean bean = (Bean) beanManager.resolve(beanManager.getBeans(type));
if (bean != null) {
Context context = beanManager.getContext(bean.getScope());
if (create) {
return context.get(bean, beanManager.createCreationalContext(bean));
} else {
return context.get(bean);
}
} else {
return null;
}
}
/**
* Finds an annotation in an Annotated, taking stereo types into account
*
* @param the generic annotation type
* @param beanManager the current bean manager
* @param annotated the Annotated in which to search
* @param annotationType the type of the annotation to search for
* @return An Optional that contains an instance of annotation type for which was searched if the annotated contained
* this.
*/
public static Optional getAnnotation(BeanManager beanManager, Annotated annotated, Class annotationType) {
annotated.getAnnotation(annotationType);
if (annotated.getAnnotations().isEmpty()) {
return empty();
}
if (annotated.isAnnotationPresent(annotationType)) {
return Optional.of(annotated.getAnnotation(annotationType));
}
Queue annotations = new LinkedList<>(annotated.getAnnotations());
while (!annotations.isEmpty()) {
Annotation annotation = annotations.remove();
if (annotation.annotationType().equals(annotationType)) {
return Optional.of(annotationType.cast(annotation));
}
try {
if (beanManager.isStereotype(annotation.annotationType())) {
annotations.addAll(beanManager.getStereotypeDefinition(annotation.annotationType()));
}
} catch (Exception e) {
// Log and continue, if it's not allowed to test if it's a stereo type
// we're unlikely to be interested in this annotation
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.warning("Exception happened when finding an annotation: " + e);
}
}
}
return empty();
}
public static DataModel> createDataModel(final Class> forClass) {
List> dataModel = new ArrayList<>(1);
CDI