All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.faces.application.InjectionApplicationFactory Maven / Gradle / Ivy

/*
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.faces.application;

import static com.sun.faces.util.Util.notNull;
import static java.text.MessageFormat.format;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.SEVERE;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.logging.Logger;

import com.sun.faces.util.FacesLogger;

import jakarta.faces.application.Application;
import jakarta.faces.application.ApplicationFactory;
import jakarta.faces.context.FacesContext;

/**
 * This {@link jakarta.faces.application.ApplicationFactory} is responsible for injecting the default
 * {@link Application} instance into the top-level {@link Application} as configured by the runtime. Doing this allows
 * us to preserve backwards compatibility as the API evolves without having the API rely on implementation specific
 * details.
 */
public class InjectionApplicationFactory extends ApplicationFactory {

    private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger();

    private Application defaultApplication;
    private Field defaultApplicationField;
    private volatile Application application;

    // ------------------------------------------------------------ Constructors

    public InjectionApplicationFactory(ApplicationFactory delegate) {
        super(delegate);
        notNull("applicationFactory", delegate);
    }

    // ----------------------------------------- Methods from ApplicationFactory

    @Override
    public Application getApplication() {

        if (application == null) {
            application = getWrapped().getApplication();

            if (application == null) {
                throw new IllegalStateException(
                        format("Delegate ApplicationContextFactory, {0}, returned null when calling getApplication().", getWrapped().getClass().getName()));
            }

            injectDefaultApplication();
        }

        return application;
    }

    @Override
    public synchronized void setApplication(Application application) {
        this.application = application;
        getWrapped().setApplication(application);
        injectDefaultApplication();
    }

    // --------------------------------------------------------- Private Methods

    private void injectDefaultApplication() {

        if (defaultApplication == null) {
            FacesContext ctx = FacesContext.getCurrentInstance();
            defaultApplication = InjectionApplicationFactory.removeApplicationInstance(ctx.getExternalContext().getApplicationMap());
        }

        if (defaultApplication != null) {
            try {
                if (defaultApplicationField == null) {
                    defaultApplicationField = Application.class.getDeclaredField("defaultApplication");
                    defaultApplicationField.setAccessible(true);
                }
                defaultApplicationField.set(application, defaultApplication);

            } catch (NoSuchFieldException nsfe) {
                if (LOGGER.isLoggable(FINE)) {
                    LOGGER.log(FINE, "Unable to find private field named 'defaultApplication' in jakarta.faces.application.Application.");
                }
            } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
                if (LOGGER.isLoggable(SEVERE)) {
                    LOGGER.log(SEVERE, e.toString(), e);
                }
            }
        }
    }

    // ------------------------------------------------- Package private Methods

    static void setApplicationInstance(Application app) {
        FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().put(InjectionApplicationFactory.class.getName(), app);
    }

    static Application removeApplicationInstance(Map appMap) {
        return (Application) appMap.remove(InjectionApplicationFactory.class.getName());
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy