Coverage Report - org.apache.myfaces.mc.test.core.AbstractMyFacesTestCase
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractMyFacesTestCase
0%
0/457
0%
0/224
4.136
AbstractMyFacesTestCase$JUnitFacesInitializer
0%
0/7
N/A
4.136
AbstractMyFacesTestCase$MyFacesMockFacesConfigurationProvider
0%
0/76
0%
0/44
4.136
AbstractMyFacesTestCase$SharedFacesConfiguration
0%
0/20
N/A
4.136
 
 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.mc.test.core;
 20  
 
 21  
 import org.apache.myfaces.mc.test.core.mock.MockMyFacesViewDeclarationLanguageFactory;
 22  
 import java.io.FileNotFoundException;
 23  
 import java.io.IOException;
 24  
 import java.io.InputStream;
 25  
 import java.lang.reflect.Constructor;
 26  
 import java.lang.reflect.Field;
 27  
 import java.lang.reflect.InvocationTargetException;
 28  
 import java.lang.reflect.Method;
 29  
 import java.net.URI;
 30  
 import java.net.URL;
 31  
 import java.net.URLClassLoader;
 32  
 import java.util.List;
 33  
 import java.util.Map;
 34  
 import java.util.concurrent.ConcurrentHashMap;
 35  
 import java.util.logging.Level;
 36  
 import java.util.logging.Logger;
 37  
 
 38  
 import javax.el.ExpressionFactory;
 39  
 import javax.faces.FacesException;
 40  
 import javax.faces.FactoryFinder;
 41  
 import javax.faces.application.Application;
 42  
 import javax.faces.application.FacesMessage;
 43  
 import javax.faces.application.ProjectStage;
 44  
 import javax.faces.application.ViewHandler;
 45  
 import javax.faces.component.UIViewRoot;
 46  
 import javax.faces.context.ExternalContext;
 47  
 import javax.faces.context.FacesContext;
 48  
 import javax.faces.context.FacesContextFactory;
 49  
 import javax.faces.context.Flash;
 50  
 import javax.faces.event.ExceptionQueuedEvent;
 51  
 import javax.faces.event.ExceptionQueuedEventContext;
 52  
 import javax.faces.event.PhaseId;
 53  
 import javax.faces.event.PhaseListener;
 54  
 import javax.faces.event.PreRenderViewEvent;
 55  
 import javax.faces.lifecycle.Lifecycle;
 56  
 import javax.faces.lifecycle.LifecycleFactory;
 57  
 import javax.faces.view.ViewDeclarationLanguage;
 58  
 import javax.faces.webapp.FacesServlet;
 59  
 import javax.naming.Context;
 60  
 import javax.servlet.ServletContext;
 61  
 import javax.servlet.ServletContextEvent;
 62  
 import javax.servlet.http.HttpServletResponse;
 63  
 
 64  
 import org.apache.myfaces.config.ConfigFilesXmlValidationUtils;
 65  
 import org.apache.myfaces.config.DefaultFacesConfigurationProvider;
 66  
 import org.apache.myfaces.config.RuntimeConfig;
 67  
 import org.apache.myfaces.config.annotation.NoInjectionAnnotationLifecycleProvider;
 68  
 import org.apache.myfaces.config.element.FacesConfig;
 69  
 import org.apache.myfaces.config.impl.digester.elements.FactoryImpl;
 70  
 import org.apache.myfaces.lifecycle.LifecycleImpl;
 71  
 import org.apache.myfaces.lifecycle.ViewNotFoundException;
 72  
 import org.apache.myfaces.mc.test.core.annotation.DeclareFacesConfig;
 73  
 import org.apache.myfaces.mc.test.core.annotation.ManagedBeans;
 74  
 import org.apache.myfaces.mc.test.core.annotation.PageBean;
 75  
 import org.apache.myfaces.mc.test.core.annotation.TestConfig;
 76  
 import org.apache.myfaces.mc.test.core.mock.DefaultContext;
 77  
 import org.apache.myfaces.mc.test.core.mock.MockInitialContextFactory;
 78  
 import org.apache.myfaces.shared.config.MyfacesConfig;
 79  
 import org.apache.myfaces.shared.util.ClassUtils;
 80  
 import org.apache.myfaces.spi.FacesConfigurationProvider;
 81  
 import org.apache.myfaces.spi.impl.DefaultFacesConfigurationProviderFactory;
 82  
 import org.apache.myfaces.spi.impl.NoInjectionAnnotationInjectionProvider;
 83  
 import org.apache.myfaces.test.el.MockExpressionFactory;
 84  
 import org.apache.myfaces.test.mock.MockPrintWriter;
 85  
 import org.apache.myfaces.test.mock.MockServletConfig;
 86  
 import org.apache.myfaces.test.mock.MockServletContext;
 87  
 import org.apache.myfaces.test.mock.MockWebContainer;
 88  
 import org.apache.myfaces.webapp.AbstractFacesInitializer;
 89  
 import org.apache.myfaces.webapp.StartupServletContextListener;
 90  
 import org.junit.After;
 91  
 import org.junit.AfterClass;
 92  
 import org.junit.Before;
 93  
 import org.xml.sax.SAXException;
 94  
 
 95  
 /**
 96  
  * <p>Abstract JUnit test case base class, which sets up MyFaces Core environment
 97  
  * using mock object for the outer servlet environment.</p>
 98  
  * <p>Since jsp engine is not bundled with MyFaces, this configuration is able to 
 99  
  * handle facelet pages only.</p>
 100  
  * 
 101  
  * @author Leonardo Uribe
 102  
  *
 103  
  */
 104  0
 public abstract class AbstractMyFacesTestCase
 105  
 {
 106  
     private static final Class<?> PHASE_EXECUTOR_CLASS;
 107  
     private static final Class<?> PHASE_MANAGER_CLASS;
 108  
     
 109  
     static {
 110  0
         Class<?> phaseExecutorClass = null;
 111  0
         Class<?> phaseManagerClass = null;
 112  
         try
 113  
         {
 114  0
             phaseExecutorClass = Class.forName("org.apache.myfaces.lifecycle.PhaseExecutor");
 115  0
             phaseManagerClass = Class.forName("org.apache.myfaces.lifecycle.PhaseListenerManager");
 116  
         }
 117  0
         catch (ClassNotFoundException e)
 118  
         {
 119  
             //No op
 120  0
         }
 121  0
         PHASE_EXECUTOR_CLASS = phaseExecutorClass;
 122  0
         PHASE_MANAGER_CLASS = phaseManagerClass;
 123  
     }
 124  
     
 125  
     public static final String PHASE_MANAGER_INSTANCE = "org.apache.myfaces.test.PHASE_MANAGER_INSTANCE";
 126  
     
 127  
     public static final String LAST_PHASE_PROCESSED = "oam.LAST_PHASE_PROCESSED";
 128  
     
 129  
     public static final String LAST_RENDER_PHASE_STEP = "oam.LAST_RENDER_PHASE_STEP";
 130  
     
 131  
     public static final int BEFORE_RENDER_STEP = 1;
 132  
     public static final int BUILD_VIEW_CYCLE_STEP = 2;
 133  
     public static final int VIEWHANDLER_RENDER_STEP = 3;
 134  
     public static final int AFTER_RENDER_STEP = 4;
 135  
     
 136  
     // ------------------------------------------------------------ Constructors
 137  
 
 138  
     /**
 139  
      * <p>Construct a new instance of this test case.</p>
 140  
      *
 141  
      * @param name Name of this test case
 142  
      */    
 143  
     public AbstractMyFacesTestCase()
 144  0
     {
 145  0
     }
 146  
 
 147  
     // ---------------------------------------------------- Overall Test Methods
 148  
 
 149  
     /**
 150  
      * <p>Set up instance variables required by this test case.</p>
 151  
      */
 152  
     @Before
 153  
     public void setUp() throws Exception
 154  
     {
 155  
         // Set up a new thread context class loader
 156  0
         setUpClassloader();
 157  
         
 158  0
         jsfConfiguration = sharedConfiguration.get(getTestJavaClass().getName());
 159  0
         if (jsfConfiguration == null)
 160  
         {
 161  0
             jsfConfiguration = new SharedFacesConfiguration();
 162  
         }
 163  
         
 164  0
         TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
 165  0
         boolean enableJNDI = (testConfig != null) ? testConfig.enableJNDI() : true;
 166  0
         if (enableJNDI)
 167  
         {
 168  0
             System.setProperty(Context.INITIAL_CONTEXT_FACTORY, MockInitialContextFactory.class.getName());
 169  0
             jndiContext = new DefaultContext();
 170  0
             MockInitialContextFactory.setCurrentContext(jndiContext);
 171  
         }
 172  
 
 173  
         // Set up Servlet API Objects
 174  0
         setUpServletObjects();
 175  
 
 176  
         // Set up JSF API Objects
 177  0
         FactoryFinder.releaseFactories();
 178  
 
 179  0
         setUpServletListeners();
 180  
         
 181  0
         webContainer.contextInitialized(new ServletContextEvent(servletContext));
 182  
         
 183  0
         setUpFacesServlet();
 184  
         
 185  0
         sharedConfiguration.put(getTestJavaClass().getName(), jsfConfiguration);
 186  0
     }
 187  
     
 188  
     /**
 189  
      * Set up the thread context classloader. JSF uses the this classloader
 190  
      * in order to find related factory classes and other resources, but in
 191  
      * some selected cases, the default classloader cannot be properly set.
 192  
      * 
 193  
      * @throws Exception 
 194  
      */
 195  
     protected void setUpClassloader() throws Exception
 196  
     {
 197  
         // Set up a new thread context class loader
 198  0
         threadContextClassLoader = Thread.currentThread()
 199  
                 .getContextClassLoader();
 200  0
         Thread.currentThread()
 201  
                 .setContextClassLoader(
 202  
                         new URLClassLoader(new URL[0], this.getClass()
 203  
                                 .getClassLoader()));
 204  0
         classLoaderSet = true;
 205  0
     }
 206  
     
 207  
     /**
 208  
      * <p>Setup servlet objects that will be used for the test:</p>
 209  
      * 
 210  
      * <ul>
 211  
      * <li><code>servletConfig</code> (<code>MockServletConfig</code>)</li>
 212  
      * <li><code>servletContext</code> (<code>MockServletContext</code>)</li>
 213  
      * </ul>
 214  
      * 
 215  
      * @throws Exception
 216  
      */
 217  
     protected void setUpServletObjects() throws Exception
 218  
     {
 219  0
         servletContext = new MockServletContext();
 220  0
         servletConfig = new MockServletConfig(servletContext);
 221  0
         servletContext.setDocumentRoot(getWebappContextURI());
 222  0
         webContainer = new MockWebContainer();
 223  0
         servletContext.setWebContainer(webContainer);
 224  0
         setUpWebConfigParams();
 225  0
     }
 226  
     
 227  
     /**
 228  
      * <p>Setup web config params. By default it sets the following params</p>
 229  
      * 
 230  
      * <ul>
 231  
      * <li>"org.apache.myfaces.INITIALIZE_ALWAYS_STANDALONE", "true"</li>
 232  
      * <li>"javax.faces.PROJECT_STAGE", "UnitTest"</li>
 233  
      * <li>"javax.faces.PARTIAL_STATE_SAVING", "true"</li>
 234  
      * <li>"javax.faces.FACELETS_REFRESH_PERIOD", "-1"</li>
 235  
      * </ul>
 236  
      * 
 237  
      * @throws Exception
 238  
      */
 239  
     protected void setUpWebConfigParams() throws Exception
 240  
     {
 241  0
         servletContext.addInitParameter("org.apache.myfaces.INITIALIZE_ALWAYS_STANDALONE", "true");
 242  0
         servletContext.addInitParameter("javax.faces.PROJECT_STAGE", "UnitTest");
 243  0
         servletContext.addInitParameter("javax.faces.PARTIAL_STATE_SAVING", "true");
 244  0
         servletContext.addInitParameter(ViewHandler.FACELETS_REFRESH_PERIOD_PARAM_NAME,"-1");
 245  0
         servletContext.addInitParameter("org.apache.myfaces.spi.InjectionProvider", 
 246  
             NoInjectionAnnotationInjectionProvider.class.getName());
 247  0
         servletContext.addInitParameter("org.apache.myfaces.config.annotation.LifecycleProvider",
 248  
             NoInjectionAnnotationLifecycleProvider.class.getName());
 249  0
     }
 250  
     
 251  
     /**
 252  
      * <p>Return an URI that identifies the base path that will be used by servletContext
 253  
      * to load resources like facelet files an others. By default it points to the directory
 254  
      * path calculated from the package name of the child test class.</p>
 255  
      * 
 256  
      * @return
 257  
      */
 258  
     protected URI getWebappContextURI()
 259  
     {
 260  
         try
 261  
         {
 262  0
             ClassLoader cl = Thread.currentThread().getContextClassLoader();
 263  0
             URL url = cl.getResource(getWebappResourcePath());
 264  0
             if (url == null)
 265  
             {
 266  0
                 throw new FileNotFoundException(cl.getResource("").getFile()
 267  
                         + getWebappResourcePath() + " was not found");
 268  
             }
 269  
             else
 270  
             {
 271  0
                 return new URI(url.toString());
 272  
             }
 273  
         }
 274  0
         catch (Exception e)
 275  
         {
 276  0
             throw new RuntimeException("Error Initializing Context", e);
 277  
         }
 278  
     }
 279  
     
 280  
     /**
 281  
      * Return a path that is used to load resources like facelet files an others.
 282  
      * By default it points to the directory path calculated from the package 
 283  
      * name of the child test class.
 284  
      * 
 285  
      * @return
 286  
      */
 287  
     protected String getWebappResourcePath()
 288  
     {
 289  0
         TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
 290  0
         if (testConfig != null && testConfig.webappResourcePath() != null &&
 291  
             !"testClassResourcePackage".equals(testConfig.webappResourcePath()))
 292  
         {
 293  0
             return testConfig.webappResourcePath();
 294  
         }
 295  0
         return this.getClass().getName().substring(0,
 296  
                 this.getClass().getName().lastIndexOf('.')).replace('.', '/')
 297  
                 + "/";
 298  
     }
 299  
     
 300  
     /**
 301  
      * Create the ExpressionFactory instance that will be used to initialize the test
 302  
      * environment. By default it uses MockExpressionFactory. 
 303  
      * 
 304  
      * @return
 305  
      */
 306  
     protected ExpressionFactory createExpressionFactory()
 307  
     {
 308  0
         TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
 309  0
         if (testConfig != null && testConfig.expressionFactory() != null &&
 310  
             testConfig.expressionFactory().length() > 0)
 311  
         {
 312  0
             return (ExpressionFactory) ClassUtils.newInstance(
 313  
                 testConfig.expressionFactory(), ExpressionFactory.class);
 314  
         }
 315  0
         return new MockExpressionFactory();
 316  
     }
 317  
     
 318  
     /**
 319  
      * setup servlets avaliable in the test environment
 320  
      * 
 321  
      * @throws Exception
 322  
      */
 323  
     protected void setUpServlets() throws Exception
 324  
     {
 325  0
         setUpFacesServlet();
 326  0
     }
 327  
     
 328  
     /**
 329  
      * setup listeners avaliable in the test environment
 330  
      * 
 331  
      * @throws Exception
 332  
      */
 333  
     protected void setUpServletListeners() throws Exception
 334  
     {
 335  0
         setUpMyFaces();
 336  0
     }
 337  
     
 338  
     /**
 339  
      * 
 340  
      * @return
 341  
      */
 342  
     protected FacesConfigurationProvider createFacesConfigurationProvider()
 343  
     {
 344  0
         return new MyFacesMockFacesConfigurationProvider(this); 
 345  
     }
 346  
     
 347  
     protected AbstractFacesInitializer createFacesInitializer()
 348  
     {
 349  0
         return new JUnitFacesInitializer(this);
 350  
     }
 351  
     
 352  
     protected void setUpMyFaces() throws Exception
 353  
     {
 354  0
         if (facesConfigurationProvider == null)
 355  
         {
 356  0
             facesConfigurationProvider = createFacesConfigurationProvider();
 357  
         }
 358  0
         servletContext.setAttribute(
 359  
                 DefaultFacesConfigurationProviderFactory.FACES_CONFIGURATION_PROVIDER_INSTANCE_KEY, 
 360  
                 facesConfigurationProvider);
 361  0
         listener = new StartupServletContextListener();
 362  0
         listener.setFacesInitializer(createFacesInitializer());
 363  0
         webContainer.subscribeListener(listener);
 364  
         //listener.contextInitialized(new ServletContextEvent(servletContext));
 365  0
     }
 366  
 
 367  
     protected void tearDownMyFaces()
 368  
     {
 369  
         //Don't tear down FacesConfigurationProvider, because that is shared by all tests.
 370  
         //This helps to reduce the time each test takes 
 371  
         //facesConfigurationProvider = null
 372  
         
 373  
         //listener.contextDestroyed(new ServletContextEvent(servletContext));
 374  0
     }
 375  
 
 376  
     protected void setUpFacesServlet() throws Exception
 377  
     {
 378  0
         lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
 379  0
         facesContextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
 380  0
         lifecycle = lifecycleFactory.getLifecycle(getLifecycleId());
 381  0
     }
 382  
     
 383  
     protected void tearDownFacesServlet() throws Exception
 384  
     {
 385  0
         lifecycleFactory = null;
 386  0
         facesContextFactory = null;
 387  0
     }
 388  
     
 389  
     protected void tearDownServlets() throws Exception
 390  
     {
 391  0
         tearDownFacesServlet();
 392  0
     }
 393  
     
 394  
     protected void tearDownServletListeners() throws Exception
 395  
     {
 396  0
         tearDownMyFaces();
 397  0
     }
 398  
 
 399  
     @After
 400  
     public void tearDown() throws Exception
 401  
     {
 402  0
         tearDownServlets();
 403  
 
 404  0
         webContainer.contextDestroyed(new ServletContextEvent(servletContext));
 405  
         
 406  0
         tearDownServletListeners();
 407  
         
 408  0
         listener = null;
 409  
         
 410  0
         servletConfig = null;
 411  0
         servletContext = null;
 412  
         
 413  0
         FactoryFinder.releaseFactories();
 414  
         
 415  0
         if (jndiContext != null)
 416  
         {
 417  0
             MockInitialContextFactory.clearCurrentContext();
 418  
         }
 419  
         
 420  0
         tearDownClassloader();
 421  0
     }
 422  
     
 423  
     protected void tearDownClassloader() throws Exception
 424  
     {
 425  0
         if (classLoaderSet)
 426  
         {
 427  0
             Thread.currentThread().setContextClassLoader(threadContextClassLoader);
 428  0
             threadContextClassLoader = null;
 429  0
             classLoaderSet = false;
 430  
         }
 431  0
     }    
 432  
     
 433  
     @AfterClass
 434  
     public static void tearDownClass()
 435  
     {
 436  0
         standardFacesConfig = null;
 437  0
         sharedConfiguration.clear();
 438  0
     }
 439  
     
 440  
     private String getLifecycleId()
 441  
     {
 442  
         // 1. check for Servlet's init-param
 443  
         // 2. check for global context parameter
 444  
         // 3. use default Lifecycle Id, if none of them was provided
 445  0
         String serLifecycleId = servletConfig.getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
 446  0
         String appLifecycleId = servletConfig.getServletContext().getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
 447  0
         appLifecycleId = serLifecycleId == null ? appLifecycleId : serLifecycleId;
 448  0
         return appLifecycleId != null ? appLifecycleId : LifecycleFactory.DEFAULT_LIFECYCLE;
 449  
     }
 450  
 
 451  
     /**
 452  
      * Call lifecycle.execute(facesContext)
 453  
      * 
 454  
      * @param facesContext
 455  
      */
 456  
     public void processLifecycleExecute(FacesContext facesContext)
 457  
     {
 458  0
         lifecycle.attachWindow(facesContext);
 459  0
         lifecycle.execute(facesContext);
 460  0
         facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.INVOKE_APPLICATION);
 461  0
     }
 462  
 
 463  
     /**
 464  
      * Execute restore view phase.
 465  
      * 
 466  
      * @param facesContext
 467  
      * @throws Exception
 468  
      */
 469  
     public void restoreView(FacesContext facesContext)
 470  
     {
 471  0
         lifecycle.attachWindow(facesContext);
 472  0
         executePhase(facesContext, PhaseId.RESTORE_VIEW);
 473  0
         facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.RESTORE_VIEW);
 474  0
     }
 475  
     
 476  
     /**
 477  
      * Execute apply request values phase. If the responseComplete or renderResponse
 478  
      * flags are set, it returns without do any action.
 479  
      * 
 480  
      * @param facesContext
 481  
      * @throws Exception
 482  
      */
 483  
     public void applyRequestValues(FacesContext facesContext)
 484  
     {
 485  0
         if (facesContext.getRenderResponse() || facesContext.getResponseComplete())
 486  
         {
 487  0
             return;
 488  
         }
 489  0
         processRemainingPhasesBefore(facesContext, PhaseId.APPLY_REQUEST_VALUES);
 490  0
         executePhase(facesContext, PhaseId.APPLY_REQUEST_VALUES);
 491  0
         facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.APPLY_REQUEST_VALUES);
 492  0
     }
 493  
 
 494  
     /**
 495  
      * Execute process validations phase. If the responseComplete or renderResponse
 496  
      * flags are set, it returns without do any action.
 497  
      * 
 498  
      * @param facesContext
 499  
      * @throws Exception
 500  
      */
 501  
     public void processValidations(FacesContext facesContext)
 502  
     {
 503  0
         if (facesContext.getRenderResponse() || facesContext.getResponseComplete())
 504  
         {
 505  0
             return;
 506  
         }
 507  0
         processRemainingPhasesBefore(facesContext, PhaseId.PROCESS_VALIDATIONS);
 508  0
         executePhase(facesContext, PhaseId.PROCESS_VALIDATIONS);
 509  0
         facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.PROCESS_VALIDATIONS);
 510  0
     }
 511  
 
 512  
     /**
 513  
      * Execute update model phase. If the responseComplete or renderResponse
 514  
      * flags are set, it returns without do any action.
 515  
      * 
 516  
      * @param facesContext
 517  
      * @throws Exception
 518  
      */
 519  
     public void updateModelValues(FacesContext facesContext)
 520  
     {
 521  0
         if (facesContext.getRenderResponse() || facesContext.getResponseComplete())
 522  
         {
 523  0
             return;
 524  
         }
 525  0
         processRemainingPhasesBefore(facesContext, PhaseId.UPDATE_MODEL_VALUES);
 526  0
         executePhase(facesContext, PhaseId.UPDATE_MODEL_VALUES);
 527  0
         facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.UPDATE_MODEL_VALUES);
 528  
 
 529  0
     }
 530  
     
 531  
     /**
 532  
      * Execute invoke application phase. If the responseComplete or renderResponse
 533  
      * flags are set, it returns without do any action.
 534  
      * 
 535  
      * @param facesContext
 536  
      * @throws Exception
 537  
      */
 538  
     public void invokeApplication(FacesContext facesContext)
 539  
     {
 540  0
         if (facesContext.getRenderResponse() || facesContext.getResponseComplete())
 541  
         {
 542  0
             return;
 543  
         }
 544  0
         processRemainingPhasesBefore(facesContext, PhaseId.INVOKE_APPLICATION);
 545  0
         executePhase(facesContext, PhaseId.INVOKE_APPLICATION);
 546  0
         facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.INVOKE_APPLICATION);
 547  0
     }
 548  
 
 549  
     public void processLifecycleRender(FacesContext facesContext)
 550  
     {
 551  0
         renderResponse(facesContext);
 552  0
     }
 553  
 
 554  
     /**
 555  
      * Call lifecycle.render(facesContext)
 556  
      * 
 557  
      * @param facesContext
 558  
      */
 559  
     public void renderResponse(FacesContext facesContext)
 560  
     {
 561  0
         processRemainingExecutePhases(facesContext);
 562  0
         lifecycle.render(facesContext);
 563  0
         facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.RENDER_RESPONSE);
 564  0
         facesContext.getAttributes().put(LAST_RENDER_PHASE_STEP, AFTER_RENDER_STEP);
 565  0
     }
 566  
     
 567  
     protected void processRemainingPhasesBefore(FacesContext facesContext, PhaseId phaseId)
 568  
     {
 569  0
         PhaseId lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
 570  0
         if (lastPhaseId == null)
 571  
         {
 572  0
             if (!phaseId.equals(PhaseId.RESTORE_VIEW))
 573  
             {
 574  0
                 restoreView(facesContext);
 575  0
                 lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
 576  
             }
 577  
             else
 578  
             {
 579  
                 // There are no phases before restore view
 580  0
                 return;
 581  
             }
 582  
         }
 583  0
         if (PhaseId.APPLY_REQUEST_VALUES.equals(phaseId))
 584  
         {
 585  0
             return;
 586  
         }
 587  0
         boolean continueProcess = false;
 588  0
         if (continueProcess || PhaseId.RESTORE_VIEW.equals(lastPhaseId))
 589  
         {
 590  0
             applyRequestValues(facesContext);
 591  0
             lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
 592  0
             continueProcess = true;
 593  
         }
 594  0
         if (PhaseId.PROCESS_VALIDATIONS.equals(phaseId))
 595  
         {
 596  0
             return;
 597  
         }
 598  0
         if (continueProcess || PhaseId.APPLY_REQUEST_VALUES.equals(lastPhaseId))
 599  
         {
 600  0
             processValidations(facesContext);
 601  0
             lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
 602  0
             continueProcess = true;
 603  
         }
 604  0
         if (PhaseId.UPDATE_MODEL_VALUES.equals(phaseId))
 605  
         {
 606  0
             return;
 607  
         }
 608  0
         if (continueProcess || PhaseId.PROCESS_VALIDATIONS.equals(lastPhaseId))
 609  
         {
 610  0
             updateModelValues(facesContext);
 611  0
             lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
 612  0
             continueProcess = true;
 613  
         }
 614  0
         if (PhaseId.INVOKE_APPLICATION.equals(phaseId))
 615  
         {
 616  0
             return;
 617  
         }
 618  0
         if (continueProcess || PhaseId.UPDATE_MODEL_VALUES.equals(lastPhaseId))
 619  
         {
 620  0
             invokeApplication(facesContext);
 621  0
             lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
 622  0
             continueProcess = true;
 623  
         }        
 624  0
         if (PhaseId.RENDER_RESPONSE.equals(phaseId))
 625  
         {
 626  0
             return;
 627  
         }
 628  0
         if (continueProcess || PhaseId.INVOKE_APPLICATION.equals(lastPhaseId))
 629  
         {
 630  0
             renderResponse(facesContext);
 631  0
             lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
 632  0
             continueProcess = true;
 633  
         }
 634  0
     }
 635  
     
 636  
     public void processRemainingExecutePhases(FacesContext facesContext)
 637  
     {
 638  0
         PhaseId lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
 639  0
         if (lastPhaseId == null)
 640  
         {
 641  0
             processLifecycleExecute(facesContext);
 642  0
             return;
 643  
         }
 644  
         else
 645  
         {
 646  0
             boolean continueProcess = false;
 647  0
             if (PhaseId.RESTORE_VIEW.equals(lastPhaseId))
 648  
             {
 649  0
                 applyRequestValues(facesContext);
 650  0
                 continueProcess = true;
 651  
             }
 652  0
             if (continueProcess || PhaseId.APPLY_REQUEST_VALUES.equals(lastPhaseId))
 653  
             {
 654  0
                 processValidations(facesContext);
 655  0
                 continueProcess = true;
 656  
             }
 657  0
             if (continueProcess || PhaseId.PROCESS_VALIDATIONS.equals(lastPhaseId))
 658  
             {
 659  0
                 updateModelValues(facesContext);
 660  0
                 continueProcess = true;
 661  
             }
 662  0
             if (continueProcess || PhaseId.UPDATE_MODEL_VALUES.equals(lastPhaseId))
 663  
             {
 664  0
                 invokeApplication(facesContext);
 665  0
                 continueProcess = true;
 666  
             }
 667  
         }
 668  0
     }
 669  
 
 670  
     public void processRemainingPhases(FacesContext facesContext)
 671  
     {
 672  0
         PhaseId lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
 673  0
         if (lastPhaseId == null)
 674  
         {
 675  0
             processLifecycleExecute(facesContext);
 676  0
             renderResponse(facesContext);
 677  0
             return;
 678  
         }
 679  
         else
 680  
         {
 681  0
             boolean continueProcess = false;
 682  0
             if (PhaseId.RESTORE_VIEW.equals(lastPhaseId))
 683  
             {
 684  0
                 applyRequestValues(facesContext);
 685  0
                 continueProcess = true;
 686  
             }
 687  0
             if (continueProcess || PhaseId.APPLY_REQUEST_VALUES.equals(lastPhaseId))
 688  
             {
 689  0
                 processValidations(facesContext);
 690  0
                 continueProcess = true;
 691  
             }
 692  0
             if (continueProcess || PhaseId.PROCESS_VALIDATIONS.equals(lastPhaseId))
 693  
             {
 694  0
                 updateModelValues(facesContext);
 695  0
                 continueProcess = true;
 696  
             }
 697  0
             if (continueProcess || PhaseId.UPDATE_MODEL_VALUES.equals(lastPhaseId))
 698  
             {
 699  0
                 invokeApplication(facesContext);
 700  0
                 continueProcess = true;
 701  
             }
 702  0
             if (continueProcess || PhaseId.INVOKE_APPLICATION.equals(lastPhaseId))
 703  
             {
 704  0
                 Integer step = (Integer) facesContext.getAttributes().get(LAST_RENDER_PHASE_STEP);
 705  0
                 if (step == null)
 706  
                 {
 707  0
                     renderResponse(facesContext);
 708  
                 }
 709  
                 else
 710  
                 {
 711  0
                     if (BEFORE_RENDER_STEP == step.intValue())
 712  
                     {
 713  0
                         executeBuildViewCycle(facesContext);
 714  0
                         executeViewHandlerRender(facesContext);
 715  0
                         executeAfterRender(facesContext);
 716  
                     }
 717  0
                     else if (BUILD_VIEW_CYCLE_STEP == step.intValue())
 718  
                     {
 719  0
                         executeViewHandlerRender(facesContext);
 720  0
                         executeAfterRender(facesContext);
 721  
                     }
 722  0
                     else if (VIEWHANDLER_RENDER_STEP == step.intValue())
 723  
                     {
 724  0
                         executeAfterRender(facesContext);
 725  
                     }
 726  
                 }
 727  
             }
 728  
         }
 729  0
     }
 730  
     
 731  
     /**
 732  
      * Indicate if annotation scanning should be done over the classpath. 
 733  
      * By default it is set to false.
 734  
      * 
 735  
      * @return
 736  
      */
 737  
     protected boolean isScanAnnotations()
 738  
     {
 739  0
         TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
 740  0
         if (testConfig != null)
 741  
         {
 742  0
             return testConfig.scanAnnotations();
 743  
         }
 744  0
         return false;
 745  
     }
 746  
     
 747  
     public void executeBeforeRender(FacesContext facesContext)
 748  
     {
 749  0
         if (lifecycle instanceof LifecycleImpl)
 750  
         {
 751  0
             LifecycleImpl lifecycleImpl = (LifecycleImpl) lifecycle;
 752  
             
 753  0
             Object phaseExecutor = null;
 754  0
             Object phaseManager = null;
 755  
             try
 756  
             {
 757  0
                 Field renderExecutorField = lifecycleImpl.getClass().getDeclaredField("renderExecutor");
 758  0
                 if (!renderExecutorField.isAccessible())
 759  
                 {
 760  0
                     renderExecutorField.setAccessible(true);
 761  
                 }
 762  0
                 phaseExecutor = renderExecutorField.get(lifecycleImpl);
 763  
 
 764  0
                 if (facesContext.getResponseComplete())
 765  
                 {
 766  0
                     return;
 767  
                 }
 768  
 
 769  0
                 phaseManager = facesContext.getAttributes().get(PHASE_MANAGER_INSTANCE);
 770  0
                 if (phaseManager == null)
 771  
                 {
 772  0
                     Method getPhaseListenersMethod = lifecycleImpl.getClass().getDeclaredMethod("getPhaseListeners");
 773  0
                     if (!getPhaseListenersMethod.isAccessible())
 774  
                     {
 775  0
                         getPhaseListenersMethod.setAccessible(true);
 776  
                     }
 777  
 
 778  0
                     Constructor<?> plmc = PHASE_MANAGER_CLASS.getDeclaredConstructor(
 779  
                         new Class[]{Lifecycle.class, FacesContext.class, PhaseListener[].class});
 780  0
                     if (!plmc.isAccessible())
 781  
                     {
 782  0
                         plmc.setAccessible(true);
 783  
                     }
 784  0
                     phaseManager = plmc.newInstance(lifecycle, facesContext, getPhaseListenersMethod.invoke(
 785  
                         lifecycleImpl, null));
 786  0
                     facesContext.getAttributes().put(PHASE_MANAGER_INSTANCE, phaseManager);
 787  
                 }
 788  
             }
 789  0
             catch (NoSuchFieldException ex)
 790  
             {
 791  0
                 throw new IllegalStateException("Cannot get executors from LifecycleImpl", ex);
 792  
             }
 793  0
             catch (SecurityException ex)
 794  
             {
 795  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 796  
             }
 797  0
             catch (IllegalArgumentException ex)
 798  
             {
 799  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 800  
             }
 801  0
             catch (IllegalAccessException ex)
 802  
             {
 803  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 804  
             }
 805  0
             catch (NoSuchMethodException ex)
 806  
             {
 807  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 808  
             }
 809  0
             catch (InvocationTargetException ex)
 810  
             {
 811  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 812  
             }
 813  0
             catch (InstantiationException ex)
 814  
             {
 815  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 816  0
             }
 817  
             
 818  0
             Flash flash = facesContext.getExternalContext().getFlash();
 819  
             
 820  
             try
 821  
             {
 822  0
                 facesContext.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);
 823  
                 
 824  0
                 flash.doPrePhaseActions(facesContext);
 825  
                 
 826  
                 // let the PhaseExecutor do some pre-phase actions
 827  
                 
 828  
                 //renderExecutor.doPrePhaseActions(facesContext);
 829  0
                 Method doPrePhaseActionsMethod = phaseExecutor.getClass().getMethod("doPrePhaseActions", 
 830  
                     FacesContext.class);
 831  0
                 if(!(doPrePhaseActionsMethod.isAccessible()))
 832  
                 {
 833  0
                     doPrePhaseActionsMethod.setAccessible(true);
 834  
                 }
 835  0
                 doPrePhaseActionsMethod.invoke(phaseExecutor, facesContext);
 836  
                 
 837  
                 //phaseListenerMgr.informPhaseListenersBefore(PhaseId.RENDER_RESPONSE);
 838  0
                 Method informPhaseListenersBeforeMethod = phaseManager.getClass().getDeclaredMethod(
 839  
                     "informPhaseListenersBefore", PhaseId.class);
 840  0
                 if(!(informPhaseListenersBeforeMethod.isAccessible()))
 841  
                 {
 842  0
                     informPhaseListenersBeforeMethod.setAccessible(true);
 843  
                 }
 844  0
                 informPhaseListenersBeforeMethod.invoke(phaseManager, PhaseId.RENDER_RESPONSE);
 845  
                 
 846  
                 // also possible that one of the listeners completed the response
 847  0
                 if (facesContext.getResponseComplete())
 848  
                 {
 849  0
                     return;
 850  
                 }
 851  
                 
 852  
                 //renderExecutor.execute(facesContext);
 853  
             }
 854  
             
 855  0
             catch (Throwable e)
 856  
             {
 857  
                 // JSF 2.0: publish the executor's exception (if any).
 858  0
                 ExceptionQueuedEventContext context = new ExceptionQueuedEventContext (
 859  
                     facesContext, e, null, PhaseId.RENDER_RESPONSE);
 860  0
                 facesContext.getApplication().publishEvent (facesContext, ExceptionQueuedEvent.class, context);
 861  
             }
 862  
             
 863  
             finally
 864  0
             {
 865  
                 /*
 866  
                 phaseListenerMgr.informPhaseListenersAfter(renderExecutor.getPhase());
 867  
                 flash.doPostPhaseActions(facesContext);
 868  
                 
 869  
                 // publish a field in the application map to indicate
 870  
                 // that the first request has been processed
 871  
                 requestProcessed(facesContext);
 872  
                 */
 873  0
             }
 874  
             
 875  0
             facesContext.getExceptionHandler().handle();
 876  
             
 877  
 
 878  0
             facesContext.getAttributes().remove(PHASE_MANAGER_INSTANCE);
 879  
             
 880  0
             facesContext.getAttributes().put(LAST_RENDER_PHASE_STEP, BEFORE_RENDER_STEP);
 881  0
         }
 882  
         else
 883  
         {
 884  0
             throw new UnsupportedOperationException("Cannot execute phase on custom lifecycle instances");
 885  
         }
 886  0
     }
 887  
     
 888  
     public void executeBuildViewCycle(FacesContext facesContext)
 889  
     {
 890  0
         Application application = facesContext.getApplication();
 891  0
         ViewHandler viewHandler = application.getViewHandler();
 892  
         UIViewRoot root;
 893  
         UIViewRoot previousRoot;
 894  
         String viewId;
 895  
         String newViewId;
 896  
         boolean isNotSameRoot;
 897  0
         int loops = 0;
 898  0
         int maxLoops = 15;
 899  
         
 900  0
         if (facesContext.getViewRoot() == null)
 901  
         {
 902  0
             throw new ViewNotFoundException("A view is required to execute "+facesContext.getCurrentPhaseId());
 903  
         }
 904  
         
 905  
         try
 906  
         {
 907  
             // do-while, because the view might change in PreRenderViewEvent-listeners
 908  
             do
 909  
             {
 910  0
                 root = facesContext.getViewRoot();
 911  0
                 previousRoot = root;
 912  0
                 viewId = root.getViewId();
 913  
                 
 914  0
                 ViewDeclarationLanguage vdl = viewHandler.getViewDeclarationLanguage(
 915  
                         facesContext, viewId);
 916  0
                 if (vdl != null)
 917  
                 {
 918  0
                     vdl.buildView(facesContext, root);
 919  
                 }
 920  
                 
 921  
                 // publish a PreRenderViewEvent: note that the event listeners
 922  
                 // of this event can change the view, so we have to perform the algorithm 
 923  
                 // until the viewId does not change when publishing this event.
 924  0
                 application.publishEvent(facesContext, PreRenderViewEvent.class, root);
 925  
                 
 926  
                 // was the response marked as complete by an event listener?
 927  0
                 if (facesContext.getResponseComplete())
 928  
                 {
 929  0
                     return;
 930  
                 }
 931  
 
 932  0
                 root = facesContext.getViewRoot();
 933  
                 
 934  0
                 newViewId = root.getViewId();
 935  
                 
 936  0
                 isNotSameRoot = !( (newViewId == null ? newViewId == viewId : newViewId.equals(viewId) ) && 
 937  
                         previousRoot.equals(root) ); 
 938  
                 
 939  0
                 loops++;
 940  
             }
 941  0
             while ((newViewId == null && viewId != null) 
 942  
                     || (newViewId != null && (!newViewId.equals(viewId) || isNotSameRoot ) ) && loops < maxLoops);
 943  
             
 944  0
             if (loops == maxLoops)
 945  
             {
 946  
                 // PreRenderView reach maxLoops - probably a infinitive recursion:
 947  0
                 boolean production = facesContext.isProjectStage(ProjectStage.Production);
 948  
                 /*
 949  
                 Level level = production ? Level.FINE : Level.WARNING;
 950  
                 if (log.isLoggable(level))
 951  
                 {
 952  
                     log.log(level, "Cicle over buildView-PreRenderViewEvent on RENDER_RESPONSE phase "
 953  
                                    + "reaches maximal limit, please check listeners for infinite recursion.");
 954  
                 }*/
 955  
             }
 956  
             
 957  0
             facesContext.getAttributes().put(LAST_RENDER_PHASE_STEP, BUILD_VIEW_CYCLE_STEP);
 958  
         }
 959  0
         catch (IOException e)
 960  
         {
 961  0
             throw new FacesException(e.getMessage(), e);
 962  0
         }
 963  0
     }
 964  
     
 965  
     public void executeViewHandlerRender(FacesContext facesContext)
 966  
     {
 967  0
         Application application = facesContext.getApplication();
 968  0
         ViewHandler viewHandler = application.getViewHandler();
 969  
 
 970  
         try
 971  
         {
 972  0
             viewHandler.renderView(facesContext, facesContext.getViewRoot());
 973  
             
 974  
             // log all unhandled FacesMessages, don't swallow them
 975  
             // perf: org.apache.myfaces.context.servlet.FacesContextImpl.getMessageList() creates
 976  
             // new Collections.unmodifiableList with every invocation->  call it only once
 977  
             // and messageList is RandomAccess -> use index based loop
 978  0
             List<FacesMessage> messageList = facesContext.getMessageList();
 979  0
             if (!messageList.isEmpty())
 980  
             {
 981  0
                 StringBuilder builder = new StringBuilder();
 982  
                 //boolean shouldLog = false;
 983  0
                 for (int i = 0, size = messageList.size(); i < size; i++)
 984  
                 {
 985  0
                     FacesMessage message = messageList.get(i);
 986  0
                     if (!message.isRendered())
 987  
                     {
 988  0
                         builder.append("\n- ");
 989  0
                         builder.append(message.getDetail());
 990  
                         
 991  
                         //shouldLog = true;
 992  
                     }
 993  
                 }
 994  
                 /*
 995  
                 if (shouldLog)
 996  
                 {
 997  
                     log.log(Level.WARNING, "There are some unhandled FacesMessages, " +
 998  
                             "this means not every FacesMessage had a chance to be rendered.\n" +
 999  
                             "These unhandled FacesMessages are: " + builder.toString());
 1000  
                 }*/
 1001  
             }
 1002  0
             facesContext.getAttributes().put(LAST_RENDER_PHASE_STEP, VIEWHANDLER_RENDER_STEP);
 1003  
         }
 1004  0
         catch (IOException e)
 1005  
         {
 1006  0
             throw new FacesException(e.getMessage(), e);
 1007  0
         }
 1008  0
     }
 1009  
     
 1010  
     public void executeAfterRender(FacesContext facesContext)
 1011  
     {
 1012  0
         if (lifecycle instanceof LifecycleImpl)
 1013  
         {
 1014  0
             LifecycleImpl lifecycleImpl = (LifecycleImpl) lifecycle;
 1015  
             
 1016  0
             Object phaseExecutor = null;
 1017  0
             Object phaseManager = null;
 1018  0
             Method informPhaseListenersAfterMethod = null;
 1019  
             try
 1020  
             {
 1021  0
                 Field renderExecutorField = lifecycleImpl.getClass().getDeclaredField("renderExecutor");
 1022  0
                 if (!renderExecutorField.isAccessible())
 1023  
                 {
 1024  0
                     renderExecutorField.setAccessible(true);
 1025  
                 }
 1026  0
                 phaseExecutor = renderExecutorField.get(lifecycleImpl);
 1027  
             
 1028  0
                 phaseManager = facesContext.getAttributes().get(PHASE_MANAGER_INSTANCE);
 1029  0
                 if (phaseManager == null)
 1030  
                 {
 1031  0
                     Method getPhaseListenersMethod = lifecycleImpl.getClass().getDeclaredMethod("getPhaseListeners");
 1032  0
                     if (!getPhaseListenersMethod.isAccessible())
 1033  
                     {
 1034  0
                         getPhaseListenersMethod.setAccessible(true);
 1035  
                     }
 1036  
 
 1037  0
                     Constructor<?> plmc = PHASE_MANAGER_CLASS.getDeclaredConstructor(
 1038  
                         new Class[]{Lifecycle.class, FacesContext.class, PhaseListener[].class});
 1039  0
                     if (!plmc.isAccessible())
 1040  
                     {
 1041  0
                         plmc.setAccessible(true);
 1042  
                     }
 1043  0
                     phaseManager = plmc.newInstance(lifecycle, facesContext, getPhaseListenersMethod.invoke(
 1044  
                         lifecycleImpl, null));
 1045  0
                     facesContext.getAttributes().put(PHASE_MANAGER_INSTANCE, phaseManager);
 1046  
                 }
 1047  
 
 1048  
                 //phaseListenerMgr.informPhaseListenersAfter(renderExecutor.getPhase());
 1049  0
                 informPhaseListenersAfterMethod = phaseManager.getClass().getDeclaredMethod(
 1050  
                     "informPhaseListenersAfter", PhaseId.class);
 1051  0
                 if(!(informPhaseListenersAfterMethod.isAccessible()))
 1052  
                 {
 1053  0
                     informPhaseListenersAfterMethod.setAccessible(true);
 1054  
                 }
 1055  
                 
 1056  0
                 informPhaseListenersAfterMethod.invoke(phaseManager, PhaseId.RENDER_RESPONSE);
 1057  
             }
 1058  0
             catch (NoSuchFieldException ex)
 1059  
             {
 1060  0
                 throw new IllegalStateException("Cannot get executors from LifecycleImpl", ex);
 1061  
             }
 1062  0
             catch (SecurityException ex)
 1063  
             {
 1064  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1065  
             }
 1066  0
             catch (IllegalArgumentException ex)
 1067  
             {
 1068  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1069  
             }
 1070  0
             catch (IllegalAccessException ex)
 1071  
             {
 1072  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1073  
             }
 1074  0
             catch (NoSuchMethodException ex)
 1075  
             {
 1076  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1077  
             }
 1078  0
             catch (InvocationTargetException ex)
 1079  
             {
 1080  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1081  
             }
 1082  0
             catch (InstantiationException ex)
 1083  
             {
 1084  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1085  0
             }
 1086  
             
 1087  0
             Flash flash = facesContext.getExternalContext().getFlash();
 1088  
             
 1089  0
             flash.doPostPhaseActions(facesContext);
 1090  
             
 1091  0
             facesContext.getExceptionHandler().handle();
 1092  
 
 1093  0
             facesContext.getAttributes().remove(PHASE_MANAGER_INSTANCE);
 1094  
             
 1095  0
             facesContext.getAttributes().put(LAST_RENDER_PHASE_STEP, AFTER_RENDER_STEP);
 1096  
             //End render response phase
 1097  0
             facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.RENDER_RESPONSE);
 1098  0
         }
 1099  
         else
 1100  
         {
 1101  0
             throw new UnsupportedOperationException("Cannot execute phase on custom lifecycle instances");
 1102  
         }
 1103  0
     }
 1104  
     
 1105  
     /**
 1106  
      * Execute an specified phase, doing some reflection over LifecycleImpl.
 1107  
      * 
 1108  
      * @param facesContext
 1109  
      * @param phase
 1110  
      * @throws Exception
 1111  
      */
 1112  
     protected void executePhase(FacesContext facesContext, PhaseId phase)
 1113  
     {
 1114  0
         if (lifecycle instanceof LifecycleImpl)
 1115  
         {
 1116  0
             LifecycleImpl lifecycleImpl = (LifecycleImpl) lifecycle;
 1117  
             
 1118  0
             int phaseId = phase.equals(PhaseId.RESTORE_VIEW) ? 0 :
 1119  
                           phase.equals(PhaseId.APPLY_REQUEST_VALUES) ? 1 : 
 1120  
                           phase.equals(PhaseId.PROCESS_VALIDATIONS) ? 2 :
 1121  
                           phase.equals(PhaseId.UPDATE_MODEL_VALUES) ? 3 : 
 1122  
                           phase.equals(PhaseId.INVOKE_APPLICATION) ? 4 : 5 ;
 1123  
             
 1124  0
             Method executePhaseMethod = null;
 1125  0
             Object phaseManager = null;
 1126  0
             Object phaseExecutor = null;
 1127  
             try
 1128  
             {
 1129  0
                 if (phaseId < 5)
 1130  
                 {
 1131  
                     Field lifecycleExecutorsField;
 1132  0
                         lifecycleExecutorsField = lifecycleImpl.getClass().getDeclaredField("lifecycleExecutors");
 1133  0
                         if (!lifecycleExecutorsField.isAccessible())
 1134  
                         {
 1135  0
                             lifecycleExecutorsField.setAccessible(true);
 1136  
                         }
 1137  0
                         phaseExecutor = ((Object[])lifecycleExecutorsField.get(lifecycleImpl))[phaseId];
 1138  0
                 }
 1139  
                 else
 1140  
                 {
 1141  0
                     Field renderExecutorField = lifecycleImpl.getClass().getDeclaredField("renderExecutor");
 1142  0
                     if (!renderExecutorField.isAccessible())
 1143  
                     {
 1144  0
                         renderExecutorField.setAccessible(true);
 1145  
                     }
 1146  0
                     phaseExecutor = renderExecutorField.get(lifecycleImpl);
 1147  
                 }
 1148  
 
 1149  0
                 phaseManager = facesContext.getAttributes().get(PHASE_MANAGER_INSTANCE);
 1150  0
                 if (phaseManager == null)
 1151  
                 {
 1152  0
                     Method getPhaseListenersMethod = lifecycleImpl.getClass().getDeclaredMethod("getPhaseListeners");
 1153  0
                     if (!getPhaseListenersMethod.isAccessible())
 1154  
                     {
 1155  0
                         getPhaseListenersMethod.setAccessible(true);
 1156  
                     }
 1157  
 
 1158  0
                     Constructor<?> plmc = PHASE_MANAGER_CLASS.getDeclaredConstructor(
 1159  
                         new Class[]{Lifecycle.class, FacesContext.class, PhaseListener[].class});
 1160  0
                     if (!plmc.isAccessible())
 1161  
                     {
 1162  0
                         plmc.setAccessible(true);
 1163  
                     }
 1164  0
                     phaseManager = plmc.newInstance(lifecycle, facesContext, 
 1165  
                         getPhaseListenersMethod.invoke(lifecycleImpl, null));
 1166  0
                     facesContext.getAttributes().put(PHASE_MANAGER_INSTANCE, phaseManager);
 1167  
                 }
 1168  
 
 1169  0
                 executePhaseMethod = lifecycleImpl.getClass().getDeclaredMethod("executePhase", new Class[]{
 1170  
                         FacesContext.class, PHASE_EXECUTOR_CLASS, PHASE_MANAGER_CLASS});
 1171  0
                 if (!executePhaseMethod.isAccessible())
 1172  
                 {
 1173  0
                     executePhaseMethod.setAccessible(true);
 1174  
                 }
 1175  
                 
 1176  0
                 executePhaseMethod.invoke(lifecycleImpl, facesContext, phaseExecutor, phaseManager);
 1177  
             }
 1178  0
             catch (NoSuchFieldException ex)
 1179  
             {
 1180  0
                 throw new IllegalStateException("Cannot get executors from LifecycleImpl", ex);
 1181  
             }
 1182  0
             catch (SecurityException ex)
 1183  
             {
 1184  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1185  
             }
 1186  0
             catch (IllegalArgumentException ex)
 1187  
             {
 1188  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1189  
             }
 1190  0
             catch (IllegalAccessException ex)
 1191  
             {
 1192  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1193  
             }
 1194  0
             catch (NoSuchMethodException ex)
 1195  
             {
 1196  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1197  
             }
 1198  0
             catch (InvocationTargetException ex)
 1199  
             {
 1200  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1201  
             }
 1202  0
             catch (InstantiationException ex)
 1203  
             {
 1204  0
                 throw new UnsupportedOperationException("Cannot get executors from LifecycleImpl", ex);
 1205  0
             }            
 1206  
             
 1207  0
             if (phase.equals(PhaseId.RENDER_RESPONSE))
 1208  
             {
 1209  0
                 facesContext.getAttributes().remove(PHASE_MANAGER_INSTANCE);
 1210  
             }
 1211  0
         }
 1212  
         else
 1213  
         {
 1214  0
             throw new UnsupportedOperationException("Cannot execute phase on custom lifecycle instances");
 1215  
         }
 1216  0
     }
 1217  
     
 1218  
     protected String getRenderedContent(FacesContext facesContext) throws IOException
 1219  
     {
 1220  0
         MockPrintWriter writer1 = (MockPrintWriter) 
 1221  
             (((HttpServletResponse) facesContext.getExternalContext().getResponse()).getWriter());
 1222  0
         return String.valueOf(writer1.content());
 1223  
     }
 1224  
 
 1225  
     // ------------------------------------------------------ Instance Variables
 1226  
 
 1227  
 
 1228  
     // Thread context class loader saved and restored after each test
 1229  0
     private ClassLoader threadContextClassLoader = null;
 1230  0
     private boolean classLoaderSet = false;
 1231  0
     private Context jndiContext = null;
 1232  
 
 1233  
     // Servlet objects 
 1234  0
     protected MockServletConfig servletConfig = null;
 1235  0
     protected MockServletContext servletContext = null;
 1236  0
     protected MockWebContainer webContainer = null;
 1237  
 
 1238  
     // MyFaces specific objects created by the servlet environment
 1239  0
     protected StartupServletContextListener listener = null;
 1240  0
     protected FacesConfigurationProvider facesConfigurationProvider = null;
 1241  
     
 1242  0
     protected FacesContextFactory facesContextFactory = null;
 1243  0
     protected LifecycleFactory lifecycleFactory = null;
 1244  
     protected Lifecycle lifecycle;
 1245  
 
 1246  
     private static FacesConfig standardFacesConfig;
 1247  0
     private static Map<String, SharedFacesConfiguration> sharedConfiguration =
 1248  
         new ConcurrentHashMap<String, SharedFacesConfiguration>();
 1249  
     private SharedFacesConfiguration jsfConfiguration;
 1250  
     
 1251  
     protected Class<?> getTestJavaClass()
 1252  
     {
 1253  0
         return this.getClass();
 1254  
     }
 1255  
     
 1256  
 
 1257  
     // ------------------------------------------------------ Subclasses
 1258  
 
 1259  
     /**
 1260  
      * Mock FacesConfigurationProvider that replace the original ViewDeclarationLanguageFactory 
 1261  
      * with a customized one that contains only facelets vdl and cache some FacesConfig that 
 1262  
      * does not change to reduce the time required to process each test.
 1263  
      * 
 1264  
      * @author Leonardo Uribe
 1265  
      *
 1266  
      */
 1267  
     protected class MyFacesMockFacesConfigurationProvider extends DefaultFacesConfigurationProvider
 1268  
     {
 1269  
         private AbstractMyFacesTestCase testCase;
 1270  
         
 1271  
         public MyFacesMockFacesConfigurationProvider(AbstractMyFacesTestCase testCase)
 1272  0
         {
 1273  0
             this.testCase = testCase;
 1274  0
         }
 1275  
         
 1276  
         @Override
 1277  
         public FacesConfig getStandardFacesConfig(ExternalContext ectx)
 1278  
         {
 1279  0
             if (standardFacesConfig == null)
 1280  
             {
 1281  0
                 FacesConfig sfc = super.getStandardFacesConfig(ectx);
 1282  0
                 FactoryImpl factory = (FactoryImpl) sfc.getFactories().get(0);
 1283  
                 // Override the default vdl factory with a mock one that only load
 1284  
                 // facelet views
 1285  0
                 factory.getViewDeclarationLanguageFactory().set(0,
 1286  
                     MockMyFacesViewDeclarationLanguageFactory.class.getName());
 1287  0
                 standardFacesConfig = sfc;
 1288  
             }
 1289  0
             return standardFacesConfig;
 1290  
         }
 1291  
 
 1292  
         @Override
 1293  
         public FacesConfig getAnnotationsFacesConfig(ExternalContext ectx,
 1294  
                 boolean metadataComplete)
 1295  
         {
 1296  0
             FacesConfig facesConfig = jsfConfiguration.getAnnotationsFacesConfig();
 1297  0
             if (facesConfig == null)
 1298  
             {
 1299  0
                 if (isScanAnnotations())
 1300  
                 {
 1301  0
                     facesConfig = super.getAnnotationsFacesConfig(ectx, metadataComplete); 
 1302  
                 }
 1303  
 
 1304  0
                 ManagedBeans annoManagedBeans = getTestJavaClass().getAnnotation(ManagedBeans.class);
 1305  0
                 if (annoManagedBeans != null)
 1306  
                 {
 1307  0
                     if (facesConfig == null)
 1308  
                     {
 1309  0
                         facesConfig = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
 1310  
                     }
 1311  0
                     for (PageBean annoPageBean : annoManagedBeans.value())
 1312  
                     {
 1313  0
                         org.apache.myfaces.config.impl.digester.elements.ManagedBeanImpl bean = new 
 1314  
                             org.apache.myfaces.config.impl.digester.elements.ManagedBeanImpl();
 1315  0
                         bean.setBeanClass(annoPageBean.clazz().getName());
 1316  0
                         bean.setName(annoPageBean.name() == null ? 
 1317  
                             annoPageBean.clazz().getName() : annoPageBean.name());
 1318  0
                         bean.setScope(annoPageBean.scope() == null ? "request" : annoPageBean.scope());
 1319  0
                         bean.setEager(Boolean.toString(annoPageBean.eager()));
 1320  
 
 1321  0
                         ((org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl)facesConfig).
 1322  
                             addManagedBean(bean);
 1323  
                     }
 1324  
                 }
 1325  
 
 1326  0
                 PageBean annoPageBean = getTestJavaClass().getAnnotation(PageBean.class);
 1327  0
                 if (annoPageBean != null)
 1328  
                 {
 1329  0
                     if (facesConfig == null)
 1330  
                     {
 1331  0
                         facesConfig = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
 1332  
                     }
 1333  0
                     org.apache.myfaces.config.impl.digester.elements.ManagedBeanImpl bean = new 
 1334  
                         org.apache.myfaces.config.impl.digester.elements.ManagedBeanImpl();
 1335  0
                     bean.setBeanClass(annoPageBean.clazz().getName());
 1336  0
                     bean.setName(annoPageBean.name() == null ? annoPageBean.clazz().getName() : annoPageBean.name());
 1337  0
                     bean.setScope(annoPageBean.scope() == null ? "request" : annoPageBean.scope());
 1338  0
                     bean.setEager(Boolean.toString(annoPageBean.eager()));
 1339  
 
 1340  0
                     ((org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl)facesConfig).
 1341  
                         addManagedBean(bean);
 1342  
                 }
 1343  0
                 jsfConfiguration.setAnnotationFacesConfig(facesConfig);
 1344  
             }
 1345  0
             return facesConfig;
 1346  
         }
 1347  
 
 1348  
         @Override
 1349  
         public List<FacesConfig> getClassloaderFacesConfig(ExternalContext ectx)
 1350  
         {
 1351  0
             List<FacesConfig> list = jsfConfiguration.getClassloaderFacesConfig();
 1352  0
             if (list == null)
 1353  
             {
 1354  0
                 list = super.getClassloaderFacesConfig(ectx);
 1355  0
                 jsfConfiguration.setClassloaderFacesConfig(list);
 1356  
             }
 1357  0
             return list;
 1358  
         }
 1359  
 
 1360  
         @Override
 1361  
         public List<FacesConfig> getFaceletTaglibFacesConfig(ExternalContext externalContext)
 1362  
         {
 1363  0
             List<FacesConfig> list = jsfConfiguration.getFaceletTaglibFacesConfig();
 1364  0
             if (list == null)
 1365  
             {
 1366  0
                 list = super.getFaceletTaglibFacesConfig(externalContext);
 1367  0
                 jsfConfiguration.setFaceletTaglibFacesConfig(list);
 1368  
             }
 1369  0
             return list;
 1370  
         }
 1371  
 
 1372  
         @Override
 1373  
         public List<FacesConfig> getFacesFlowFacesConfig(ExternalContext ectx)
 1374  
         {
 1375  0
             List<FacesConfig> list = jsfConfiguration.getFacesFlowFacesConfig();
 1376  0
             if (list == null)
 1377  
             {
 1378  0
                 list = super.getFacesFlowFacesConfig(ectx);
 1379  0
                 jsfConfiguration.setFacesFlowFacesConfig(list);
 1380  
             }
 1381  0
             return list;
 1382  
         }
 1383  
 
 1384  
         @Override
 1385  
         public FacesConfig getMetaInfServicesFacesConfig(ExternalContext ectx)
 1386  
         {
 1387  0
             FacesConfig facesConfig = jsfConfiguration.getMetaInfServicesFacesConfig();
 1388  0
             if (facesConfig == null)
 1389  
             {
 1390  0
                 facesConfig = super.getMetaInfServicesFacesConfig(ectx);
 1391  
             }
 1392  0
             return facesConfig;
 1393  
         }
 1394  
         
 1395  
         @Override
 1396  
         public List<FacesConfig> getContextSpecifiedFacesConfig(ExternalContext ectx)
 1397  
         {
 1398  0
             List<FacesConfig> appConfigResources = super.getContextSpecifiedFacesConfig(ectx);
 1399  
             
 1400  0
             DeclareFacesConfig annoFacesConfig = getTestJavaClass().getAnnotation(DeclareFacesConfig.class);
 1401  0
             if (annoFacesConfig != null)
 1402  
             {
 1403  0
                 Logger log = Logger.getLogger(getTestJavaClass().getName());
 1404  
                 try
 1405  
                 {
 1406  0
                     for (String systemId : annoFacesConfig.value())
 1407  
                     {
 1408  0
                         if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
 1409  
                         {
 1410  0
                             URL url = ectx.getResource(systemId);
 1411  0
                             if (url != null)
 1412  
                             {
 1413  0
                                 validateFacesConfig(ectx, url);
 1414  
                             }
 1415  
                         }   
 1416  0
                         InputStream stream = ectx.getResourceAsStream(systemId);
 1417  0
                         if (stream == null)
 1418  
                         {
 1419  
                             
 1420  0
                             log.severe("Faces config resource " + systemId + " not found");
 1421  0
                             continue;
 1422  
                         }
 1423  
             
 1424  0
                         if (log.isLoggable(Level.INFO))
 1425  
                         {
 1426  0
                             log.info("Reading config " + systemId);
 1427  
                         }
 1428  0
                         appConfigResources.add(getUnmarshaller(ectx).getFacesConfig(stream, systemId));
 1429  
                         //getDispenser().feed(getUnmarshaller().getFacesConfig(stream, systemId));
 1430  0
                         stream.close();
 1431  
     
 1432  
                     }
 1433  
                 }
 1434  0
                 catch (Throwable e)
 1435  
                 {
 1436  0
                     throw new FacesException(e);
 1437  0
                 }
 1438  
             }
 1439  0
             return appConfigResources;
 1440  
         }
 1441  
     }
 1442  
     
 1443  
     private void validateFacesConfig(ExternalContext ectx, URL url) throws IOException, SAXException
 1444  
     {
 1445  0
         String version = ConfigFilesXmlValidationUtils.getFacesConfigVersion(url);
 1446  0
         if ("1.2".equals(version) || "2.0".equals(version) || "2.1".equals(version))
 1447  
         {
 1448  0
             ConfigFilesXmlValidationUtils.validateFacesConfigFile(url, ectx, version);
 1449  
         }
 1450  0
     }
 1451  
     
 1452  
     protected class JUnitFacesInitializer extends AbstractFacesInitializer
 1453  
     {
 1454  
         private final AbstractMyFacesTestCase testCase;
 1455  
         
 1456  
         public JUnitFacesInitializer(AbstractMyFacesTestCase testCase)
 1457  0
         {
 1458  0
             this.testCase = testCase;
 1459  0
         }
 1460  
         
 1461  
         @Override
 1462  
         protected void initContainerIntegration(ServletContext servletContext,
 1463  
                 ExternalContext externalContext)
 1464  
         {
 1465  0
             ExpressionFactory expressionFactory = createExpressionFactory();
 1466  
 
 1467  0
             RuntimeConfig runtimeConfig = buildConfiguration(servletContext, externalContext, expressionFactory);
 1468  0
         }
 1469  
 
 1470  
         public AbstractMyFacesTestCase getTestCase()
 1471  
         {
 1472  0
             return testCase;
 1473  
         }
 1474  
 
 1475  
     }
 1476  
     
 1477  0
     protected static class SharedFacesConfiguration
 1478  
     {
 1479  
         private List<FacesConfig> classloaderFacesConfig;
 1480  
         private FacesConfig annotationFacesConfig;
 1481  
         private List<FacesConfig> faceletTaglibFacesConfig;
 1482  
         private List<FacesConfig> facesFlowFacesConfig;
 1483  
         private FacesConfig metaInfServicesFacesConfig;
 1484  
         private List<FacesConfig> contextSpecifiedFacesConfig;
 1485  
 
 1486  
         /**
 1487  
          * @return the annotationFacesConfig
 1488  
          */
 1489  
         public FacesConfig getAnnotationsFacesConfig()
 1490  
         {
 1491  0
             return annotationFacesConfig;
 1492  
         }
 1493  
 
 1494  
         /**
 1495  
          * @param annotationFacesConfig the annotationFacesConfig to set
 1496  
          */
 1497  
         public void setAnnotationFacesConfig(FacesConfig annotationFacesConfig)
 1498  
         {
 1499  0
             this.annotationFacesConfig = annotationFacesConfig;
 1500  0
         }
 1501  
 
 1502  
         /**
 1503  
          * @return the annotationFacesConfig
 1504  
          */
 1505  
         public FacesConfig getAnnotationFacesConfig()
 1506  
         {
 1507  0
             return annotationFacesConfig;
 1508  
         }
 1509  
 
 1510  
         /**
 1511  
          * @return the faceletTaglibFacesConfig
 1512  
          */
 1513  
         public List<FacesConfig> getFaceletTaglibFacesConfig()
 1514  
         {
 1515  0
             return faceletTaglibFacesConfig;
 1516  
         }
 1517  
 
 1518  
         /**
 1519  
          * @param faceletTaglibFacesConfig the faceletTaglibFacesConfig to set
 1520  
          */
 1521  
         public void setFaceletTaglibFacesConfig(List<FacesConfig> faceletTaglibFacesConfig)
 1522  
         {
 1523  0
             this.faceletTaglibFacesConfig = faceletTaglibFacesConfig;
 1524  0
         }
 1525  
 
 1526  
         /**
 1527  
          * @return the facesFlowFacesConfig
 1528  
          */
 1529  
         public List<FacesConfig> getFacesFlowFacesConfig()
 1530  
         {
 1531  0
             return facesFlowFacesConfig;
 1532  
         }
 1533  
 
 1534  
         /**
 1535  
          * @param facesFlowFacesConfig the facesFlowFacesConfig to set
 1536  
          */
 1537  
         public void setFacesFlowFacesConfig(List<FacesConfig> facesFlowFacesConfig)
 1538  
         {
 1539  0
             this.facesFlowFacesConfig = facesFlowFacesConfig;
 1540  0
         }
 1541  
 
 1542  
         /**
 1543  
          * @return the metaInfServicesFacesConfig
 1544  
          */
 1545  
         public FacesConfig getMetaInfServicesFacesConfig()
 1546  
         {
 1547  0
             return metaInfServicesFacesConfig;
 1548  
         }
 1549  
 
 1550  
         /**
 1551  
          * @param metaInfServicesFacesConfig the metaInfServicesFacesConfig to set
 1552  
          */
 1553  
         public void setMetaInfServicesFacesConfig(FacesConfig metaInfServicesFacesConfig)
 1554  
         {
 1555  0
             this.metaInfServicesFacesConfig = metaInfServicesFacesConfig;
 1556  0
         }
 1557  
 
 1558  
         /**
 1559  
          * @return the contextSpecifiedFacesConfig
 1560  
          */
 1561  
         public List<FacesConfig> getContextSpecifiedFacesConfig()
 1562  
         {
 1563  0
             return contextSpecifiedFacesConfig;
 1564  
         }
 1565  
 
 1566  
         /**
 1567  
          * @param contextSpecifiedFacesConfig the contextSpecifiedFacesConfig to set
 1568  
          */
 1569  
         public void setContextSpecifiedFacesConfig(List<FacesConfig> contextSpecifiedFacesConfig)
 1570  
         {
 1571  0
             this.contextSpecifiedFacesConfig = contextSpecifiedFacesConfig;
 1572  0
         }
 1573  
 
 1574  
         /**
 1575  
          * @return the classloaderFacesConfigList
 1576  
          */
 1577  
         public List<FacesConfig> getClassloaderFacesConfig()
 1578  
         {
 1579  0
             return classloaderFacesConfig;
 1580  
         }
 1581  
 
 1582  
         /**
 1583  
          * @param classloaderFacesConfigList the classloaderFacesConfigList to set
 1584  
          */
 1585  
         public void setClassloaderFacesConfig(List<FacesConfig> classloaderFacesConfigList)
 1586  
         {
 1587  0
             this.classloaderFacesConfig = classloaderFacesConfigList;
 1588  0
         }
 1589  
     }
 1590  
 }