| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.myfaces.extensions.cdi.core.impl.activation; |
| |
| import java.util.logging.Logger; |
| |
| import org.apache.myfaces.extensions.cdi.core.api.activation.Deactivatable; |
| import org.apache.myfaces.extensions.cdi.core.api.activation.ProjectStageActivated; |
| import org.apache.myfaces.extensions.cdi.core.api.projectstage.ProjectStage; |
| import org.apache.myfaces.extensions.cdi.core.api.startup.CodiStartupBroadcaster; |
| import org.apache.myfaces.extensions.cdi.core.impl.projectstage.ProjectStageProducer; |
| import org.apache.myfaces.extensions.cdi.core.impl.util.ActivationUtils; |
| import org.apache.myfaces.extensions.cdi.core.impl.util.ClassDeactivation; |
| |
| import javax.enterprise.event.Observes; |
| import javax.enterprise.inject.spi.AfterDeploymentValidation; |
| import javax.enterprise.inject.spi.Extension; |
| import javax.enterprise.inject.spi.ProcessAnnotatedType; |
| |
| |
| /** |
| * <p>This class implements the logic for handling |
| * {@link ProjectStageActivated} annotations.</p> |
| * <p>We simply listen for all annotated types to get scanned, and |
| * if it has a {@link org.apache.myfaces.extensions.cdi.core.api.activation.ProjectStageActivated} annotation but the |
| * the current {@link ProjectStage} is not in the list, we simply |
| * veto that bean.</p> |
| * |
| */ |
| public class ActivationExtension implements Extension, Deactivatable |
| { |
| private static final Logger LOG = Logger.getLogger(ActivationExtension.class.getName()); |
| |
| |
| protected void initProjectStage(@Observes AfterDeploymentValidation afterDeploymentValidation) |
| { |
| //trigger initialization |
| ProjectStageProducer.getInstance(); |
| } |
| |
| /** |
| * Check if the {@link javax.enterprise.inject.spi.AnnotatedType} is an @Alternative and |
| * is not disabled for the current {@link ProjectStage}. |
| */ |
| protected void vetoAlternativeTypes(@Observes ProcessAnnotatedType<Object> processAnnotatedType) |
| { |
| if(!isActivated()) |
| { |
| return; |
| } |
| |
| CodiStartupBroadcaster.broadcastStartup(); |
| |
| try |
| { |
| //also forces deterministic project-stage initialization |
| ProjectStage projectStage = ProjectStageProducer.getInstance().getProjectStage(); |
| |
| checkProjectStageActivated(processAnnotatedType, projectStage); |
| |
| checkExpressionActivated(processAnnotatedType); |
| } |
| catch (RuntimeException e) |
| { |
| throw new IllegalStateException("Invalid bean detected: " + |
| processAnnotatedType.getAnnotatedType().getJavaClass().getName(), e); |
| } |
| |
| //placed here to ensue that no validation of a deactivated class will be performance |
| //TODO validateCodiImplementationRules(processAnnotatedType); |
| } |
| |
| private void checkProjectStageActivated(ProcessAnnotatedType<Object> processAnnotatedType, |
| ProjectStage currentlyConfiguredProjectStage) |
| { |
| if (processAnnotatedType.getAnnotatedType().getJavaClass().isAnnotationPresent(ProjectStageActivated.class)) |
| { |
| Class<? extends ProjectStage>[] activatedIn = processAnnotatedType.getAnnotatedType().getJavaClass() |
| .getAnnotation(ProjectStageActivated.class).value(); |
| |
| if (!isInProjectStage(activatedIn, currentlyConfiguredProjectStage)) |
| { |
| // this alternative shall not get used |
| processAnnotatedType.veto(); |
| |
| LOG.finer("ProjectState Veto for bean with type: " |
| + processAnnotatedType.getAnnotatedType().getJavaClass() ); |
| } |
| } |
| } |
| |
| private void checkExpressionActivated(ProcessAnnotatedType<Object> processAnnotatedType) |
| { |
| Class<?> annotatedClass = processAnnotatedType.getAnnotatedType().getJavaClass(); |
| |
| if(!ActivationUtils.isActivated(annotatedClass, PropertyExpressionInterpreter.class)) |
| { |
| processAnnotatedType.veto(); |
| |
| LOG.finer("Expression Veto for bean with type: " |
| + processAnnotatedType.getAnnotatedType().getJavaClass() ); |
| } |
| } |
| |
| private boolean isInProjectStage(Class<? extends ProjectStage>[] activatedIn, |
| ProjectStage currentlyConfiguredProjectStage) |
| { |
| if (activatedIn != null && activatedIn.length > 0) |
| { |
| for (Class<? extends ProjectStage> activated : activatedIn) |
| { |
| if (ProjectStage.class.getName().equals(activated.getName())) |
| { |
| throw new IllegalStateException( |
| "Using " + ProjectStage.class.getName() + " directly isn't allowed."); |
| } |
| |
| if (currentlyConfiguredProjectStage.getClass().equals(activated)) |
| { |
| return true; |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean isActivated() |
| { |
| return ClassDeactivation.isClassActivated(getClass()); |
| } |
| } |