/* * � Copyright IBM Corp. 2010, 2011 * * Licensed 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 com.ibm.xsp.extlib.component.layout; import java.util.List; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; import com.ibm.commons.util.StringUtil; import com.ibm.xsp.context.FacesContextEx; import com.ibm.xsp.extlib.stylekit.StyleKitExtLibDefault; import com.ibm.xsp.stylekit.ThemeControl; import com.ibm.xsp.util.DataPublisher; import com.ibm.xsp.util.DataPublisher.ShadowedObject; import com.ibm.xsp.util.FacesUtil; import com.ibm.xsp.util.StateHolderUtil; /** * Application Layout Component. */ public class UIApplicationLayout extends UIVarPublisherBase implements ThemeControl { private static final String CONFIGURATION_KEY = "_xsp.app.conf"; // $NON-NLS-1$ // // Configuration object management // /** * Find the application layout object in the hierarchy. */ public static ApplicationConfiguration findConfiguration(FacesContext context) { return (ApplicationConfiguration)context.getExternalContext().getRequestMap().get(CONFIGURATION_KEY); } public static final String COMPONENT_TYPE = "com.ibm.xsp.extlib.layout.ApplicationLayout"; //$NON-NLS-1$ public static final String COMPONENT_FAMILY = "com.ibm.xsp.extlib.layout.ApplicationLayout"; //$NON-NLS-1$ public static final String RENDERER_TYPE = "com.ibm.xsp.extlib.layout.OneUIApplicationLayout"; //$NON-NLS-1$ private ApplicationConfiguration configuration; private String onItemClick; public UIApplicationLayout() { setRendererType(RENDERER_TYPE); } public String getStyleKitFamily() { return StyleKitExtLibDefault.APPLICATION_LAYOUT; } @Override public void setParent(UIComponent parent) { super.setParent(parent); if( null == parent ){ // removing parent return; } // TODO should move this initialization to initBeforeContents instead FacesContextEx context = (FacesContextEx) getFacesContext(); if(null != context && !context.isRestoringState()) { ConversationState cs = ConversationState.get(context, FacesUtil.getViewRoot(this), true); // Initialize the conversation state // Set the current navigation path to the UserBean ApplicationConfiguration conf = findConfiguration(); if(conf!=null) { String navPath = conf.getNavigationPath(); if(StringUtil.isEmpty(navPath)) { // If there isn't a navigation path that is defined, the use the default one if(StringUtil.isEmpty(cs.getNavigationPath())) { navPath = conf.getDefaultNavigationPath(); } } if(StringUtil.isNotEmpty(navPath)) { cs.setNavigationPath(navPath); } } } } @Override public String getFamily() { return COMPONENT_FAMILY; } /** * @see DataPublisher#publishControlData(javax.faces.component.UIComponent) * @param context * @return */ @Override protected List<ShadowedObject> publishControlData(FacesContext context) { List<ShadowedObject> shadowedData = super.publishControlData(context); // publish the configuration under requestScope['_xsp.app.conf'] String variableName = CONFIGURATION_KEY; ApplicationConfiguration objectToPublish = getConfiguration(); DataPublisher dataPublisher = ((FacesContextEx)context).getDataPublisher(); if( null == shadowedData || shadowedData.isEmpty() ){ // note when isEmpty will be Collections.emptyList shadowedData = dataPublisher.createShadowedList(); } dataPublisher.pushObject(shadowedData, variableName, objectToPublish); return shadowedData; } /** * @see DataPublisher#revokeControlData(List, javax.faces.component.UIComponent) * @param shadowedData * @param context */ @Override protected void revokeControlData(List shadowedData, FacesContext context) { // pop the configuration from the shadowedData list super.revokeControlData(shadowedData, context); } public ApplicationConfiguration findConfiguration() { // We might look for a bean... return getConfiguration(); } public ApplicationConfiguration getConfiguration() { // note, this does not support value bindings, since 2011-sept-27 return configuration; } public void setConfiguration(ApplicationConfiguration configuration) { //In the twitter bootstrap theme, we provide more than one ApplicationLayout renderer //To allow that, we check here for a renderer type in the ApplicationConfiguration object //If a renderer type exists, we apply it as the chosen renderer //If no renderer type found, we don't set anything. The renderer is set in the .theme file // or in the rendererType property of the appLayout configuration this.configuration = configuration; String layoutRenderer = configuration.getLayoutRendererType(); String rendererType = this.getRendererType(); if(!StringUtil.equals(RENDERER_TYPE, rendererType)) { //Do nothing }else{ if(StringUtil.isNotEmpty(layoutRenderer)) { this.setRendererType(layoutRenderer); }else{ //Do nothing. No specialised renderer found in application configuration } } } public String getOnItemClick() { if (null != this.onItemClick) { return this.onItemClick; } ValueBinding vb = getValueBinding("onItemClick"); //$NON-NLS-1$ if (vb != null) { return (String) vb.getValue(getFacesContext()); } else { return null; } } public void setOnItemClick(String onItemClick) { this.onItemClick = onItemClick; } // ============================================================== // Access to the embedded components (facets) // ============================================================== public UIComponent getLeftColumn() { if(getFacetCount()>0) { return getFacet("LeftColumn"); // $NON-NLS-1$ } return null; } public UIComponent getRightColumn() { if(getFacetCount()>0) { return getFacet("RightColumn"); // $NON-NLS-1$ } return null; } public UIComponent getSearchBar() { if(getFacetCount()>0) { return getFacet("SearchBar"); // $NON-NLS-1$ } return null; } public UIComponent getPlaceBarName() { if(getFacetCount()>0) { return getFacet("PlaceBarName"); // $NON-NLS-1$ } return null; } public UIComponent getPlaceBarActions() { if(getFacetCount()>0) { return getFacet("PlaceBarActions"); // $NON-NLS-1$ } return null; } public UIComponent getMastHeader() { if(getFacetCount()>0) { return getFacet("MastHeader"); // $NON-NLS-1$ } return null; } public UIComponent getMastFooter() { if(getFacetCount()>0) { return getFacet("MastFooter"); // $NON-NLS-1$ } return null; } // // State management // @Override public void restoreState(FacesContext context, Object state) { Object values[] = (Object[]) state; super.restoreState(context, values[0]); this.configuration = (ApplicationConfiguration)StateHolderUtil.restoreObjectState(context, this, values[1]); this.onItemClick = (String)values[2]; } @Override public Object saveState(FacesContext context) { Object values[] = new Object[3]; values[0] = super.saveState(context); values[1] = StateHolderUtil.saveObjectState(context, configuration); values[2] = onItemClick; return values; } }