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
/*
* 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 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.logging.Level;
import java.util.logging.Logger;
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.context.FacesContext;
import jakarta.faces.convert.Converter;
import jakarta.faces.model.DataModel;
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, new FacesConverterAnnotationLiteral(value, Object.class));
if (managedConverter != null) {
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, new FacesConverterAnnotationLiteral("", forClassOrSuperclass));
}
if (managedConverter != null) {
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, new FacesBehaviorAnnotationLiteral(value));
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 = new FacesValidatorAnnotationLiteral(value);
// 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) {
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 beanManager the bean manager
* @param type the required bean type the reference must have
* @param qualifier 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 type.cast(getBeanReferenceByType(beanManager, type, qualifiers));
}
public static Object getBeanReferenceByType(BeanManager beanManager, Type type, Annotation... qualifiers) {
Object beanReference = null;
Bean bean = beanManager.resolve(beanManager.getBeans(type, qualifiers));
if (bean != null) {
beanReference = beanManager.getReference(bean, type, beanManager.createCreationalContext(bean));
}
return beanReference;
}
/**
* Returns concrete (non-proxied) bean instance of given class in current context.
*
* @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 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