View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.util;
20  
21  import java.util.logging.Level;
22  import java.util.logging.Logger;
23  
24  import javax.faces.context.ExternalContext;
25  import javax.servlet.http.HttpServletRequest;
26  import org.apache.myfaces.shared.util.ClassUtils;
27  import org.apache.myfaces.webapp.AbstractFacesInitializer;
28  
29  /**
30   * <p>
31   * Utility class for determining which specifications are available
32   * in the current process. See JIRA issue: http://issues.apache.org/jira/browse/MYFACES-2386
33   * </p>
34   *
35   * @author Jan-Kees van Andel
36   * @author Jakob Korherr (latest modification by $Author$)
37   * @version $Revision$ $Date$
38   * @since 2.0
39   */
40  public final class ExternalSpecifications
41  {
42      private static final Logger log = Logger.getLogger(ExternalSpecifications.class.getName());
43  
44      private static Lazy<Boolean> beanValidationAvailable = new Lazy<>(() ->
45      {
46          boolean available;
47          try
48          {
49              try
50              {
51                  available = ClassUtils.classForName("javax.validation.Validation") != null;
52              }
53              catch(ClassNotFoundException e)
54              {
55                  available = false;
56              }
57  
58              if (available)
59              {
60                  try
61                  {
62                      // Trial-error approach to check for Bean Validation impl existence.
63                      // If any Exception occurs here, we assume that Bean Validation is not available.
64                      // The cause may be anything, i.e. NoClassDef, config error...
65                      _ValidationUtils.tryBuildDefaultValidatorFactory();
66                  }
67                  catch (Throwable t)
68                  {
69                      //log.log(Level.FINE, "Error initializing Bean Validation (could be normal)", t);
70                      available = false;
71                  }
72              }
73          }
74          catch (Throwable t)
75          {
76              log.log(Level.FINE, "Error loading class (could be normal)", t);
77              available = false;
78          }
79  
80          log.info("MyFaces Core Bean Validation support " + (available ? "enabled" : "disabled"));
81  
82          return available;
83      });
84      
85      private static Lazy<Boolean> cdiAvailable = new Lazy<>(() ->
86      {
87          boolean available;
88          try
89          {
90              available = ClassUtils.classForName("javax.enterprise.inject.spi.BeanManager") != null;
91          }
92          catch (Throwable t)
93          {
94              //log.log(Level.FINE, "Error loading class (could be normal)", t);
95              available = false;
96          }
97  
98          log.info("MyFaces Core CDI support " + (available ? "enabled" : "disabled"));
99   
100         return available;
101     });
102     
103     private static Lazy<Boolean> el3Available = new Lazy<>(() ->
104     {
105         boolean available;
106         try
107         {
108             available = ClassUtils.classForName("javax.el.StaticFieldELResolver") != null ;
109         }
110         catch (Throwable t)
111         {
112             available = false;
113         }
114         log.info("MyFaces Core EL 3.0 support " + (available ? "enabled" : "disabled"));
115 
116         return available;
117     });
118 
119     private static Lazy<Boolean> sevlet4Available = new Lazy<>(() ->
120     {
121         boolean available;
122         try
123         {
124             available = ClassUtils.classForName("javax.servlet.http.PushBuilder") != null
125                     && HttpServletRequest.class.getMethod("newPushBuilder", (Class[]) null) != null;
126         }
127         catch (Throwable t)
128         {
129             available = false;
130         }
131         log.info("MyFaces Core Servlet 4.0 support " + (available ? "enabled" : "disabled"));
132 
133         return available;
134     });
135 
136     /**
137      * This method determines if Bean Validation is present.
138      *
139      * Eager initialization is used for performance. This means Bean Validation binaries
140      * should not be added at runtime after this variable has been set.
141      * @return true if Bean Validation is available, false otherwise.
142      */
143     public static boolean isBeanValidationAvailable()
144     {
145         return beanValidationAvailable.get();
146     }
147     
148     public static boolean isCDIAvailable(ExternalContext externalContext)
149     {
150         return cdiAvailable.get() && 
151                 externalContext.getApplicationMap().containsKey(AbstractFacesInitializer.CDI_BEAN_MANAGER_INSTANCE);
152     }
153     
154     public static boolean isEL3Available()
155     {
156         return el3Available.get();
157     }
158 
159     public static boolean isServlet4Available()
160     {
161         return sevlet4Available.get();
162     }
163 
164     /**
165      * this class should not be instantiated.
166      */
167     private ExternalSpecifications()
168     {
169     }
170 
171 }