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.custom.validatebeanbehavior;
20  
21  import java.util.logging.Level;
22  import java.util.logging.Logger;
23  import javax.el.ELContext;
24  import javax.validation.Validation;
25  import javax.validation.Validator;
26  
27  /**
28   * <p>
29   * Utility class for determining which specifications are available
30   * in the current process. See JIRA issue: http://issues.apache.org/jira/browse/MYFACES-2386
31   * </p>
32   *
33   * Note: Copy from MyFaces Core 2.0.
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  final class ExternalSpecifications {
41  
42      //private static final Log log = LogFactory.getLog(BeanValidator.class);
43      private static final Logger log = Logger.getLogger(ExternalSpecifications.class.getName());
44  
45      private static Boolean beanValidationAvailable;
46      private static Boolean unifiedELAvailable;
47  
48      /**
49       * Static inner class to prevent NoClassDefFoundErrors when Bean Validation is not available.
50       */
51      private static final class ValidationHolder {
52          static boolean trialErrorValidationInitialization() {
53              try {
54                  // Trial-error approach to check for Bean Validation impl existence.
55                  // If any Exception occurs here, we assume that Bean Validation is not available.
56                  // The cause may be anything, i.e. NoClassDef, config error...
57                  final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
58  
59                  return validator != null;
60              } catch (Throwable t) {
61                  log.log(Level.FINE, "Error initializing Bean Validation (could be normal)", t);
62                  return false;
63              }
64  
65          }
66      }
67  
68      /**
69       * This method determines if Bean Validation is present.
70       * <p/>
71       * Eager initialization is used for performance. This means Bean Validation binaries
72       * should not be added at runtime after this variable has been set.
73       *
74       * @return true if Bean Validation is available, false otherwise.
75       */
76      static synchronized boolean isBeanValidationAvailable() {
77          if (beanValidationAvailable == null) {
78              try {
79                  beanValidationAvailable = (Class.forName("javax.validation.Validation") != null);
80  
81                  if (beanValidationAvailable) {
82                      beanValidationAvailable = ValidationHolder.trialErrorValidationInitialization();
83                  }
84              } catch (Throwable t) {
85                  log.log(Level.FINE, "Error loading class (could be normal)", t);
86                  beanValidationAvailable = false;
87              }
88  
89              log.info("MyFaces Bean Validation support " + (beanValidationAvailable ? "enabled" : "disabled"));
90          }
91          return beanValidationAvailable;
92      }
93  
94      /**
95       * This method determines if Unified EL is present.
96       * <p/>
97       * Eager initialization is used for performance. This means Unified EL binaries
98       * should not be added at runtime after this variable has been set.
99       *
100      * @return true if UEL is available, false otherwise.
101      */
102     static synchronized boolean isUnifiedELAvailable() {
103         if (unifiedELAvailable == null) {
104             try {
105                 // Check if the UEL classes are available.
106                 // If the JSP EL classes are loaded first, UEL will not work
107                 // properly, hence it will be disabled.
108                 unifiedELAvailable = (
109                         Class.forName("javax.el.ValueReference") != null
110                                 && Class.forName("javax.el.ValueExpression")
111                                 .getMethod("getValueReference", ELContext.class) != null
112                 );
113             } catch (Throwable t) {
114                 log.log(Level.FINE, "Error loading class (could be normal)", t);
115                 unifiedELAvailable = false;
116             }
117 
118             log.info("MyFaces Unified EL support " + (unifiedELAvailable ? "enabled" : "disabled"));
119         }
120         return unifiedELAvailable;
121     }
122 
123     /**
124      * this class should not be instantiated.
125      */
126     private ExternalSpecifications() {
127     }
128 
129 }