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

org.apache.empire.jsf2.app.FacesConfiguration Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.empire.jsf2.app;

import java.util.Iterator;

import javax.el.ELResolver;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ProjectStage;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.event.PhaseListener;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.faces.render.Renderer;
import javax.servlet.ServletContext;

import org.apache.empire.commons.ClassUtils;
import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.InvalidOperationException;
import org.apache.empire.exceptions.ItemExistsException;
import org.apache.empire.exceptions.ItemNotFoundException;
import org.apache.empire.exceptions.ObjectNotValidException;
import org.apache.empire.jsf2.impl.FacesImplementation;
import org.apache.empire.jsf2.impl.FacesImplementation.BeanStorageProvider;
import org.apache.empire.jsf2.pages.PageNavigationHandler;
import org.apache.empire.jsf2.pages.PagePhaseListener;
import org.apache.empire.jsf2.pages.PagesELResolver;
import org.apache.empire.jsf2.utils.BeanScope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * FacesConfiguration
 * Allows programmatic Faces configuration as an alternative to the faces-config.xml
 * In order to provide custom configuration you must override the class WebAppStartupListener
 * and put it in the faces-config.xml
 * 
 
 *   <system-event-listener-class>de.volkswagen.jsf.FacesStartupListener</system-event-listener-class>
 * 
* Further you must call the super constructor with a FacesConfiguration class like this: *
 *   public FacesStartupListener()
 *   {
 *      super(FacesExtensions.class);
 *   }
 * 
*/ public class FacesConfiguration { protected static final Logger log = LoggerFactory.getLogger(FacesConfiguration.class); public final static String EMPIRE_COMPONENT_FAMILY = "org.apache.empire.component"; /* * Initialized */ private static boolean initialized = false; public static boolean isInitialized() { return initialized; } /* * Project Stage * see org.apache.myfaces.application.ApplicationImpl * How to set: * set JVM-Parameter: "org.apache.myfaces.PROJECT_STAGE" * set JNDI-Parameter: "java:comp/env/jsf/ProjectStage" * set in web.inf: * * javax.faces.PROJECT_STAGE * Development * */ private static ProjectStage projectStage; public static ProjectStage getProjectStage() { if (projectStage==null) throw new ObjectNotValidException(FacesConfiguration.class, "Not Initialized"); return projectStage; } /** * Static Initializer * @param configClass the configuration class * @param startupContext the startupContext * @param facesImpl the Faces implementation */ public static void initialize(Class configClass, FacesContext startupContext, FacesImplementation facesImpl) { // crate and initialize FacesConfiguration fConfig = ClassUtils.newInstance(configClass, FacesImplementation.class, facesImpl); fConfig.initialize(startupContext); } /* * Inject */ protected final FacesImplementation facesImpl; /* * Temp Variables */ protected ExternalContext externalContext; protected Application application; /* * Lazy */ private BeanStorageProvider beanStorage; // call getBeanStorageProvider() public FacesConfiguration(FacesImplementation facesImpl) { this.facesImpl = facesImpl; } public final void initialize(FacesContext startupContext) { if (initialized) throw new InvalidOperationException("FacesConfiguration already initialized!"); try { // Set temporary variables this.externalContext = startupContext.getExternalContext(); this.application = startupContext.getApplication(); this.beanStorage = null; projectStage = application.getProjectStage(); log.info("Initializing Faces Configuration for ProjectStage {}", projectStage.name()); // Init everything initAll(startupContext); // done log.info("Faces Configuration complete."); } finally { // cleanup this.beanStorage = null; this.application = null; this.externalContext = null; this.facesImpl.configComplete(); // set initialized (even if Exception has been thrown) initialized = true; } } /* * Overrideable methods */ protected void initAll(FacesContext context) { log.debug("Init FacesParams..."); initFacesParams(); log.debug("Init Factories..."); initFactories(); log.debug("Init NavigationHandler..."); initNavigationHandler(); log.debug("Init ResourceHandler..."); initResourceHandler(); log.debug("Registrating Converters..."); initConverters(); log.debug("Registrating EL-Resolvers..."); initElResolvers(); log.debug("Registrating Lifecycle..."); initLifecycle(new LifecycleUpdater()); log.debug("Registrating Search Expression Resolvers..."); initSearchExpressionResolvers(); log.debug("Registrating Components..."); initComponents(); log.debug("Registrating Renderers..."); initRenderers(new RenderKitUpdater(getApplicationRenderKit(context))); log.debug("Registrating Managed Beans..."); initManagedBeans(); log.debug("Registrating Controls..."); initControls(); } protected void initFacesParams() { // set params setFacesInitParam(ViewHandler.FACELETS_SKIP_COMMENTS_PARAM_NAME, true); } protected void initFactories() { // Noting yet /* example * log.info("Setting Factory {}", FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY); FactoryFinder.setFactory(FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY, CustomTagHandlerDelegateFactory.class.getName()); // (check) // TagHandlerDelegateFactory tagHandlerFactory = (TagHandlerDelegateFactory)FactoryFinder.getFactory(FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY); // log.info(tagHandlerFactory.getClass().getName()); */ } protected void initNavigationHandler() { NavigationHandler wrapped = application.getNavigationHandler(); if (wrapped instanceof PageNavigationHandler) return; // Already set // replace log.info("Setting NavigationHandler to {}", PageNavigationHandler.class.getName()); application.setNavigationHandler(new PageNavigationHandler(wrapped)); } protected void initResourceHandler() { // Not implemented // application.setResourceHandler(new MyResourceHandler(wrapped)); } protected void initConverters() { // Noting } protected void initElResolvers() { // add addELResolver(DBELResolver.class); addELResolver(PagesELResolver.class); } protected void initLifecycle(LifecycleUpdater lcu) { lcu.addPhaseListener(FacesRequestPhaseListener.class); lcu.addPhaseListener(PagePhaseListener.class); } protected void initSearchExpressionResolvers() { // Nothing // SearchExpressionResolverFactory.registerResolver("@fragment", new FragmentExpressionResolver()); } protected void initComponents() { // Empire Components addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.ControlTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.InputTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.FormGridTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.LabelTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.LinkTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.MenuItemTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.MenuListTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.RecordTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.SelectTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.TabPageTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.TabViewTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.TitleTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.UnitTag.class); addComponent(EMPIRE_COMPONENT_FAMILY, org.apache.empire.jsf2.components.ValueTag.class); } protected void initRenderers(RenderKitUpdater rku) { // Noting // rku.replace("javax.faces.Input", "javax.faces.Text", FacesTextInputRenderer.class); } protected void initManagedBeans() { // Nothing // addManagedBean(ConfirmPopup.MANAGED_BEAN_NAME, ConfirmPopup.class, ConfirmPopup.MANAGED_BEAN_SCOPE); } protected void initControls() { // Not implemented // InputControlManager.registerControl(new CustomCheckboxInputControl()); } /* * Helpers */ protected BeanStorageProvider getBeanStorageProvider() { if (this.beanStorage==null) this.beanStorage = facesImpl.getBeanStorageProvider(externalContext); return this.beanStorage; } protected RenderKit getApplicationRenderKit(FacesContext context) { String renderKitId = StringUtils.coalesce(application.getDefaultRenderKitId(), RenderKitFactory.HTML_BASIC_RENDER_KIT); return ((RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY)).getRenderKit(context, renderKitId); } protected void setFacesInitParam(String paramName, Object paramValue, boolean overwriteExisting) { if (StringUtils.isEmpty(paramName)) throw new InvalidArgumentException("paramName", paramName); // special case if (ProjectStage.PROJECT_STAGE_PARAM_NAME.equals(paramName)) throw new InvalidOperationException(ProjectStage.PROJECT_STAGE_PARAM_NAME+" cannot be changed!"); // get map ServletContext sc = (ServletContext)this.externalContext.getContext(); String paramVal = StringUtils.toString(paramValue); String orgValue = sc.getInitParameter(paramName); if (ObjectUtils.compareEqual(paramVal, orgValue)) return; // No change if (ObjectUtils.isNotEmpty(orgValue) && !overwriteExisting) { // Ingnore log.info("Ignoring FacesParam \"{}\" (\"{}\"). Keeping current value of \"{}\"", paramName, paramVal, orgValue); return; } if (orgValue!=null) log.info("Setting FacesParam \"{}\" to \"{}\". Original value was \"{}\"", paramName, paramVal, orgValue); else log.info("Setting FacesParam \"{}\" to \"{}\".", paramName, paramVal); // add to map sc.setInitParameter(paramName, paramVal); } protected void setFacesInitParam(String paramName, Object paramValue) { setFacesInitParam(paramName, paramValue, false); } protected void setFacesInitParam(Enum paramName, Object paramValue) { setFacesInitParam(paramName.toString(), paramValue, false); } protected void addConverter(Class targetClass, Class converterClass) { log.info("Adding Type-Converter for type \"{}\" using {}", targetClass.getName(), converterClass.getName()); application.addConverter(targetClass, converterClass.getName()); } protected void addComponent(String componentFamily, Class clazz) { String type = StringUtils.concat(componentFamily, ".", clazz.getSimpleName()); log.info("Adding component type \"{}\" using {}", type, clazz.getName()); application.addComponent(type, clazz.getName()); } protected void addManagedBean(String beanName, Class beanClass, BeanScope beanScope) { String scope = beanScope.name().toLowerCase(); facesImpl.registerManagedBean(beanName, beanClass.getName(), scope); } protected void addManagedBean(Class beanClass, BeanScope scope) { // check if (beanClass==null || scope==null) throw new InvalidArgumentException("beanClass|scope", null); // detect name String className = beanClass.getName(); int nameIndex = className.lastIndexOf('.')+1; String beanName = className.substring(nameIndex, nameIndex+1).toLowerCase() + className.substring(nameIndex+1); // register now addManagedBean(beanName, beanClass, scope); } protected void replaceComponent(String componentType, Class overrideComponent) { if (StringUtils.isEmpty(componentType)) throw new InvalidArgumentException("componentType", componentType); // check checkComponentTypeExists(componentType); log.info("Replacing component type \"{}\" with {}", componentType, overrideComponent.getName()); application.addComponent(componentType, overrideComponent.getName()); } protected void replaceComponent(Class componentClassWithType, Class overrideComponent) { String componentType = (String) ClassUtils.getFieldValue(componentClassWithType, null, "COMPONENT_TYPE", true); replaceComponent(componentType, overrideComponent); } protected void replaceComponent(String componentFamily, Class componentClassToReplace, Class overrideComponent) { String componentType = StringUtils.concat(componentFamily, ".", componentClassToReplace.getSimpleName()); replaceComponent(componentType, overrideComponent); } protected void checkComponentTypeExists(String componentType) { Iterator types = application.getComponentTypes(); while (types.hasNext()) { String type = types.next(); if (componentType.equals(type)) return; // found; } throw new ItemNotFoundException("Component-Type: "+componentType); } protected void addELResolver(Class resolverClass) { boolean added = facesImpl.registerElResolver(resolverClass); if (added) log.info("Adding FacesConfigElResolver {}", resolverClass.getName()); } /* * list */ protected void listCompoennts() { ConfigTypeList list = new ConfigTypeList("Component-Types"); Iterator types = application.getComponentTypes(); while (types.hasNext()) { String componentType = types.next(); // log.info("Renderer-Family: {} Type {}", componentFamily, rendererType); list.addItem(componentType); } log.info(list.toString()); } /** * RenderKitReplacer * @author doebele */ protected class RenderKitUpdater { private final RenderKit renderKit; public RenderKitUpdater(RenderKit renderKit) { this.renderKit = renderKit; } public RenderKit getRenderKit() { return renderKit; } public void listAll() { // list all ConfigTypeList list = new ConfigTypeList("Renderer-Types"); Iterator families = renderKit.getComponentFamilies(); while (families.hasNext()) { String componentFamily = families.next(); Iterator types = renderKit.getRendererTypes(componentFamily); while (types.hasNext()) { String rendererType = types.next(); // log.info("Renderer-Family: {} Type {}", componentFamily, rendererType); list.addItem(componentFamily, rendererType); } } log.info(list.toString()); } public void add(String componentFamily, String rendererType, Class rendererClass) { Renderer check = findRenderer(componentFamily, rendererType); if (check!=null) { if (check.getClass().equals(rendererClass)) return; // already there // Another renderer exists throw new ItemExistsException(StringUtils.concat(componentFamily, " / ", rendererType)); } // add log.info("Adding Renderer type \"{}\" using {}", rendererType, rendererClass.getName()); renderKit.addRenderer(componentFamily, rendererType, ClassUtils.newInstance(rendererClass)); } public void replace(String componentFamily, String rendererType, Class replaceClass) { // checkRenderTypeExists(componentFamily, rendererType); Renderer check = findRenderer(componentFamily, rendererType); if (check==null) throw new ItemNotFoundException(StringUtils.concat(componentFamily, " / ", rendererType)); if (check.getClass().equals(replaceClass)) return; // Already replaced // replace log.info("Replacing Renderer type \"{}\" with class {}", rendererType, replaceClass.getName()); renderKit.addRenderer(componentFamily, rendererType, ClassUtils.newInstance(replaceClass)); } /* public void replace(Class orgClass, Class replaceClass) { String name = orgClass.getName(); int sep = name.lastIndexOf('.'); replace(name.substring(0, sep), name.substring(sep+1), replaceClass); } */ private Renderer findRenderer(String componentFamily, String rendererType) { // list all Iterator families = renderKit.getComponentFamilies(); while (families.hasNext()) { String family = families.next(); if (componentFamily.equals(family)) { Iterator types = renderKit.getRendererTypes(family); while (types.hasNext()) { String type = types.next(); if (rendererType.equals(type)) return renderKit.getRenderer(componentFamily, rendererType); // found } } } return null; } } /** * LifecycleUpdater * @author doebele */ protected class LifecycleUpdater { private final Lifecycle lifecycle; private PhaseListener[] phaseListeners; public LifecycleUpdater() { // The DEFAULT Lifecycle LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); this.lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE); this.phaseListeners = lifecycle.getPhaseListeners(); } public void listAll() { ConfigTypeList list = new ConfigTypeList("Phase-Listeners"); this.phaseListeners = lifecycle.getPhaseListeners(); for (PhaseListener pl : phaseListeners) { list.addItem(pl.getClass(), pl.getPhaseId()); } log.info(list.toString()); } public void addPhaseListener(Class phaseListenerClass) { for (PhaseListener pl : phaseListeners) { if (pl.getClass().equals(phaseListenerClass)) return; // already there } // Not found: Create and Append log.info("Adding Lifecycle PhaseListener {}", phaseListenerClass.getName()); PhaseListener listener = ClassUtils.newInstance(phaseListenerClass); // Add to bean storage getBeanStorageProvider().injectBean(listener); // Add to lifecycle lifecycle.addPhaseListener(listener); // refresh // this.phaseListeners = lifecycle.getPhaseListeners(); } } /** * ConfigTypeList * @author doebele */ protected static class ConfigTypeList { private static final String CRLF = "\r\n"; private static final String TAB = "\t"; private final StringBuilder b; public ConfigTypeList(String listName) { this.b = new StringBuilder(200); b.append(listName); b.append(":"); b.append(CRLF); } public void addItem(Object item, Object... more) { b.append(TAB); b.append(toString(item)); for (int i=0; i) return ((Class)o).getName(); if (o instanceof Enum) return ((Enum)o).name(); return String.valueOf(o); } @Override public String toString() { return this.b.toString(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy