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.spi.impl;
20  
21  import org.apache.myfaces.config.DefaultFacesConfigurationMerger;
22  import org.apache.myfaces.shared.util.ClassUtils;
23  import org.apache.myfaces.spi.FacesConfigurationMerger;
24  import org.apache.myfaces.spi.FacesConfigurationMergerFactory;
25  import org.apache.myfaces.spi.ServiceProviderFinderFactory;
26  
27  import javax.faces.FacesException;
28  import javax.faces.context.ExternalContext;
29  import java.lang.reflect.InvocationTargetException;
30  import java.security.AccessController;
31  import java.security.PrivilegedActionException;
32  import java.util.List;
33  import java.util.logging.Level;
34  import java.util.logging.Logger;
35  
36  /**
37   * @author Jakob Korherr
38   */
39  public class DefaultFacesConfigurationMergerFactory extends FacesConfigurationMergerFactory
40  {
41  
42      public static final String FACES_CONFIGURATION_MERGER = FacesConfigurationMerger.class.getName();
43      public static final String FACES_CONFIGURATION_MERGER_INSTANCE_KEY = FACES_CONFIGURATION_MERGER + ".INSTANCE";
44  
45      @Override
46      public FacesConfigurationMerger getFacesConfigurationMerger(ExternalContext externalContext)
47      {
48          // check for cached instance
49          FacesConfigurationMerger returnValue = (FacesConfigurationMerger)
50                  externalContext.getApplicationMap().get(FACES_CONFIGURATION_MERGER_INSTANCE_KEY);
51  
52          if (returnValue == null)
53          {
54              final ExternalContext extContext = externalContext;
55              try
56              {
57                  if (System.getSecurityManager() != null)
58                  {
59                      returnValue = AccessController.doPrivileged(
60                              new java.security.PrivilegedExceptionAction<FacesConfigurationMerger>()
61                              {
62                                  public FacesConfigurationMerger run() throws ClassNotFoundException,
63                                          NoClassDefFoundError,
64                                          InstantiationException,
65                                          IllegalAccessException,
66                                          InvocationTargetException,
67                                          PrivilegedActionException
68                                  {
69                                      return resolveFacesConfigurationMergerFromService(extContext);
70                                  }
71                              });
72                  }
73                  else
74                  {
75                      returnValue = resolveFacesConfigurationMergerFromService(extContext);
76                  }
77  
78                  // cache the result on the ApplicationMap
79                  externalContext.getApplicationMap().put(FACES_CONFIGURATION_MERGER_INSTANCE_KEY, returnValue);
80              }
81              catch (ClassNotFoundException e)
82              {
83                  // ignore
84              }
85              catch (NoClassDefFoundError e)
86              {
87                  // ignore
88              }
89              catch (InstantiationException e)
90              {
91                  getLogger().log(Level.SEVERE, "", e);
92              }
93              catch (IllegalAccessException e)
94              {
95                  getLogger().log(Level.SEVERE, "", e);
96              }
97              catch (InvocationTargetException e)
98              {
99                  getLogger().log(Level.SEVERE, "", e);
100             }
101             catch (PrivilegedActionException e)
102             {
103                 throw new FacesException(e);
104             }
105         }
106 
107 
108         return returnValue;
109     }
110 
111     private FacesConfigurationMerger resolveFacesConfigurationMergerFromService(ExternalContext externalContext)
112             throws ClassNotFoundException,
113                    NoClassDefFoundError,
114                    InstantiationException,
115                    IllegalAccessException,
116                    InvocationTargetException,
117                    PrivilegedActionException
118     {
119         // get all fitting SPI implementations (no need to cache this since it's only called once per JSF-app)
120         List<String> classList = ServiceProviderFinderFactory.getServiceProviderFinder(externalContext)
121                 .getServiceProviderList(FACES_CONFIGURATION_MERGER);
122 
123         // create the instance using decorator pattern
124         return ClassUtils.buildApplicationObject(FacesConfigurationMerger.class,
125                 classList, new DefaultFacesConfigurationMerger());
126     }
127 
128     private Logger getLogger()
129     {
130         return Logger.getLogger(DefaultFacesConfigurationMergerFactory.class.getName());
131     }
132 
133 }