001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.cdi;
018
019import jakarta.enterprise.inject.spi.BeanManager;
020import jakarta.enterprise.inject.spi.CDI;
021import javax.naming.InitialContext;
022import javax.naming.NamingException;
023
024import org.apache.wicket.Application;
025import org.slf4j.Logger;
026import org.slf4j.LoggerFactory;
027
028/**
029 * Defines several strategies for looking up a CDI BeanManager in a portable
030 * way. The following strategies are tried (in order):
031 * <ul>
032 * <li>JNDI under java:comp/BeanManager (default location)</li>
033 * <li>JNDI under java:comp/env/BeanManager (for servlet containers like Tomcat
034 * and Jetty)</li>
035 * <li>CDI.current().getBeanManager() (portable lookup)</li>
036 * <li>{@linkplain CdiConfiguration#getFallbackBeanManager() Fallback}</li>
037 * </ul>
038 * 
039 * The last successful lookup strategy is saved and tried first next time.
040 * 
041 * @author papegaaij
042 */
043public final class BeanManagerLookup
044{
045        private static final Logger log = LoggerFactory.getLogger(BeanManagerLookup.class);
046
047        private enum BeanManagerLookupStrategy {
048                JNDI {
049                        @Override
050                        public BeanManager lookup()
051                        {
052                                try
053                                {
054                                        return InitialContext.doLookup("java:comp/BeanManager");
055                                }
056                                catch (NamingException e)
057                                {
058                                        return null;
059                                }
060                        }
061                },
062                JNDI_ENV {
063                        @Override
064                        public BeanManager lookup()
065                        {
066                                try
067                                {
068                                        return InitialContext.doLookup("java:comp/env/BeanManager");
069                                }
070                                catch (NamingException e)
071                                {
072                                        return null;
073                                }
074                        }
075                },
076                CDI_PROVIDER {
077                        @Override
078                        public BeanManager lookup()
079                        {
080                                try
081                                {
082                                        return CDI.current().getBeanManager();
083                                }
084                                catch (Exception e)
085                                {
086                                        log.debug(e.getMessage(), e);
087                                        return null;
088                                }
089                        }
090                },
091                FALLBACK {
092                        @Override
093                        public BeanManager lookup()
094                        {
095                                return CdiConfiguration.get(Application.get()).getFallbackBeanManager();
096                        }
097                };
098
099                public abstract BeanManager lookup();
100        }
101
102        private static BeanManagerLookupStrategy lastSuccessful = BeanManagerLookupStrategy.JNDI;
103
104        private BeanManagerLookup()
105        {
106        }
107
108        public static BeanManager lookup()
109        {
110                BeanManager ret = lastSuccessful.lookup();
111                if (ret != null)
112                        return ret;
113
114                for (BeanManagerLookupStrategy curStrategy : BeanManagerLookupStrategy.values())
115                {
116                        ret = curStrategy.lookup();
117                        if (ret != null)
118                        {
119                                lastSuccessful = curStrategy;
120                                return ret;
121                        }
122                }
123
124                throw new IllegalStateException(
125                                "No BeanManager found via the CDI provider and no fallback specified. Check your "
126                                                + "CDI setup or specify a fallback BeanManager in the CdiConfiguration.");
127        }
128}