001// Generated by delombok at Sun Jul 30 17:21:56 UTC 2023 002package de.cuioss.test.jsf.config.decorator; 003 004import java.util.Collection; 005import java.util.Locale; 006import java.util.ResourceBundle; 007import javax.faces.application.Application; 008import javax.faces.application.ApplicationWrapper; 009import javax.faces.application.NavigationCase; 010import javax.faces.application.NavigationHandler; 011import javax.faces.application.ProjectStage; 012import javax.faces.context.ExternalContext; 013import javax.faces.context.FacesContext; 014import javax.servlet.http.HttpServletRequest; 015import org.apache.myfaces.test.config.ResourceBundleVarNames; 016import org.apache.myfaces.test.mock.MockApplication20; 017import org.apache.myfaces.test.mock.MockHttpServletRequest; 018import org.apache.myfaces.test.mock.MockServletContext; 019import de.cuioss.test.jsf.mocks.CuiMockConfigurableNavigationHandler; 020import de.cuioss.tools.reflect.FieldWrapper; 021 022/** 023 * Helper class acting as runtime-registry for {@link ResourceBundle}, 024 * {@link NavigationHandler}, 025 * 026 * @author Oliver Wolff 027 */ 028public class ApplicationConfigDecorator { 029 private final Application application; 030 private final FacesContext facesContext; 031 032 /** 033 * Registers a {@link ResourceBundle} to a given name 034 * 035 * @param bundleName the name of the bundle to be registered to 036 * @param bundlePath the path to the {@link ResourceBundle} 037 * @return the {@link ApplicationConfigDecorator} itself in order to enable a 038 * fluent-api style usage 039 */ 040 public ApplicationConfigDecorator registerResourceBundle(final String bundleName, final String bundlePath) { 041 ResourceBundleVarNames.addVarName(bundleName, bundlePath); 042 return this; 043 } 044 045 /** 046 * Registers the supported {@link Locale}s, see 047 * {@link Application#setSupportedLocales(Collection)} 048 * 049 * @param locales to be registered 050 * @return the {@link ApplicationConfigDecorator} itself in order to enable a 051 * fluent-api style usage 052 */ 053 public ApplicationConfigDecorator registerSupportedLocales(final Collection<Locale> locales) { 054 application.setSupportedLocales(locales); 055 return this; 056 } 057 058 /** 059 * Registers the default {@link Locale}, see 060 * {@link Application#setDefaultLocale(Locale)} 061 * 062 * @param locale to be registered 063 * @return the {@link ApplicationConfigDecorator} itself in order to enable a 064 * fluent-api style usage 065 */ 066 public ApplicationConfigDecorator registerDefaultLocale(final Locale locale) { 067 application.setDefaultLocale(locale); 068 return this; 069 } 070 071 /** 072 * Register a navigation case in a simple way, with two parameter only 073 * 074 * @param outcome to be registered 075 * @param toViewId to be registered 076 * @return the {@link ApplicationConfigDecorator} itself in order to enable a 077 * fluent-api style usage 078 */ 079 public ApplicationConfigDecorator registerNavigationCase(final String outcome, final String toViewId) { 080 getMockNavigationHandler().addNavigationCase(outcome, new NavigationCase(null, null, outcome, null, toViewId, null, null, true, true)); 081 return this; 082 } 083 084 /** 085 * @return an instance of {@link CuiMockConfigurableNavigationHandler} If not 086 * already configured this method will implicitly register a new 087 * instance 088 */ 089 public CuiMockConfigurableNavigationHandler getMockNavigationHandler() { 090 if (!(application.getNavigationHandler() instanceof CuiMockConfigurableNavigationHandler)) { 091 application.setNavigationHandler(new CuiMockConfigurableNavigationHandler()); 092 } 093 return (CuiMockConfigurableNavigationHandler) application.getNavigationHandler(); 094 } 095 096 /** 097 * Sets the {@link ProjectStage}. Caution: this method uses hardcore reflection 098 * to access the field with the name "_projectStage", may therefore be fragile. 099 * 100 * @param projectStage to be set 101 * @return the {@link ApplicationConfigDecorator} itself in order to enable a 102 * fluent-api style usage 103 */ 104 public ApplicationConfigDecorator setProjectStage(final ProjectStage projectStage) { 105 var projectStageField = FieldWrapper.from(MockApplication20.class, "_projectStage"); 106 if (projectStageField.isEmpty()) { 107 throw new IllegalStateException("Unable to set projectStage, due to underlying Exception"); 108 } 109 projectStageField.get().writeValue(getMockApplicationInstance(application), projectStage); 110 return this; 111 } 112 113 private static Object getMockApplicationInstance(final Application application) { 114 if (application instanceof MockApplication20) { 115 return application; 116 } 117 if (application instanceof ApplicationWrapper) { 118 return getMockApplicationInstance(((ApplicationWrapper) application).getWrapped()); 119 } 120 return application; 121 } 122 123 /** 124 * Sets the contextPath in {@link HttpServletRequest} 125 * 126 * @param contextPath to be set 127 * @return the {@link ApplicationConfigDecorator} itself in order to enable a 128 * fluent-api style usage 129 */ 130 public ApplicationConfigDecorator setContextPath(final String contextPath) { 131 ((MockHttpServletRequest) facesContext.getExternalContext().getRequest()).setContextPath(contextPath); 132 return this; 133 } 134 135 /** 136 * Registers a concrete InitParameter to 137 * {@link ExternalContext#getInitParameterMap()} 138 * 139 * @param key used as the key for the 140 * {@link ExternalContext#getInitParameterMap()} 141 * @param value used as the value for the 142 * {@link ExternalContext#getInitParameterMap()} 143 * @return the {@link ApplicationConfigDecorator} itself in order to enable a 144 * fluent-api style usage 145 */ 146 public ApplicationConfigDecorator addInitParameter(final String key, final String value) { 147 var context = (MockServletContext) facesContext.getExternalContext().getContext(); 148 context.addInitParameter(key, value); 149 return this; 150 } 151 152 @java.lang.SuppressWarnings("all") 153 @lombok.Generated 154 public ApplicationConfigDecorator(final Application application, final FacesContext facesContext) { 155 this.application = application; 156 this.facesContext = facesContext; 157 } 158}