org.apache.myfaces.custom.tabbedpane.AbstractHtmlPanelTabbedPane Maven / Gradle / Ivy
/*
* 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.myfaces.custom.tabbedpane;
import java.util.Iterator;
import java.util.List;
import javax.faces.component.PartialStateHolder;
import javax.faces.component.StateHolder;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.component.UINamingContainer;
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.component.html.HtmlPanelGroup;
import javax.faces.context.FacesContext;
import javax.faces.el.EvaluationException;
import javax.faces.el.MethodBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseId;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
import org.apache.myfaces.component.AlignProperty;
import org.apache.myfaces.component.AttachedDeltaWrapper;
import org.apache.myfaces.component.DataProperties;
import org.apache.myfaces.component.EventAware;
import org.apache.myfaces.component.PanelProperties;
import org.apache.myfaces.component.UniversalProperties;
import org.apache.myfaces.component.UserRoleAware;
/**
* TODO: Document this component.
*
* Unless otherwise specified, all attributes accept static values or EL expressions.
*
* @JSFComponent
* name = "t:panelTabbedPane"
* class = "org.apache.myfaces.custom.tabbedpane.HtmlPanelTabbedPane"
* tagClass = "org.apache.myfaces.custom.tabbedpane.HtmlPanelTabbedPaneTag"
* tagHandler = "org.apache.myfaces.custom.tabbedpane.HtmlPanelTabbedPaneTagHandler"
*
* @author Manfred Geiler (latest modification by $Author: lu4242 $)
* @version $Revision: 745263 $ $Date: 2009-02-17 16:51:58 -0500 (mar, 17 feb 2009) $
*/
public abstract class AbstractHtmlPanelTabbedPane
extends HtmlPanelGroup
implements UniversalProperties, EventAware, PanelProperties,
AlignProperty, DataProperties, UserRoleAware, ClientBehaviorHolder
{
//private static final Log log = LogFactory.getLog(HtmlPanelTabbedPane.class);
public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlPanelTabbedPane";
public static final String COMPONENT_FAMILY = "javax.faces.Panel";
private static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.TabbedPane";
private static final int DEFAULT_SELECTEDINDEX = 0;
private static final boolean DEFAULT_SERVER_SIDE_TAB_SWITCH = false;
private MethodBinding _tabChangeListener = null;
private static final int DEFAULT_BORDER = Integer.MIN_VALUE;
public void decode(FacesContext context)
{
super.decode(context); //To change body of overridden methods use File | Settings | File Templates.
}
public void processDecodes(javax.faces.context.FacesContext context)
{
if (context == null) throw new NullPointerException("context");
decode(context);
int tabIdx = 0;
int selectedIndex = getSelectedIndex();
Iterator it = getFacetsAndChildren();
while (it.hasNext())
{
UIComponent childOrFacet = getUIComponent((UIComponent) it.next());
if (childOrFacet instanceof HtmlPanelTab) {
if (isClientSide() || selectedIndex == tabIdx) {
childOrFacet.processDecodes(context);
}
tabIdx++;
} else {
childOrFacet.processDecodes(context);
}
}
}
public void processValidators(FacesContext context)
{
if (context == null) throw new NullPointerException("context");
if (!isRendered()) return;
int tabIdx = 0;
int selectedIndex = getSelectedIndex();
Iterator it = getFacetsAndChildren();
while (it.hasNext())
{
UIComponent childOrFacet = getUIComponent((UIComponent) it.next());
if (childOrFacet instanceof HtmlPanelTab) {
if (isClientSide() || selectedIndex == tabIdx) {
childOrFacet.processValidators(context);
}
tabIdx++;
} else {
childOrFacet.processValidators(context);
}
}
}
public void processUpdates(FacesContext context)
{
if (context == null) throw new NullPointerException("context");
if (!isRendered()) return;
int tabIdx = 0;
int selectedIndex = getSelectedIndex();
Iterator it = getFacetsAndChildren();
while (it.hasNext())
{
UIComponent childOrFacet = getUIComponent((UIComponent) it.next());
if (childOrFacet instanceof HtmlPanelTab) {
if (isClientSide() || selectedIndex == tabIdx) {
childOrFacet.processUpdates(context);
}
tabIdx++;
} else {
childOrFacet.processUpdates(context);
}
}
}
private UIComponent getUIComponent(UIComponent uiComponent)
{
/*todo: checking for UIForm is not enough - Trinidad form, etc.*/
if (uiComponent instanceof UINamingContainer || uiComponent instanceof UIForm)
{
List children = uiComponent.getChildren();
for (int i = 0, len = children.size(); i < len; i++)
{
uiComponent = getUIComponent((UIComponent)children.get(i));
}
}
return uiComponent;
}
public void addTabChangeListener(TabChangeListener listener)
{
addFacesListener(listener);
}
public void removeTabChangeListener(TabChangeListener listener)
{
removeFacesListener(listener);
}
/**
* TODO: This should be something like this:
*
* JSFProperty
* returnSignature = "void"
* methodSignature = "org.apache.myfaces.custom.tabbedpane.TabChangeEvent"
*
* And be added on tld. But you can do the same with TabChangeListenerTag.
*
* @return
*/
public MethodBinding getTabChangeListener()
{
return _tabChangeListener;
}
private boolean _isSetTabChangeListener()
{
Boolean value = (Boolean) getStateHelper().get(PropertyKeys.tabChangeListenerSet);
return value == null ? false : value;
}
public void setTabChangeListener(MethodBinding tabChangeListener)
{
_tabChangeListener = tabChangeListener;
}
public Object saveState(FacesContext facesContext)
{
if (initialStateMarked())
{
boolean nullDelta = true;
Object parentSaved = super.saveState(facesContext);
Object tabChangeListenerSaved = null;
if (!_isSetTabChangeListener() &&
_tabChangeListener != null && _tabChangeListener instanceof PartialStateHolder)
{
//Delta
StateHolder holder = (StateHolder) _tabChangeListener;
if (!holder.isTransient())
{
Object attachedState = holder.saveState(facesContext);
if (attachedState != null)
{
nullDelta = false;
}
tabChangeListenerSaved = new AttachedDeltaWrapper(_tabChangeListener.getClass(),
attachedState);
}
}
else if (_isSetTabChangeListener() || _tabChangeListener != null)
{
//Full
tabChangeListenerSaved = saveAttachedState(facesContext,_tabChangeListener);
nullDelta = false;
}
if (parentSaved == null && nullDelta)
{
//No values
return null;
}
Object[] values = new Object[2];
values[0] = parentSaved;
values[1] = tabChangeListenerSaved;
return values;
}
else
{
Object[] values = new Object[2];
values[0] = super.saveState(facesContext);
values[1] = saveAttachedState(facesContext,_tabChangeListener);
return values;
}
}
public void restoreState(FacesContext facesContext, Object state)
{
if (state == null)
{
return;
}
Object[] values = (Object[])state;
super.restoreState(facesContext,values[0]);
if (values[1] instanceof AttachedDeltaWrapper)
{
//Delta
((StateHolder)_tabChangeListener).restoreState(facesContext, ((AttachedDeltaWrapper) values[1]).getWrappedStateObject());
}
else
{
//Full
_tabChangeListener = (javax.faces.el.MethodBinding) restoreAttachedState(facesContext,values[1]);
}
}
public void broadcast(FacesEvent event) throws AbortProcessingException
{
if (event instanceof TabChangeEvent)
{
TabChangeEvent tabChangeEvent = (TabChangeEvent)event;
if (tabChangeEvent.getComponent() == this)
{
setSelectedIndex(tabChangeEvent.getNewTabIndex());
getFacesContext().renderResponse();
}
}
super.broadcast(event);
MethodBinding tabChangeListenerBinding = getTabChangeListener();
if (tabChangeListenerBinding != null)
{
try
{
tabChangeListenerBinding.invoke(getFacesContext(), new Object[]{event});
}
catch (EvaluationException e)
{
Throwable cause = e.getCause();
if (cause != null && cause instanceof AbortProcessingException)
{
throw (AbortProcessingException)cause;
}
else
{
throw e;
}
}
}
}
/**
* Write out information about the toggling mode - the component might
* be toggled server side or client side.
*/
public boolean isClientSide()
{
return !isServerSideTabSwitch();
}
/**
*
*/
@JSFProperty(
tagExcluded = true)
public abstract String getActiveTabVar();
/**
* Boolean Variable that is set in request scope when
* rendering a panelTab. True means that the currently
* rendered panelTab is active.
*
*/
@JSFProperty
public abstract Boolean getActivePanelTabVar();
/**
* Index of tab that is selected by default.
*
*/
@JSFProperty(
defaultValue = "0")
public abstract int getSelectedIndex();
public abstract void setSelectedIndex(int selectedIndex);
/**
* Style class of the active tab cell.
*
*/
@JSFProperty
public abstract String getActiveTabStyleClass();
/**
* Style class of the inactive tab cells.
*
*/
@JSFProperty
public abstract String getInactiveTabStyleClass();
/**
* Style class of the active tab sub cell.
*
*/
@JSFProperty
public abstract String getActiveSubStyleClass();
/**
* Style class of the inactive tab sub cells.
*
*/
@JSFProperty
public abstract String getInactiveSubStyleClass();
/**
* Style class of the active tab content cell.
*
*/
@JSFProperty
public abstract String getTabContentStyleClass();
/**
* Style class of the disabled tab cells.
*
*/
@JSFProperty
public abstract String getDisabledTabStyleClass();
/**
* Toggle client-side/server-side tab switches.
*
*/
@JSFProperty(
defaultValue = "false")
public abstract boolean isServerSideTabSwitch();
public boolean getServerSideTabSwitch()
{
return isServerSideTabSwitch();
}
/**
* Define if the process validation and update model phases
* should be executed before change between tabs, when
* serverSideTabSwitch = true (if is false, the switch
* is done by other way so this property does not have any
* effect).
*
* Note that if this property is set as false, only a tab
* change is done if all input fields inside the form are valid
* (including input components outside this panel).
*
* By default is true, so both phases are not executed.
*
*/
@JSFProperty(
defaultValue = "true")
public abstract boolean isImmediateTabChange();
public void queueEvent(FacesEvent event)
{
if (event != null && event instanceof TabChangeEvent)
{
if (isImmediateTabChange())
{
event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
}
else
{
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
}
}
super.queueEvent(event);
}
enum PropertyKeys
{
tabChangeListenerSet
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy