You are viewing a plain text version of this content. The canonical link for it is here.
Posted to adffaces-commits@incubator.apache.org by sl...@apache.org on 2006/10/01 17:26:57 UTC
svn commit: r451772 [1/8] - in /incubator/adffaces/trunk/trinidad:
src/site/xdoc/
trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/desktop/
trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xht...
Author: slessard
Date: Sun Oct 1 10:26:55 2006
New Revision: 451772
URL: http://svn.apache.org/viewvc?view=rev&rev=451772
Log:
Applied patch for ADFFACES-60 with some small changes to compile with the new public rendering API.
Modified:
incubator/adffaces/trunk/trinidad/src/site/xdoc/skin-selectors.xml
incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/desktop/TrainRenderer.java
incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinProperties.java
incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinSelectors.java
incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/resources/META-INF/adf/styles/base-desktop.xss
incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/resources/META-INF/adf/styles/minimal-desktop.xss
incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/renderkit/golden/train-minimal-golden.xml
incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/renderkit/golden/train-minimalIE-golden.xml
incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/renderkit/golden/train-minimalIERtl-golden.xml
incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/renderkit/golden/train-minimalInacc-golden.xml
incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/renderkit/golden/train-minimalSaf-golden.xml
incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resources/org/apache/myfaces/trinidadinternal/renderkit/golden/train-minimalScrRdr-golden.xml
Modified: incubator/adffaces/trunk/trinidad/src/site/xdoc/skin-selectors.xml
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/src/site/xdoc/skin-selectors.xml?view=diff&rev=451772&r1=451771&r2=451772
==============================================================================
--- incubator/adffaces/trunk/trinidad/src/site/xdoc/skin-selectors.xml (original)
+++ incubator/adffaces/trunk/trinidad/src/site/xdoc/skin-selectors.xml Sun Oct 1 10:26:55 2006
@@ -2954,7 +2954,52 @@
</tr>
</table>
</subsection>
- <subsection name="tr:processTrain Component">
+ <subsection name="tr:train Component">
+ <table>
+ <tr>
+ <th colspan="2">
+ <i>Properties</i>
+ </th>
+ </tr>
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>-ora-render-parent-train</td>
+ <td>Boolean value that specifies if parent train icons should be
+ rendered if this train is a sub-train. A sub-train is a process
+ not located at the root of its TreeModel.</td>
+ </tr>
+ <tr>
+ <td>-ora-visible-stop-count</td>
+ <td>Strictly positive integer value specifying the maximum amount of
+ stops visible at a time.</td>
+ </tr>
+ </table>
+ <table>
+ <tr>
+ <th colspan="2">
+ <i>Aliases</i>
+ </th>
+ </tr>
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>.AFTrainContent:alias</td>
+ <td>Styles all train station content.</td>
+ </tr>
+ <tr>
+ <td>.AFTrainIconCell:alias</td>
+ <td>Styles all train station icons.</td>
+ </tr>
+ <tr>
+ <td>.AFTrainJoin:alias</td>
+ <td>Styles all train station joins.</td>
+ </tr>
+ </table>
<table>
<tr>
<th colspan="2">
@@ -2966,33 +3011,215 @@
<th>Description</th>
</tr>
<tr>
- <td>af|processTrain::step-active</td>
- <td>Styles the active train station.</td>
+ <td>af|train</td>
+ <td>Styles the whole train.</td>
+ </tr>
+ <tr>
+ <td>af|train::stop</td>
+ <td>Styles a train stop. A stop include both the icon and its content.
+ This selector is often combined with one or more station pseudo-classes like
+ :selected, :unvisited, :disabled, :read-only and .p_AFVisited and
+ used in descendant selector, e.g. "af|train::stop:unvisited af|train::link"
+ would style the link generated for an unvisited stop.</td>
+ </tr>
+ <tr>
+ <td>af|train::stop-icon-cell</td>
+ <td>Styles the icon section of the stop. This selector is combinable
+ with state pseudo-classes. This selector includes .AFTrainIconCell:alias.
+ </td>
</tr>
<tr>
- <td>af|processTrain::step-visited</td>
- <td>Styles the visited train stations.</td>
+ <td>af|train::stop-content</td>
+ <td>Styles the content section of the stop. This selector is combinable
+ with state pseudo-classes. This selector includes .AFTrainContent:alias.
+ </td>
</tr>
<tr>
- <td>af|processTrain::step-disabled</td>
- <td>Styles the disabled train stations.</td>
+ <td>af|train::join</td>
+ <td>Styles the join between stop icons. This selector is combinable with state
+ pseudo-classes, except :selected. This selector includes .AFTrainJoin:alias.
+ </td>
</tr>
<tr>
- <td>af|processTrain::step-unvisited</td>
- <td>Styles the unvisited train stations.</td>
+ <td>af|train::overflow-start</td>
+ <td>Styles a train start overflow. A start overflow is generated when the amount
+ of steps in the process is higher than the amount of visibled stop defined by
+ the -ora-visible-stop-count property. In LTR mode, this selector represents
+ the left side overflow (previous step group). This selector includes both the
+ icon and its content. This selector is combinable with state pseudo-classes.</td>
</tr>
<tr>
- <td>.AFTrainStation:alias</td>
- <td>Style that is included by all of the af|processTrain* style
- classes.</td>
+ <td>af|train::overflow-start-icon-cell</td>
+ <td>Styles the icon section of the overflow-start. This selector is combinable
+ with state pseudo-classes. This selector includes .AFTrainIconCell:alias.
+ </td>
</tr>
<tr>
- <td>af|processTrain::step-visited af|processTrain:: link</td>
- <td>Styles the visited train stations links.</td>
+ <td>af|train::overflow-start-content</td>
+ <td>Styles the content section of the overflow-start. This selector is combinable
+ with state pseudo-classes. This selector includes .AFTrainContent:alias.
+ </td>
+ </tr>
+ <tr>
+ <td>af|train::overflow-end</td>
+ <td>Styles a train end overflow. A end overflow is generated when the amount
+ of steps in the process is higher than the amount of visibled stop defined by
+ the -ora-visible-stop-count property. In LTR mode, this selector represents
+ the right side overflow (next step group). This selector includes both the
+ icon and its content. This selector is combinable with state pseudo-classes.</td>
+ </tr>
+ <tr>
+ <td>af|train::overflow-end-icon-cell</td>
+ <td>Styles the icon section of the overflow-end. This selector is combinable
+ with state pseudo-classes. This selector includes .AFTrainIconCell:alias.
+ </td>
+ </tr>
+ <tr>
+ <td>af|train::overflow-end-content</td>
+ <td>Styles the content section of the overflow-end. This selector is combinable
+ with state pseudo-classes. This selector includes .AFTrainContent:alias.
+ </td>
+ </tr>
+ <tr>
+ <td>af|train::join-overflow</td>
+ <td>Styles the join between overflows and stop icons. This selector is combinable
+ with state pseudo-classes, except :selected. This selector includes
+ .AFTrainJoin:alias.</td>
+ </tr>
+ <tr>
+ <td>af|train::parent-start</td>
+ <td>Styles a train start parent. A parent is generated when the current train is
+ not located at the root of its TreeModel and that -ora-render-parent-train
+ property is set to true. In LTR mode this will be rendered to the left of the
+ first step's stop. This selector includes both the icon and its content.
+ This selector is NOT combinable with state pseudo-classes.</td>
+ </tr>
+ <tr>
+ <td>af|train::parent-start-icon-cell</td>
+ <td>Styles the icon section of the parent-start. This selector is NOT combinable
+ with state pseudo-classes. This selector includes .AFTrainIconCell:alias.
+ </td>
+ </tr>
+ <tr>
+ <td>af|train::parent-start-content</td>
+ <td>Styles the content section of the parent-start. This selector is NOT combinable
+ with state pseudo-classes. This selector includes .AFTrainContent:alias.
+ </td>
+ </tr>
+ <tr>
+ <td>af|train::parent-end</td>
+ <td>Styles a train end parent. A parent is generated when the current train is
+ not located at the root of its TreeModel and that -ora-render-parent-train
+ property is set to true. In LTR mode this will be rendered to the right of
+ the last step's stop. This selector includes both the icon and its content.
+ This selector is NOT combinable with state pseudo-classes.</td>
+ </tr>
+ <tr>
+ <td>af|train::parent-end-icon-cell</td>
+ <td>Styles the icon section of the parent-end. This selector is NOT combinable
+ with state pseudo-classes. This selector includes .AFTrainIconCell:alias.
+ </td>
+ </tr>
+ <tr>
+ <td>af|train::parent-end-content</td>
+ <td>Styles the content section of the parent-end. This selector is NOT combinable
+ with state pseudo-classes. This selector includes .AFTrainContent:alias.
+ </td>
+ </tr>
+ <tr>
+ <td>af|train::join-parent</td>
+ <td>Styles the join between parent and stop icons. This selector is NOT combinable
+ with state pseudo-classes. This selector includes .AFTrainJoin:alias.</td>
+ </tr>
+ <tr>
+ <td>af|train::link</td>
+ <td>Styles the links generated within the stop's content. This selector is
+ NOT combinable with state pseudo-classes</td>
+ </tr>
+ </table>
+ <table>
+ <tr>
+ <th colspan="2">
+ <i>Icons</i>
+ </th>
+ </tr>
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
</tr>
<tr>
- <td>af|processTrain::step-unvisited af|processTrain::link</td>
- <td>Styles the unvisited train stations links.</td>
+ <td colspan="2">
+ Stop and overflow icons are combinable with one or more state pseudo-classes.
+ For example, it's possible to build icons for a very specific situations like
+ a read-only visited stop being different from a read-only unvisited stop. The
+ valid classes are:
+ <ul>
+ <li>:visited for steps that were already completed (assumed to be all steps
+ before the current one, this might change in the future);</li>
+ <li>:selected for the current step. This state is not available to overflows;
+ </li>
+ <li>:unvisited for steps that were not completed by the user (assumed to be
+ all steps after the current one, this might change in the future);</li>
+ <li>:read-only for steps that cannot be accessed directly by the user by
+ clicking on the link (clicking on the icon is not implemented at this
+ time). This state is combinable with any of the previous three states,
+ but must be placed after them, e.g. :selected:read-only-icon is valid,
+ while :read-only:selected is not;</li>
+ <li>:disabled for steps that cannot be accessed by the user using the link
+ and should theorically not be accessible at all until some condition is
+ met. This state has absolute priority and is not combinable with any other
+ state.</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>af|train::stop<states>-icon</td>
+ <td>Define the icons for stops. At least one state must be specified.
+ For example:
+ <ul>
+ <li>VALID: af|train::stop:selected-icon;</li>
+ <li>INVALID: af|train::stop-icon;</li>
+ </ul></td>
+ </tr>
+ <tr>
+ <td>af|train::overflow-start<states>-icon</td>
+ <td>Define the icons for overflows toward the previous step group. At least one
+ state must be specified.
+ For example:
+ <ul>
+ <li>VALID: af|train::overflow-start:read-only-icon;</li>
+ <li>INVALID: af|train::overflow-start-icon;</li>
+ </ul></td>
+ </tr>
+ <tr>
+ <td>af|train::overflow-end<states>-icon</td>
+ <td>Define the icons for overflows toward the next step group. At least one
+ state must be specified.
+ For example:
+ <ul>
+ <li>VALID: af|train::overflow-end:read-only-icon;</li>
+ <li>INVALID: af|train::overflow-end-icon;</li>
+ </ul></td>
+ </tr>
+ <tr>
+ <td>af|train::parent-start<states>-icon</td>
+ <td>Define the icons for the parent train that include this train.
+ It appears before the first stop's icon. This icon is NOT
+ combinable with state pseudo-classes. For example:
+ <ul>
+ <li>VALID: af|train::parent-start-icon;</li>
+ <li>INVALID: af|train::parent-start:read-only-icon;</li>
+ </ul></td>
+ </tr>
+ <tr>
+ <td>af|train::parent-end<states>-icon</td>
+ <td>Define the icons for the parent train that follow the parent train
+ including this train. It appears after the last stop's icon. This
+ icon is NOT combinable with state pseudo-classes. For example:
+ <ul>
+ <li>VALID: af|train::parent-end-icon;</li>
+ <li>INVALID: af|train::parent-end:read-only-icon;</li>
+ </ul></td>
</tr>
</table>
</subsection>
@@ -3119,7 +3346,7 @@
</tr>
</table>
</subsection>
- <subsection name="tr:selectInputDate Component">
+ <subsection name="tr:inputDate Component">
<table>
<tr>
<th colspan="2">
Modified: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/desktop/TrainRenderer.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/desktop/TrainRenderer.java?view=diff&rev=451772&r1=451771&r2=451772
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/desktop/TrainRenderer.java (original)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/desktop/TrainRenderer.java Sun Oct 1 10:26:55 2006
@@ -18,8 +18,14 @@
import java.io.IOException;
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
import java.util.Map;
+import java.util.TreeMap;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
@@ -29,11 +35,14 @@
import org.apache.myfaces.trinidad.bean.FacesBean;
import org.apache.myfaces.trinidad.component.UIXProcess;
import org.apache.myfaces.trinidad.component.core.nav.CoreTrain;
-import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.context.Agent;
import org.apache.myfaces.trinidad.context.FormData;
import org.apache.myfaces.trinidad.context.RenderingContext;
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.skin.Icon;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.OutputUtils;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.ProcessUtils;
+import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SkinProperties;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SkinSelectors;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.XhtmlConstants;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.XhtmlRenderer;
@@ -41,7 +50,7 @@
/**
* Renderer for process train components
- * * <p>
+ *
*/
public class TrainRenderer
extends XhtmlRenderer
@@ -144,49 +153,78 @@
@Override
protected void encodeAll(
- FacesContext context,
+ FacesContext context,
RenderingContext arc,
- UIComponent component,
- FacesBean bean)
+ UIComponent component,
+ FacesBean bean)
throws IOException
{
+ if(!(component instanceof UIXProcess))
+ {
+ throw new ClassCastException("TrainRenderer can only renders instances of " +
+ UIXProcess.class.getName() +
+ ", found " +
+ component.getClass().getName());
+ }
+
UIXProcess process = (UIXProcess) component;
UIComponent stamp = process.getNodeStamp();
if (stamp != null)
{
- Object oldPath = process.getRowKey();
- Object newPath = null;
- boolean isNewPath = _setNewPath(process);
- if (isNewPath)
+ Train train = new Train(context, arc, process, stamp);
+ try
{
+ process.setRowKey(train.getFocusRowKey());
+
+ // Renders some fields and scripts
+ _renderHiddenFields(context, arc, train);
+
ResponseWriter writer = context.getResponseWriter();
-
- TrainRenderer.TrainState trainState =
- _getTrainState(context, arc, process);
- _renderHiddenFields(context, arc, trainState);
-
- writer.startElement("table", component);
- OutputUtils.renderLayoutTableAttributes(context, arc, "0", null);
- writer.writeAttribute("align", "center", null);
- newPath = process.getRowKey();
- process.setRowKey(oldPath);
+
+ // Need to render the frame even if there's no visible station
+ // to support PPR.
+ writer.startElement(XhtmlConstants.TABLE_ELEMENT, component);
+ process.setRowKey(train.getInitialRowKey());
renderId(context, component);
- process.setRowKey(newPath);
renderAllAttributes(context, arc, bean);
-
- int length = process.getRowCount();
-
- if (length == 0)
- return;
-
- _encodeChildren(context, arc, process, stamp, trainState, length);
-
- writer.endElement("table");
-
- process.setRowKey(oldPath);
+ // Does not seem to be needed and this is not XHTML 1.0 Strict compliant
+ // writer.writeAttribute("align", "center", null);
+
+ if(!train.getStations().isEmpty())
+ {
+ // There're visible stations currently, let render them.
+ writer.startElement(XhtmlConstants.TABLE_BODY_ELEMENT, null);
+ _renderTrain(context, arc, process, bean, stamp, train);
+ writer.endElement(XhtmlConstants.TABLE_BODY_ELEMENT);
+ }
+
+ writer.endElement(XhtmlConstants.TABLE_ELEMENT);
}
+ finally
+ {
+ // Always restore the model, whatever happened
+ process.setRowKey(train.getInitialRowKey());
+ }
+ }
+ else
+ {
+ _LOG.warning("Train expect a nodeStamp facet, " +
+ "no such facet was found for train " + component);
}
+ /*
+ _encodeChildren(context, arc, process, stamp, trainState, length);
+ */
+ }
+
+ @Override
+ protected void renderAllAttributes(
+ FacesContext context,
+ RenderingContext arc,
+ FacesBean bean) throws IOException
+ {
+ super.renderAllAttributes(context, arc, bean);
+ OutputUtils.renderLayoutTableAttributes(context, arc, "0", null);
}
/**
@@ -195,603 +233,1631 @@
*/
@Override
protected void renderStyleAttributes(
- FacesContext context,
+ FacesContext context,
RenderingContext arc,
- FacesBean bean)
+ FacesBean bean)
throws IOException
{
- renderStyleAttributes(context, arc, bean,
- SkinSelectors.AF_PROCESS_TRAIN_STYLE_CLASS);
+ renderStyleAttributes(context,
+ arc,
+ bean,
+ SkinSelectors.AF_TRAIN_ROOT_STYLE_CLASS);
+ }
+
+ private void _preRenderIconBlock(
+ FacesContext context,
+ RenderingContext arc) throws IOException
+ {
+ ResponseWriter writer = context.getResponseWriter();
+
+ // Icon cell
+ writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
+
+ // Icons need to be in a table to stretch well
+ writer.startElement(XhtmlConstants.TABLE_ELEMENT, null);
+ OutputUtils.renderLayoutTableAttributes(context, arc, "0", null);
+ writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE, "width: 100%", null);
+
+ writer.startElement(XhtmlConstants.TABLE_BODY_ELEMENT, null);
+ writer.startElement(XhtmlConstants.TABLE_ROW_ELEMENT, null);
+ }
+
+ private void _postRenderIconBlock(FacesContext context) throws IOException
+ {
+ ResponseWriter writer = context.getResponseWriter();
+
+ writer.endElement(XhtmlConstants.TABLE_ROW_ELEMENT);
+ writer.endElement(XhtmlConstants.TABLE_BODY_ELEMENT);
+ writer.endElement(XhtmlConstants.TABLE_ELEMENT);
+ writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
}
-
- /**
- * Initialize the station state
- */
- private void _initializeStationState(
- FacesContext context,
+ private void _renderHiddenFields(
+ FacesContext context,
RenderingContext arc,
- TrainRenderer.TrainState train,
- TrainRenderer.StationState station,
- int currVisChildIndex,
- int prevVisChildIndex,
- int nextVisChildIndex,
- boolean isCurrChildDisabled,
- boolean isPrevChildDisabled,
- boolean isNextChildDisabled)
+ Train train)
+ throws IOException
{
- station.isPreviousLink = false;
- station.isMoreLink = false;
- station.isDisabled = false;
- station.isNextDisabled = false;
- station.isPrevDisabled = false;
- station.index = currVisChildIndex;
+ if((train.getFormName() != null) && supportsScripting(arc))
+ {
+ // render hidden fields to hold the form data
+ FormData formData = arc.getFormData();
+ if (formData != null)
+ {
+ formData.addNeededValue(XhtmlConstants.EVENT_PARAM);
+ formData.addNeededValue(XhtmlConstants.SOURCE_PARAM);
+ formData.addNeededValue(XhtmlConstants.VALUE_PARAM);
+ formData.addNeededValue(XhtmlConstants.SIZE_PARAM);
+ }
- // train.startIndex is the index into the List that is the
- // start of the train. The algorithm is dependent upon the BLAF spec.
- if (currVisChildIndex == train.startIndex - 1)
+ // Render script submission code.
+ ProcessUtils.renderNavSubmitScript(context, arc);
+ }
+ }
+
+ private void _renderContentRowLtr(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ UIComponent stamp,
+ Train train) throws IOException
+ {
+ ParentTrain parentTrain = train.getParentTrain();
+
+ // Render parent start
+ if(parentTrain != null && parentTrain.hasParentStart())
+ {
+ _renderParentContent(context, arc, parentTrain.getParentStart());
+ }
+
+ for(Station station : train.getStations())
+ {
+ _renderStationContent(context, arc, process, stamp, station);
+ }
+
+ // Render parent end
+ if(parentTrain != null && parentTrain.hasParentEnd())
{
- station.isPreviousLink = true;
+ _renderParentContent(context, arc, parentTrain.getParentEnd());
}
- else if (currVisChildIndex == train.startIndex + _MAX_NUM_LINK_INDEX)
+ }
+
+ private void _renderContentRowRtl(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ UIComponent stamp,
+ Train train) throws IOException
+ {
+ ParentTrain parentTrain = train.getParentTrain();
+
+ // Render parent start
+ if(parentTrain != null && parentTrain.hasParentEnd())
+ {
+ _renderParentContent(context, arc, parentTrain.getParentEnd());
+ }
+
+ List<Station> stations = train.getStations();
+ ListIterator<Station> iterator = stations.listIterator(stations.size());
+ while(iterator.hasPrevious())
+ {
+ _renderStationContent(context, arc, process, stamp, iterator.previous());
+ }
+
+ // Render parent end
+ if(parentTrain != null && parentTrain.hasParentStart())
{
- station.isMoreLink = true;
+ _renderParentContent(context, arc, parentTrain.getParentStart());
}
+ }
+
+ private void _renderIconBlock(
+ FacesContext context,
+ RenderingContext arc,
+ List<String> iconNames,
+ String shortDesc,
+ String styleClass,
+ String iconStyleClass,
+ List<String> stateStyleClasses) throws IOException
+ {
+ ResponseWriter writer = context.getResponseWriter();
- // selected nodes cannot be disabled,
- // so don't bother getting disabled attribute for the selected node
-
- if (currVisChildIndex != NO_CHILD_INDEX &&
- currVisChildIndex != train.selectedIndex)
+ writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
+
+ stateStyleClasses.add(styleClass);
+ stateStyleClasses.add(iconStyleClass);
+
+ renderStyleClasses(context,
+ arc,
+ stateStyleClasses.toArray(_EMPTY_STRING_ARRAY));
+
+ if(iconNames != null)
+ {
+ // Render the first valid icon found. The list should be in
+ // decreasing priority order.
+ for(String iconName : iconNames)
+ {
+ Icon icon = arc.getIcon(iconName);
+ if(icon != null)
+ {
+ OutputUtils.renderIcon(context, arc, icon, shortDesc, null);
+ break;
+ }
+ }
+ }
+
+ writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
+ }
+
+ private void _renderIconRowLtr(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ UIComponent stamp,
+ Train train) throws IOException
+ {
+ ParentTrain parentTrain = train.getParentTrain();
+
+ // Render parent start
+ if(parentTrain != null && parentTrain.hasParentStart())
+ {
+ _renderParentStartLtr(context, arc, process, train);
+ }
+
+ for(Station station : train.getStations())
+ {
+ _renderStationIconLtr(context, arc, process, station);
+ }
+
+ // Render parent end
+ if(parentTrain != null && parentTrain.hasParentEnd())
{
- station.isDisabled = isCurrChildDisabled;
+ _renderParentEndLtr(context, arc, process, train);
}
-
- // get disabled information about the previous and the next child.
- // selectedIndex cannot act disabled
- //
- if (prevVisChildIndex != NO_CHILD_INDEX &&
- prevVisChildIndex != train.selectedIndex)
+ }
+
+ private void _renderIconRowRtl(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ UIComponent stamp,
+ Train train) throws IOException
+ {
+ ParentTrain parentTrain = train.getParentTrain();
+
+ // Render parent end
+ if(parentTrain != null && parentTrain.hasParentEnd())
+ {
+ _renderParentEndRtl(context, arc, process, train);
+ }
+
+ List<Station> stations = train.getStations();
+ ListIterator<Station> iterator = stations.listIterator(stations.size());
+ while(iterator.hasPrevious())
+ {
+ _renderStationIconRtl(context, arc, process, iterator.previous());
+ }
+
+ // Render parent start
+ if(parentTrain != null && parentTrain.hasParentStart())
{
- station.isPrevDisabled = isPrevChildDisabled;
+ _renderParentStartRtl(context, arc, process, train);
}
-
- if (nextVisChildIndex != NO_CHILD_INDEX &&
- nextVisChildIndex != train.selectedIndex)
+
+ }
+
+ private void _renderJoin(
+ FacesContext context,
+ RenderingContext arc,
+ String stateStyleClass,
+ boolean overflow) throws IOException
+ {
+ if(stateStyleClass == _STATE_PARENT)
+ {
+ _renderJoin(context,
+ arc,
+ SkinSelectors.AF_TRAIN_PARENT_JOIN_STYLE_CLASS,
+ null);
+ }
+ else if(overflow)
+ {
+ _renderJoin(context,
+ arc,
+ SkinSelectors.AF_TRAIN_OVERFLOW_JOIN_STYLE_CLASS,
+ stateStyleClass);
+ }
+ else
{
- station.isNextDisabled = isNextChildDisabled;
-
+ _renderJoin(context,
+ arc,
+ SkinSelectors.AF_TRAIN_JOIN_STYLE_CLASS,
+ stateStyleClass);
}
+ }
+
+ private void _renderJoin(
+ FacesContext context,
+ RenderingContext arc,
+ String joinStyleClass,
+ String stateStyleClass) throws IOException
+ {
+ ResponseWriter writer = context.getResponseWriter();
- //
- // get the selected and visited flags for our node
- //
- station.isSelected = (currVisChildIndex == train.selectedIndex);
- station.isVisited = (currVisChildIndex <= train.maxVisitedIndex);
- station.isNextVisited = (currVisChildIndex < train.maxVisitedIndex);
- station.isNext = (currVisChildIndex == (train.maxVisitedIndex + 1));
- // if previous station is "next", and disabled, mark this as "next".
- if ((currVisChildIndex - 1 == (train.maxVisitedIndex + 1)) &&
- (station.isPrevDisabled))
+ writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
+ renderStyleClasses(context,
+ arc,
+ new String[]{
+ joinStyleClass,
+ stateStyleClass});
+
+ writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
+ }
+
+ private void _renderJoinIconBlock(
+ FacesContext context,
+ RenderingContext arc,
+ String stateStyleClass,
+ boolean overflow) throws IOException
+ {
+ if(stateStyleClass == _STATE_PARENT)
+ {
+ _renderJoinIconBlock(context,
+ arc,
+ SkinSelectors.AF_TRAIN_PARENT_JOIN_STYLE_CLASS,
+ null);
+ }
+ else if(overflow)
+ {
+ _renderJoinIconBlock(context,
+ arc,
+ SkinSelectors.AF_TRAIN_OVERFLOW_JOIN_STYLE_CLASS,
+ stateStyleClass);
+ }
+ else
{
- station.isNext = true;
+ _renderJoinIconBlock(context,
+ arc,
+ SkinSelectors.AF_TRAIN_JOIN_STYLE_CLASS,
+ stateStyleClass);
}
}
-
- /**
- * Returns the MAX_VISITED_ATTR
- * @todo =-=jmw Hopefully the controller will tell us this someday.
- */
- private static Object _getMaxVisited(
- RenderingContext arc,
- UIComponent component)
+
+ private void _renderJoinIconBlock(
+ FacesContext context,
+ RenderingContext arc,
+ String joinStyleClass,
+ String stateStyleClass) throws IOException
{
- // return component.getAttributes().get("maxVisited");
- return null;
- }
+ ResponseWriter writer = context.getResponseWriter();
- /**
- * Get the maxVisited attribute from the node and return it.
- */
- private int _getMaxVisitedIndex(
- RenderingContext arc,
- UIComponent component)
+ writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
+ writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE, "width: 50%", null);
+ renderStyleClasses(context,
+ arc,
+ new String[]{
+ joinStyleClass,
+ stateStyleClass});
+ writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
+ }
+
+ private void _renderParentContent(
+ FacesContext context,
+ RenderingContext arc,
+ Station parent) throws IOException
{
- int maxVisitedIndex = NO_CHILD_INDEX;
- Integer maxVisited = (Integer) _getMaxVisited(arc, component);
- if (maxVisited != null)
- {
- maxVisitedIndex = maxVisited.intValue();
+ ResponseWriter writer = context.getResponseWriter();
+
+ String baseStyleClass = parent.getBaseStyleClass();
+ writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
+ writer.writeAttribute(XhtmlConstants.COLSPAN_ATTRIBUTE, "3", null);
+ renderStyleClasses(context,
+ arc,
+ new String[]{
+ baseStyleClass,
+ baseStyleClass + _SUFFIX_CONTENT});
+
+ /* -= Simon =-
+ * FIXME HACK for MSIE CSS bug involving composite style classes.
+ * Since the bug is most obvious with join background images
+ * I hard code background-image to none to fix it.
+ * See Jira for issue ADFFACES-206.
+ */
+ if(arc.getAgent().getAgentName().equalsIgnoreCase(Agent.AGENT_IE))
+ {
+ writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE,
+ "background-image:none;",
+ null);
}
- return maxVisitedIndex;
+
+ writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
}
-
- /**
- * Return what the starting index into the stations List.
- */
- private int _getStartIndex(int numPages, int originalSelectedIndex)
+
+ private void _renderParentEnd(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Train train,
+ String leftState,
+ String rightState) throws IOException
+ {
+ // Add join
+ _renderJoin(context, arc, leftState, false);
+
+ // Icon cell
+ _preRenderIconBlock(context, arc);
+
+ // Add join
+ _renderJoinIconBlock(context, arc, leftState, false);
+
+ // Add the parent's stop icon
+ _renderParentEndIconBlock(context, arc, process, train);
+
+ // Add join
+ _renderJoinIconBlock(context, arc, rightState, false);
+
+ // End icon cell
+ _postRenderIconBlock(context);
+
+ // Add join
+ _renderJoin(context, arc, rightState, false);
+ }
+
+ private void _renderParentEndLtr(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Train train) throws IOException
+ {
+ _renderParentEnd(context,
+ arc,
+ process,
+ train,
+ _STATE_PARENT,
+ null);
+ }
+
+ private void _renderParentEndRtl(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Train train) throws IOException
+ {
+ _renderParentEnd(context,
+ arc,
+ process,
+ train,
+ null,
+ _STATE_PARENT);
+ }
+
+ private void _renderParentEndIconBlock(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Train train) throws IOException
+ {
+ assert train.getParentTrain().hasParentEnd();
+
+ Station parent = train.getParentTrain().getParentEnd();
+
+ process.setRowKey(parent.getRowKey());
+
+ _renderStationIconBlock(context, arc, process, parent);
+
+ // Restore model
+ process.setRowKey(train.getInitialRowKey());
+ }
+
+ private void _renderParentStartIconBlock(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Train train) throws IOException
+ {
+ assert train.getParentTrain().hasParentStart();
+
+ Station parent = train.getParentTrain().getParentStart();
+
+ process.setRowKey(parent.getRowKey());
+
+ _renderStationIconBlock(context, arc, process, parent);
+
+ // Restore model
+ process.setRowKey(train.getInitialRowKey());
+ }
+
+ private void _renderParentStart(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Train train,
+ String leftState,
+ String rightState) throws IOException
+ {
+ // Add join
+ _renderJoin(context, arc, leftState, false);
+
+ // Icon cell
+ _preRenderIconBlock(context, arc);
+
+ // Add join
+ _renderJoinIconBlock(context, arc, leftState, false);
+
+ // Add the parent's stop icon
+ _renderParentStartIconBlock(context, arc, process, train);
+
+ // Add join
+ _renderJoinIconBlock(context, arc, rightState, false);
+
+ _postRenderIconBlock(context);
+ // End icon cell
+
+ // Add join
+ _renderJoin(context, arc, rightState, false);
+ }
+
+ private void _renderParentStartLtr(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Train train) throws IOException
+ {
+ _renderParentStart(context,
+ arc,
+ process,
+ train,
+ null,
+ _STATE_PARENT);
+ }
+
+ private void _renderParentStartRtl(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Train train) throws IOException
+ {
+ _renderParentStart(context,
+ arc,
+ process,
+ train,
+ _STATE_PARENT,
+ null);
+ }
+
+ private void _renderStationContent(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ UIComponent stamp,
+ Station station) throws IOException
{
- int currentMinIndex = 0;
-
- if (numPages <= _MAX_NUM_LINK_INDEX)
- return currentMinIndex;
-
- int selectedIndex = originalSelectedIndex;
- int currentMaxIndex = _MAX_NUM_LINK_INDEX - 1;
-
- if (selectedIndex < currentMaxIndex)
+ ResponseWriter writer = context.getResponseWriter();
+
+ writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
+
+ writer.writeAttribute(XhtmlConstants.COLSPAN_ATTRIBUTE, "3", null);
+
+ String baseStyleClass = station.getBaseStyleClass();
+
+ List<String> stateStyleClasses = station.getStates();
+ stateStyleClasses.add(baseStyleClass);
+ stateStyleClasses.add(baseStyleClass + _SUFFIX_CONTENT);
+
+ renderStyleClasses(context,
+ arc,
+ stateStyleClasses.toArray(_EMPTY_STRING_ARRAY));
+
+ /* -= Simon =-
+ * FIXME HACK for MSIE CSS bug involving composite style classes.
+ * Since the bug is most obvious with join background images
+ * I hard code background-image to none to fix it.
+ * See Jira for issue ADFFACES-206.
+ */
+ if(arc.getAgent().getAgentName().equalsIgnoreCase(Agent.AGENT_IE))
+ {
+ writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE,
+ "background-image:none;",
+ null);
+ }
+
+ Map<String, String> originalMap = arc.getSkinResourceKeyMap();
+
+ // Init the model
+ process.setRowIndex(station.getRowIndex());
+ try
{
- return currentMinIndex; //0
+ arc.setSkinResourceKeyMap(_RESOURCE_KEY_MAP);
+ encodeChild(context, stamp);
}
-
- // the algorithm below works, but I thought it was too cryptic
- // return (selectedIndex -
- // (((selectedIndex-1)%(_MAX_NUM_LINK_INDEX-2))+1));
-
- // loop until the selectedIndex range is found or
- // we have gone past the number of nodes in the train.
- // Then we'll know what index to start the visible portion of the train.
- while (numPages > currentMaxIndex)
+ finally
{
- currentMinIndex = currentMaxIndex - 1;
- currentMaxIndex += (_MAX_NUM_LINK_INDEX - 2);
- if (selectedIndex > currentMinIndex &&
- selectedIndex < currentMaxIndex)
- return currentMinIndex;
+ arc.setSkinResourceKeyMap(originalMap);
}
-
- return currentMinIndex;
+
+ writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
}
-
-
- /**
- * Gather up the train state: selectedIndex, maxVisitedIndex, startIndex,
- * isSubTrain, formName, id,.
- * This way all the parameters we need to pass around to various methods
- * are all in one place, the TrainState
- * @param arc RenderingContext
- * @param context FacesContext
- * @param process the UIXProcess component.
- * @return
- */
- private TrainState _getTrainState(
- FacesContext context,
- RenderingContext arc,
- UIXProcess process)
- {
- TrainRenderer.TrainState state =
- new TrainRenderer.TrainState();
-
- state.selectedIndex = process.getRowIndex();
-
- // get highest node in train visited
- state.maxVisitedIndex = _getMaxVisitedIndex(arc, process);
-
- // default to selectedIndex if it wasn't set
- // or if it was set to be greater than selectedIndex
- if (state.maxVisitedIndex == NO_CHILD_INDEX ||
- state.maxVisitedIndex < state.selectedIndex)
- {
- state.maxVisitedIndex = state.selectedIndex;
- }
-
- int totalPages = process.getRowCount();
- state.startIndex = _getStartIndex(totalPages, state.selectedIndex);
-
- state.subTrain = _isSubTrain(process);
-
- state.formName = arc.getFormData().getName();
-
- String id = process.getClientId(context);
- state.id = (id != null)? id: null;
-
- return state;
+
+ private void _renderStationIcon(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Station station,
+ String leftJoinState,
+ String rightJoinState,
+ boolean overflowLeft,
+ boolean overflowRight) throws IOException
+ {
+ // Add join
+ _renderJoin(context, arc, leftJoinState, overflowLeft);
+
+ // Icon cell
+ _preRenderIconBlock(context, arc);
+
+ // Add join
+ _renderJoinIconBlock(context, arc, leftJoinState, overflowLeft);
+
+ // Add the parent's stop icon
+ _renderStationIconBlock(context, arc, process, station);
+
+ // Add join
+ _renderJoinIconBlock(context, arc, rightJoinState, overflowRight);
+
+ // End icon cell
+ _postRenderIconBlock(context);
+
+ // Add join
+ _renderJoin(context, arc, rightJoinState, overflowRight);
}
-
-
- /**
- * Get the subTrain attribute from the node and return it.
- */
- private boolean _isSubTrain(UIXProcess component)
- {
- Object focusRowKey = component.getFocusRowKey();
- if (focusRowKey != null && (component.getDepth(focusRowKey) > 0))
- return true;
-
- return false;
+
+ private void _renderStationIconBlock(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Station station) throws IOException
+ {
+ process.setRowIndex(station.getRowIndex());
+
+ String baseStyleClass = station.getBaseStyleClass();
+
+ _renderIconBlock(context,
+ arc,
+ station.getIconNames(),
+ station.getLabel(),
+ baseStyleClass,
+ baseStyleClass + _SUFFIX_ICON_CELL,
+ station.getStates());
}
-
-
- private void _encodeChildren(
- FacesContext context,
- RenderingContext arc,
- UIXProcess process,
- UIComponent stamp,
- TrainState train,
- int length)
- throws IOException
+
+ private void _renderStationIconLtr(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Station station) throws IOException
+ {
+ _renderStationIcon(context,
+ arc,
+ process,
+ station,
+ station.getStartJoinState(),
+ station.getEndJoinState(),
+ station.hasPrevious() && station.getPrevious().isOverflowStart(),
+ station.hasNext() && station.getNext().isOverflowEnd());
+ }
+
+ private void _renderStationIconRtl(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ Station station) throws IOException
+ {
+ _renderStationIcon(context,
+ arc,
+ process,
+ station,
+ station.getEndJoinState(),
+ station.getStartJoinState(),
+ station.hasNext() && station.getNext().isOverflowEnd(),
+ station.hasPrevious() && station.getPrevious().isOverflowStart());
+ }
+
+ private void _renderTrain(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ FacesBean bean,
+ UIComponent stamp,
+ Train train) throws IOException
{
-
ResponseWriter writer = context.getResponseWriter();
- // start FOR SUBTRAIN
- // If subTrain, add a row and on the first and last cells, render
- // a border which looks like a sub-train
- if (train.subTrain)
- {
- _renderSubTrainRow(context, arc, train, length, writer);
-
- writer.startElement("tr", null);
- writer.startElement("td", null);
- writer.endElement("td");
+ // Start of the icon row
+ writer.startElement(XhtmlConstants.TABLE_ROW_ELEMENT, null);
+
+ if(arc.isRightToLeft())
+ {
+ _renderIconRowRtl(context, arc, process, stamp, train);
}
else
{
- writer.startElement("tr", null);
+ _renderIconRowLtr(context, arc, process, stamp, train);
}
+
+ writer.endElement(XhtmlConstants.TABLE_ROW_ELEMENT);
- // loop through each rendered station.
- int lastTrainIndex = train.startIndex + _getMaxLinks(arc, process);
-
- if (length <= lastTrainIndex)
+ // Start of the content row
+ writer.startElement(XhtmlConstants.TABLE_ROW_ELEMENT, null);
+
+ if(arc.isRightToLeft())
{
- lastTrainIndex = length;
+ _renderContentRowRtl(context, arc, process, stamp, train);
}
else
{
- lastTrainIndex++; // length of train is larger than the visible
- // number of train stations, so make room for the more
- // by adding one to the lastTrainIndex.
+ _renderContentRowLtr(context, arc, process, stamp, train);
}
- int currVisChildIndex = Math.max(0, train.startIndex - 1);
- boolean isPrevVisChildDisabled = false;
- boolean isCurrVisChildDisabled = false;
- boolean isNextVisChildDisabled = false;
-
- process.setRowIndex(currVisChildIndex);
-
- isCurrVisChildDisabled =
- Boolean.TRUE.equals(stamp.getAttributes().get("disabled"));
- // getBooleanAttributeValue(context, stamp, DISABLED_ATTR, false);
-
- for (; currVisChildIndex < lastTrainIndex; currVisChildIndex++)
+
+ writer.endElement(XhtmlConstants.TABLE_ROW_ELEMENT);
+ }
+
+ private static class Train
+ {
+ public Train(
+ FacesContext context,
+ RenderingContext arc,
+ UIXProcess process,
+ UIComponent stamp)
+ {
+ // Save the model state
+ int maxVisitedIndex = _getMaxVisitedIndex(arc, process);
+ int activeIndex = _loadStations(process, stamp, maxVisitedIndex);
+ int visibleStopCount = _getVisibleStopCount(arc);
+
+ _formName = arc.getFormData().getName();
+ _isSubTrain = _loadIsSubTrain(process);
+
+ if(!_stations.isEmpty())
+ {
+ // There's something visible in the train
+ if(_stations.size() > visibleStopCount)
+ {
+ // We have overflow, let resolve it
+ _resolveOverflow(visibleStopCount, activeIndex);
+ }
+ else
+ {
+ // No overflow, yay!
+ _resolveStandard();
+ }
+
+ _initLabels(arc, process, stamp);
+ _initParentTrain(arc, process, stamp);
+ }
+ }
+
+ public Object getFocusRowKey()
{
- //
- // get index of the child and
- // determine if it is within the range in which it will be rendered.
- //
- int prevVisChildIndex =
- ((currVisChildIndex == 0)? NO_CHILD_INDEX: currVisChildIndex - 1);
- int nextVisChildIndex =
- ((currVisChildIndex == length - 1)? NO_CHILD_INDEX:
- currVisChildIndex + 1);
-
- process.setRowIndex(nextVisChildIndex);
-
- isNextVisChildDisabled =
- Boolean.TRUE.equals(stamp.getAttributes().get("disabled"));
-
- process.setRowIndex(currVisChildIndex);
-
- // initialized state of the station
- TrainRenderer.StationState station = train.station;
- _initializeStationState(context, arc, train, station,
- currVisChildIndex, prevVisChildIndex,
- nextVisChildIndex, isCurrVisChildDisabled,
- isPrevVisChildDisabled,
- isNextVisChildDisabled);
-
- // set up for next pass
- isPrevVisChildDisabled = isCurrVisChildDisabled;
- isCurrVisChildDisabled = isNextVisChildDisabled;
-
- Object label = stamp.getAttributes().get("text");
-
- String currVisChildText = null;
-
- // Get text from link, or Previous or More text if appropriate
- currVisChildText = _getTextForStation(arc, station, label);
-
- String currVisChildID = null;
-
- process.setRowIndex(currVisChildIndex);
- _renderLink(context, arc, stamp, writer, train, currVisChildText,
- currVisChildID, station);
-
+ return _focusRowKey;
}
-
- if (train.subTrain)
+
+ public String getFormName()
{
- writer.startElement("td", null);
- writer.endElement("td");
+ return _formName;
+ }
+
+ public Object getInitialRowKey()
+ {
+ return _initialRowKey;
+ }
+
+ public ParentTrain getParentTrain()
+ {
+ return _parent;
+ }
+
+ public List<Station> getStations()
+ {
+ return _stations;
+ }
+
+ public boolean isSubTrain()
+ {
+ return _isSubTrain;
+ }
+
+ private void _createStation(
+ UIXProcess process,
+ UIComponent stamp,
+ int index,
+ boolean active,
+ boolean visited)
+ {
+ process.setRowIndex(index);
+ if(stamp.isRendered())
+ {
+ // The station will be visible.
+ _stations.add(new Station(this,
+ stamp,
+ index,
+ process.getRowKey(),
+ active,
+ visited));
+ }
}
- writer.endElement("tr");
- }
-
- /**
- * Renders the link under the train node
- *
- */
- private void _renderLink(
- FacesContext context,
- RenderingContext arc,
- UIComponent stamp,
- ResponseWriter writer,
- TrainRenderer.TrainState train,
- String currVisChildText,
- String currVisChildID,
- TrainRenderer.StationState station)
- throws IOException
- {
- //
- // Write the link under the train node.
- //
- writer.startElement("td", null);
- writer.writeAttribute("colspan", "2", null);
-
- String styleClass =
- (station.isSelected)? SkinSelectors.AF_PROCESS_TRAIN_ACTIVE_STYLE_CLASS:
- (station.isDisabled && !station.isMoreLink)?
- SkinSelectors.AF_PROCESS_TRAIN_DISABLED_STYLE_CLASS:
- (station.isVisited)?
- SkinSelectors.AF_PROCESS_TRAIN_VISITED_STYLE_CLASS:
- SkinSelectors.AF_PROCESS_TRAIN_UNVISITED_STYLE_CLASS;
-
- renderStyleClass(context, arc, styleClass);
+ /**
+ * Get the maxVisited attribute from the node and return it.
+ */
+ private int _getMaxVisitedIndex(
+ RenderingContext arc,
+ UIComponent component)
+ {
+ int maxVisitedIndex = NO_CHILD_INDEX;
+ Integer maxVisited = (Integer) _getMaxVisited(arc, component);
+ if (maxVisited != null)
+ {
+ maxVisitedIndex = maxVisited.intValue();
+ }
+ return maxVisitedIndex;
+ }
- Map<String, String> originalResourceKeyMap = arc.getSkinResourceKeyMap();
- try
+ /**
+ * Returns the MAX_VISITED_ATTR
+ * @todo =-=jmw Hopefully the controller will tell us this someday.
+ */
+ private static Object _getMaxVisited(
+ RenderingContext arc,
+ UIComponent component)
+ {
+ // return component.getAttributes().get("maxVisited");
+ return null;
+ }
+
+ private int _getVisibleStopCount(RenderingContext arc)
+ {
+ Object propValue =
+ arc.getSkin().getProperty(SkinProperties.AF_TRAIN_VISIBLE_STOP_COUNT);
+
+ if(propValue == null)
+ {
+ return DEFAULT_MAX_VISIBLE_STOP_COUNT;
+ }
+
+ try
+ {
+ int count = Integer.parseInt(propValue.toString());
+ if(count <= 0)
+ {
+ _LOG.warning("Visible stop count must be > 0, found " + count);
+ return DEFAULT_MAX_VISIBLE_STOP_COUNT;
+ }
+
+ return count;
+ }
+ catch(NumberFormatException e)
+ {
+ _LOG.warning("Visible stop count must be an integer, found " + propValue);
+ return DEFAULT_MAX_VISIBLE_STOP_COUNT;
+ }
+ }
+
+ private void _initLabels(
+ RenderingContext arc,
+ UIXProcess process,
+ UIComponent stamp)
{
- arc.setSkinResourceKeyMap(_RESOURCE_KEY_MAP);
- _renderStamp(context, stamp);
+ for(Station s : _stations)
+ {
+ process.setRowIndex(s.getRowIndex());
+ s.initLabel(arc, stamp);
+ }
}
- finally
+
+ private void _initParentTrain(
+ RenderingContext arc,
+ UIXProcess process,
+ UIComponent stamp)
{
- arc.setSkinResourceKeyMap(originalResourceKeyMap);
+ if(_isSubTrain)
+ {
+ if(_shouldRenderParentTrain(arc))
+ {
+ _parent = new ParentTrain(arc, process, stamp, this);
+ if(!_parent.hasParentStart() && !_parent.hasParentEnd())
+ {
+ _isSubTrain = false;
+ }
+ }
+ else
+ {
+ _isSubTrain = false;
+ }
+ }
}
- writer.endElement("td");
- }
-
- /**
- * Called to render a child. This method does not update the
- * rendering context (by calling pushChild() and popChild()
- * as needed); subclasses need to use renderIndexedChild() or
- * renderNamedChild() for that purpose.
- * <p>
- * @param context the faces context
- * @param child the child under consideration
- */
- private void _renderStamp(FacesContext context, UIComponent child)
- throws IOException
- {
- if (child != null)
+
+ /**
+ * Determine if this train is a sub-train.
+ */
+ private boolean _loadIsSubTrain(UIXProcess process)
{
- encodeChild(context, child);
- // child.render(context);
+ Object focusRowKey = process.getFocusRowKey();
+ if (focusRowKey != null && (process.getDepth(focusRowKey) > 0))
+ {
+ return true;
+ }
+
+ return false;
}
- }
-
- /**
- * return the string to use for the text of the station
- * it is the text of the link or "Previous" or "More"
- */
- private String _getTextForStation(
- RenderingContext arc,
- TrainRenderer.StationState station,
- Object textObj)
- {
- String textValue = (textObj == null)? null: textObj.toString();
- final String currText;
+
+ private int _loadStations(
+ UIXProcess process,
+ UIComponent stamp,
+ int maxVisitedIndex)
+ {
+ _initialRowKey = process.getRowKey();
+ try
+ {
+ // Set the model on the focus item
+ _focusRowKey = process.getFocusRowKey();
+ process.setRowKey(_focusRowKey);
+
+ int count = process.getRowCount();
+ int activeIndex = process.getRowIndex();
+ int index = 0;
+
+ assert activeIndex < count;
+
+ _stations = new ArrayList<Station>(count);
+
+ // Process visited stations
+ for(; index < activeIndex; index++)
+ {
+ _createStation(process, stamp, index, false, true);
+ }
+
+ assert index == activeIndex;
+
+ _createStation(process, stamp, index, true, true);
+ index++;
+ // Might have an invisible active station. Thsi is weird, but still.
+ // You never know what users want to do, but let support
+ // it nevertheless for now.
+ // selectedIndex is either the active station index or the index
+ // of the station just before the selected one if active is not visible.
+ activeIndex = _stations.size() - 1;
+
+ if(maxVisitedIndex != NO_CHILD_INDEX)
+ {
+ for(; index < maxVisitedIndex; index++)
+ {
+ _createStation(process, stamp, index, false, true);
+ }
+ }
+
+ for(; index < count; index++)
+ {
+ _createStation(process, stamp, index, false, false);
+ }
+
+ return activeIndex;
+ }
+ finally
+ {
+ // Restore the model's state
+ process.setRowKey(_initialRowKey);
+ }
+ }
+
+ private void _resolveOverflow(
+ int visibleStopCount,
+ int activeIndex)
+ {
+ assert _stations != null;
+ assert activeIndex >= -1;
+ assert activeIndex < _stations.size();
+
+ // First, resolve chaining
+ _resolveStandard();
+
+ // We have more stations than the max available, so we have an overflow
+ // for sure.
+ if(activeIndex <= 0)
+ {
+ // Overflow to the following group only
+ _resolveOverflowEnd(visibleStopCount);
+ _stations = _stations.subList(0, visibleStopCount + 1);
+ }
+ else
+ {
+ // Get the visible group index
+ int groupIndex = activeIndex / visibleStopCount;
+ int startIndex = 0;
+ int endIndex = _stations.size();
+ if(groupIndex > 0)
+ {
+ // We have a previous overflow
+ startIndex = groupIndex * visibleStopCount - 1;
+ _resolveOverflowStart(startIndex);
+ }
+
+ int maxGroupIndex = (_stations.size() - 1) / visibleStopCount;
+
+ if(groupIndex < maxGroupIndex)
+ {
+ // We have a next overflow
+ int overflowIndex = (groupIndex + 1) * visibleStopCount;
+
+ // endIndex is exclusive
+ endIndex = overflowIndex + 1;
+
+ _resolveOverflowEnd(overflowIndex);
+ }
- if (textValue != null && !station.isPreviousLink &&
- !station.isMoreLink)
+ _stations = _stations.subList(startIndex, endIndex);
+ }
+ }
+
+ private void _resolveOverflowEnd(int index)
+ {
+ assert _stations != null;
+ assert index >= 0;
+ assert index < _stations.size();
+
+ Station station = _stations.get(index);
+ station.setOverflowEnd(true);
+ if(station.hasPrevious() && station.getPrevious().isDisabled())
+ {
+ // If previous stop is disabled, so is the overflow
+ station.setDisabled(true);
+ }
+
+ station.setNext(null);
+ }
+
+ private void _resolveOverflowStart(int index)
+ {
+ assert _stations != null;
+ assert index >= 0;
+ assert index < _stations.size();
+
+ Station station = _stations.get(index);
+ station.setOverflowStart(true);
+ if(station.hasNext() && station.getNext().isDisabled())
+ {
+ // If next stop is disabled, so is the overflow
+ station.setDisabled(true);
+ }
+
+ station.setPrevious(null);
+ }
+
+ private void _resolveStandard()
+ {
+ if(_stations.size() > 1)
+ {
+ Iterator<Station> iterator = _stations.iterator();
+
+ Station previous = null;
+ Station current = iterator.next();
+ Station next = iterator.next();
+
+ _updateStation(current, previous, next);
+
+ while(iterator.hasNext())
+ {
+ previous = current;
+ current = next;
+ next = iterator.next();
+ _updateStation(current, previous, next);
+ }
+
+ next.setPrevious(current);
+ }
+ }
+
+ private boolean _shouldRenderParentTrain(RenderingContext arc)
+ {
+ Object propValue =
+ arc.getSkin().getProperty(SkinProperties.AF_TRAIN_RENDER_PARENT_TRAIN);
+
+ if(propValue == null)
+ {
+ return DEFAULT_RENDER_PARENT_TRAIN;
+ }
+
+ return Boolean.TRUE.equals(propValue);
+ }
+
+ private void _updateStation(
+ Station current,
+ Station previous,
+ Station next)
+ {
+ current.setPrevious(previous);
+ current.setNext(next);
+ }
+
+ private Object _focusRowKey;
+ private String _formName;
+ private Object _initialRowKey;
+ private boolean _isSubTrain;
+ private ParentTrain _parent;
+ private List<Station> _stations;
+ }
+
+ private static class Station
+ {
+ public Station(
+ Train train,
+ int index,
+ Object rowKey)
+ {
+ _rowIndex = index;
+ _rowKey = rowKey;
+ _active = false;
+ _visited = false;
+ _disabled = false;
+ _readOnly = false;
+ _parentEnd = false;
+ _parentStart = false;
+ _train = train;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Station(
+ Train train,
+ UIComponent stamp,
+ int index,
+ Object rowKey,
+ boolean active,
+ boolean visited)
+ {
+ Map<String, Object> attributes = stamp.getAttributes();
+
+ _rowIndex = index;
+ _rowKey = rowKey;
+ _active = active;
+ _visited = visited;
+ _disabled = _getBooleanAttribute(attributes, "disabled", false);
+ _readOnly = _getBooleanAttribute(attributes, "readOnly", false);
+ _parentEnd = false;
+ _parentStart = false;
+ _train = train;
+ }
+
+ public String getBaseStyleClass()
{
- // if we are in screen reader mode, then we must render more descriptive
- // text.
- // see bug 1801348 REMOVE ONE SET OF TRAIN TEXT IN ACCESSIBLE MODE
- if (isScreenReaderMode(arc))
+ if(isOverflowEnd())
+ {
+ return SkinSelectors.AF_TRAIN_OVERFLOW_END_STYLE_CLASS;
+ }
+ else if(isOverflowStart())
+ {
+ return SkinSelectors.AF_TRAIN_OVERFLOW_START_STYLE_CLASS;
+ }
+ else if(isParentStart())
+ {
+ return SkinSelectors.AF_TRAIN_PARENT_START_STYLE_CLASS;
+ }
+ else if(isParentEnd())
{
- currText = _getDisabledUserText(arc, station, textValue);
+ return SkinSelectors.AF_TRAIN_PARENT_END_STYLE_CLASS;
}
else
{
- currText = textValue;
+ return SkinSelectors.AF_TRAIN_STOP_STYLE_CLASS;
}
}
- else if (station.isPreviousLink)
+
+ public String getEndJoinState()
{
- currText = arc.getTranslatedString(_PREVIOUS_KEY);
+ if(isOverflowEnd())
+ {
+ return null;
+ }
+ else if(!hasNext())
+ {
+ ParentTrain parent = _train.getParentTrain();
+ if(parent != null && parent.hasParentEnd())
+ {
+ return _STATE_PARENT;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else if(isDisabled() || getNext().isDisabled())
+ {
+ return _STATE_DISABLED;
+ }
+ else if(getNext().isVisited())
+ {
+ return _STATE_VISITED;
+ }
+ else
+ {
+ return _STATE_UNVISITED;
+ }
}
- else if (station.isMoreLink)
+
+ public List<String> getIconNames()
{
- currText = arc.getTranslatedString(_MORE_KEY);
+ if(isOverflowEnd())
+ {
+ return _getOverflowEndIconNames();
+ }
+ else if(isOverflowStart())
+ {
+ return _getOverflowStartIconNames();
+ }
+ else if(isParentStart())
+ {
+ return Collections.singletonList(SkinSelectors.AF_TRAIN_PARENT_START_ICON_NAME);
+ }
+ else if(isParentEnd())
+ {
+ return Collections.singletonList(SkinSelectors.AF_TRAIN_PARENT_END_ICON_NAME);
+ }
+ else
+ {
+ return _getStopIconNames();
+ }
}
- else
- currText = null;
-
- return currText;
- }
-
- private String _getDisabledUserText(
- RenderingContext arc,
- TrainRenderer.StationState station,
- String textString)
- {
- String altTextKey =
- station.isSelected? _ACTIVE_KEY: station.isVisited? _VISITED_KEY:
- _NEXT_KEY;
-
- String[] parameters = new String[]
- { textString };
-
- String altText =
- XhtmlUtils.getFormattedString(arc.getTranslatedString(altTextKey),
- parameters);
- return altText;
- }
-
- /**
- * Returns the max number of links to show
- */
- private int _getMaxLinks(
- RenderingContext arc,
- UIComponent component)
- {
- return _MAX_NUM_LINK_INDEX;
- }
-
- private void _renderSubTrainRow(
- FacesContext context,
- RenderingContext arc,
- TrainRenderer.TrainState train,
- int length,
- ResponseWriter writer)
- throws IOException
- {
- boolean isRTL = arc.getLocaleContext().isRightToLeft();
-
- writer.startElement("tr", null);
-
- if (isRTL)
- _renderSubTrainCell(context, arc,
- SkinSelectors.TRAIN_SUB_RIGHT_STYLE_CLASS,
- writer);
- else
- _renderSubTrainCell(context, arc,
- SkinSelectors.AF_PROCESS_TRAIN_SUB_START_STYLE_CLASS,
- writer);
-
- _renderSubTrainBlankCells(train, length, writer);
-
- if (isRTL)
- _renderSubTrainCell(context, arc,
- SkinSelectors.AF_PROCESS_TRAIN_SUB_START_STYLE_CLASS,
- writer);
- else
- _renderSubTrainCell(context, arc,
- SkinSelectors.TRAIN_SUB_RIGHT_STYLE_CLASS,
- writer);
-
- writer.endElement("tr");
- }
-
- private void _renderSubTrainCell(
- FacesContext context,
- RenderingContext arc,
- String style,
- ResponseWriter writer)
- throws IOException
- {
- writer.startElement("td", null);
- renderStyleClass(context, arc, style);
- renderSpacer(context, arc, "14", "2");
- writer.endElement("td");
- }
-
- /**
- * renders a td with colSpan equal to the number of visible stations
- * including the Previous and More if they are there.
- * @param train
- * @param length
- * @param writer
- * @throws IOException
- */
- private void _renderSubTrainBlankCells(TrainRenderer.TrainState train,
- int length, ResponseWriter writer)
- throws IOException
- {
- writer.startElement("td", null);
-
- // figure out the number of stations
- int startIndex = Math.max(0, train.startIndex - 1);
- int lastTrainIndex = train.startIndex + _MAX_NUM_LINK_INDEX;
- if (length <= lastTrainIndex)
- lastTrainIndex = length;
- else
+
+ public String getLabel()
{
- // when the length of train is larger than the visible
- // number of train stations, we render a More link.
- // so make room for the more
- // by adding one to the lastTrainIndex.
- lastTrainIndex++;
- }
- String numberOfStations =
- Integer.toString((lastTrainIndex - startIndex) * 2);
- writer.writeAttribute("colspan", numberOfStations, null);
- writer.endElement("td");
- }
+ return _label;
+ }
+
+ public Station getNext()
+ {
+ return _next;
+ }
+
+ public Station getPrevious()
+ {
+ return _previous;
+ }
+
+ public int getRowIndex()
+ {
+ return _rowIndex;
+ }
+
+ public Object getRowKey()
+ {
+ return _rowKey;
+ }
+
+ public String getStartJoinState()
+ {
+ if(isOverflowStart())
+ {
+ return null;
+ }
+ else if(!hasPrevious())
+ {
+ ParentTrain parent = _train.getParentTrain();
+ if(parent != null && parent.hasParentStart())
+ {
+ return _STATE_PARENT;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else if(isDisabled() || getPrevious().isDisabled())
+ {
+ return _STATE_DISABLED;
+ }
+ else if(isVisited())
+ {
+ return _STATE_VISITED;
+ }
+ else
+ {
+ return _STATE_UNVISITED;
+ }
+ }
+
+ public List<String> getStates()
+ {
+ List<String> states = new ArrayList<String>(5);
+ if(isParentStart() || isParentEnd())
+ {
+ return states;
+ }
+
+ if(isDisabled())
+ {
+ states.add(_STATE_DISABLED);
+ return states;
+ }
+
+ if(isActive())
+ {
+ states.add(_STATE_ACTIVE);
+ }
+ else if(isVisited())
+ {
+ states.add(_STATE_VISITED);
+ }
+ else
+ {
+ states.add(_STATE_UNVISITED);
+ }
+
+ if(isReadOnly())
+ {
+ states.add(_STATE_READ_ONLY);
+ }
+
+ return states;
+ }
+
+ public boolean hasNext()
+ {
+ return _next != null;
+ }
+
+ public boolean hasPrevious()
+ {
+ return _previous != null;
+ }
- private void _renderHiddenFields(
- FacesContext context,
- RenderingContext arc,
- TrainState train)
- throws IOException
- {
- if ((train.formName != null) && supportsScripting(arc))
+ /**
+ * return the string to use for the text of the station
+ * it is the text of the link or "Previous" or "More"
+ */
+ public void initLabel(
+ RenderingContext arc,
+ UIComponent stamp)
{
- // render hidden fields to hold the form data
- FormData fData = arc.getFormData();
- if (fData != null)
+ if(isOverflowStart())
{
- fData.addNeededValue(XhtmlConstants.EVENT_PARAM);
- fData.addNeededValue(XhtmlConstants.SOURCE_PARAM);
- fData.addNeededValue(XhtmlConstants.VALUE_PARAM);
- fData.addNeededValue(XhtmlConstants.SIZE_PARAM);
+ _label = arc.getTranslatedString(_PREVIOUS_KEY);
+ }
+ else if(isOverflowEnd())
+ {
+ _label = arc.getTranslatedString(_MORE_KEY);
+ }
+ else
+ {
+ Object text = stamp.getAttributes().get("text");
+ if(text != null)
+ {
+ _label = text.toString();
+ if (isScreenReaderMode(arc))
+ {
+ _label = _getDisabledUserText(arc, _label);
+ }
+ }
+ else
+ {
+ _label = null;
+ }
}
-
- // Render script submission code.
- ProcessUtils.renderNavSubmitScript(context, arc);
}
- }
+
+ public boolean isActive()
+ {
+ return _active;
+ }
+
+ public boolean isDisabled()
+ {
+ return _disabled;
+ }
+
+ public boolean isNextDisabled()
+ {
+ return hasNext() && _next.isDisabled();
+ }
+
+ public boolean isOverflowEnd()
+ {
+ return _overflowEnd;
+ }
+
+ public boolean isOverflowStart()
+ {
+ return _overflowStart;
+ }
+
+ public boolean isParentEnd()
+ {
+ return _parentEnd;
+ }
+
+ public boolean isParentStart()
+ {
+ return _parentStart;
+ }
+
+ public boolean isPreviousDisabled()
+ {
+ return hasPrevious() && _previous.isDisabled();
+ }
+
+ public boolean isReadOnly()
+ {
+ return _readOnly;
+ }
+
+ public boolean isVisited()
+ {
+ return _visited;
+ }
+
+ public void setDisabled(boolean disabled)
+ {
+ _disabled = disabled;
+ }
+
+ public void setNext(Station next)
+ {
+ _next = next;
+ }
+
+ public void setOverflowEnd(boolean overflowEnd)
+ {
+ _overflowEnd = overflowEnd;
+ }
+
+ public void setOverflowStart(boolean overflowStart)
+ {
+ _overflowStart = overflowStart;
+ _visited = true;
+ }
+
+ public void setParentEnd(boolean parentEnd)
+ {
+ _parentEnd = parentEnd;
+ }
+
+ public void setParentStart(boolean parentStart)
+ {
+ _parentStart = parentStart;
+ }
+
+ public void setPrevious(Station previous)
+ {
+ _previous = previous;
+ }
+
+ public void setReadOnly(boolean readOnly)
+ {
+ _readOnly = readOnly;
+ }
+
+ private boolean _getBooleanAttribute(
+ Map<String, Object> attributes,
+ String attributeName,
+ boolean defaultValue)
+ {
+ Object value = attributes.get(attributeName);
+ if(value == null)
+ {
+ return defaultValue;
+ }
+
+ return Boolean.TRUE.equals(value);
+ }
+ private String _getDisabledUserText(
+ RenderingContext arc,
+ String text)
+ {
+ String altTextKey;
+ if(isActive())
+ {
+ altTextKey = _ACTIVE_KEY;
+ }
+ else if(isVisited())
+ {
+ altTextKey = _VISITED_KEY;
+ }
+ else
+ {
+ altTextKey = _NEXT_KEY;
+ }
- private boolean _setNewPath(UIXProcess component)
- {
- Object focusPath = component.getFocusRowKey();
- component.setRowKey(focusPath);
- return true;
+ String altText =
+ XhtmlUtils.getFormattedString(arc.getTranslatedString(altTextKey),
+ new String[]{text});
+
+ return altText;
+ }
+
+ private List<String> _getIconNames(String baseSelector)
+ {
+ LinkedList<String> names = new LinkedList<String>();
+
+ StringBuilder builder = new StringBuilder(64);
+ builder.append(baseSelector);
+
+ int suffixLength = SkinSelectors.ICON_SUFFIX.length();
+ int baseIndex = builder.length();
+
+ builder.append(SkinSelectors.ICON_SUFFIX);
+ names.addFirst(builder.toString());
+ builder.delete(baseIndex, baseIndex + suffixLength);
+
+ if(isDisabled())
+ {
+ builder.append(_SUFFIX_DISABLED);
+ builder.append(SkinSelectors.ICON_SUFFIX);
+ names.addFirst(builder.toString());
+ }
+ else
+ {
+ if(isActive())
+ {
+ builder.append(_SUFFIX_ACTIVE);
+ }
+ else if(isVisited())
+ {
+ builder.append(_SUFFIX_VISITED);
+ }
+ else
+ {
+ builder.append(_SUFFIX_UNVISITED);
+ }
+
+ baseIndex = builder.length();
+
+ builder.append(SkinSelectors.ICON_SUFFIX);
+ names.addFirst(builder.toString());
+ builder.delete(baseIndex, baseIndex + suffixLength);
+
+ if(isReadOnly())
+ {
+ builder.append(_SUFFIX_READ_ONLY);
+ builder.append(SkinSelectors.ICON_SUFFIX);
+ names.addFirst(builder.toString());
+ }
+ }
+
+ return names;
+ }
+
+ private List<String> _getOverflowEndIconNames()
+ {
+ return _getIconNames(SkinSelectors.AF_TRAIN_OVERFLOW_END_STYLE_CLASS);
+ }
+
+ private List<String> _getOverflowStartIconNames()
+ {
+ return _getIconNames(SkinSelectors.AF_TRAIN_OVERFLOW_START_STYLE_CLASS);
+ }
+
+ private List<String> _getStopIconNames()
+ {
+ return _getIconNames(SkinSelectors.AF_TRAIN_STOP_STYLE_CLASS);
+ }
+
+ private boolean _active; // Is this station the active one?
+ private boolean _disabled; // Disabled attribute
+ private boolean _overflowEnd; // Is this station the next step set link?
+ private boolean _overflowStart; // Is this station the prev step set link?
+ private boolean _parentEnd; // Is this station a parent end?
+ private boolean _parentStart; // Is this station a parent start?
+ private boolean _readOnly; // Read only attribute
+ private boolean _visited; // Is this station visited?
+
+ private int _rowIndex; // Row index
+
+ private Object _rowKey; // Row key
+
+ private String _label; // This station's label
+
+ private Station _next;
+ private Station _previous;
+
+ private Train _train;
}
-
- protected static class TrainState
+
+ private static class ParentTrain
{
- public TrainState()
+ public ParentTrain(
+ RenderingContext arc,
+ UIXProcess process,
+ UIComponent stamp,
+ Train train)
+ {
+ List<Station> stations = train.getStations();
+ int stationCount = stations.size();
+
+ boolean hasParentStart = !stations.get(0).isOverflowStart();
+ boolean hasParentEnd = !stations.get(stationCount - 1).isOverflowEnd();
+
+ if(hasParentStart || hasParentEnd)
+ {
+ Object parentStartRowKey = process.getContainerRowKey();
+ process.setRowKey(parentStartRowKey);
+ int rowIndex = process.getRowIndex();
+ if(hasParentStart)
+ {
+ _parentStart = new Station(train, rowIndex, parentStartRowKey);
+ _parentStart.setParentStart(true);
+ _parentStart.initLabel(arc, stamp);
+ }
+
+ rowIndex = rowIndex + 1;
+
+ // Check if the parent has more steps, render it only if it does
+ hasParentEnd = rowIndex < process.getRowCount();
+ if(hasParentEnd)
+ {
+ process.setRowIndex(rowIndex);
+ _parentEnd = new Station(train, rowIndex, process.getRowKey());
+ _parentEnd.setParentEnd(true);
+ _parentEnd.initLabel(arc, stamp);
+ }
+
+ // Restore the model
+ process.setRowKey(train.getInitialRowKey());
+ }
+ }
+
+ public Station getParentEnd()
{
- station = new TrainRenderer.StationState();
+ return _parentEnd;
}
- public int startIndex;
- public int maxVisitedIndex;
- public int selectedIndex;
- public boolean subTrain;
- public String formName;
- public String id;
- public TrainRenderer.StationState station;
- }
-
- protected static class StationState
- {
-
- public boolean isSelected;
- // is this the station that is right AFTER the selected station.
- public boolean isNext;
- public boolean isVisited; // has this station been visited already?
- public boolean isPreviousLink; // is this the Previous link?
- public boolean isMoreLink; // is this the More link?
- public boolean isDisabled; // is this station disabled?
- public boolean isNextDisabled; // is the next station disabled?
- public boolean isPrevDisabled; // is the previous station disabled?
- public boolean isNextVisited; // is the next station visited?
- public int index; // the index of this node
- } //end StationState
+
+ public Station getParentStart()
+ {
+ return _parentStart;
+ }
+
+ public boolean hasParentEnd()
+ {
+ return _parentEnd != null;
+ }
+
+ public boolean hasParentStart()
+ {
+ return _parentStart != null;
+ }
+
+ private Station _parentEnd;
+ private Station _parentStart;
+ }
- private static final int _MAX_NUM_LINK_INDEX =
- 6; //number of visible links
+ /**
+ * Gives the amount of visible stops that get rendered by default if no
+ * amount is specified by the -ora-visible-stop-count skin property.
+ */
+ public static final int DEFAULT_MAX_VISIBLE_STOP_COUNT = 6;
+
+ /**
+ * Determines if the parent train of sub-trains should be rendered by
+ * default if not specified by the -ora-render-parent-train skin property.
+ */
+ public static final boolean DEFAULT_RENDER_PARENT_TRAIN = false;
+
+ private static final String _STATE_ACTIVE = SkinSelectors.STATE_PREFIX + "Selected";
+ private static final String _STATE_DISABLED = SkinSelectors.STATE_PREFIX + "Disabled";
+ private static final String _STATE_PARENT = SkinSelectors.STATE_PREFIX + "Parent";
+ private static final String _STATE_READ_ONLY = SkinSelectors.STATE_PREFIX + "ReadOnly";
+ private static final String _STATE_UNVISITED = SkinSelectors.STATE_PREFIX + "Unvisited";
+ private static final String _STATE_VISITED = SkinSelectors.STATE_PREFIX + "Visited";
+
+ private static final String _SUFFIX_CONTENT = "-content";
+ private static final String _SUFFIX_ICON_CELL = "-icon-cell";
+
+ private static final String _SUFFIX_ACTIVE = ":selected";
+ private static final String _SUFFIX_DISABLED = ":disabled";
+ private static final String _SUFFIX_READ_ONLY = ":read-only";
+ private static final String _SUFFIX_UNVISITED = ":unvisited";
+ private static final String _SUFFIX_VISITED = ":visited";
/**
- * The following keys are used to get at the corresponding translated
- * strings.
- */
+ * The following keys are used to get at the corresponding translated
+ * strings.
+ */
private static final String _VISITED_KEY = "af_train.VISITED_TIP";
private static final String _ACTIVE_KEY = "af_train.ACTIVE_TIP";
private static final String _NEXT_KEY = "af_train.NEXT_TIP";
@@ -800,23 +1866,22 @@
private static final TrinidadLogger _LOG =
TrinidadLogger.createTrinidadLogger(TrainRenderer.class);
-
- // for now keep the OraLink/OraDisabledLink styles on the 'a', and
- // append train link style class.
- private static final Map<String, String> _RESOURCE_KEY_MAP =
- new HashMap<String, String>();
- private static final String _TRAIN_DISABLED_LINK =
- SkinSelectors.LINK_DISABLED_STYLE_CLASS + " " +
- SkinSelectors.AF_PROCESS_TRAIN_LINK_STYLE_CLASS;
- private static final String _TRAIN_ENABLED_LINK =
- SkinSelectors.LINK_STYLE_CLASS + " " +
- SkinSelectors.AF_PROCESS_TRAIN_LINK_STYLE_CLASS;
-
- static {
- _RESOURCE_KEY_MAP.put(SkinSelectors.LINK_DISABLED_STYLE_CLASS,
- _TRAIN_DISABLED_LINK);
- _RESOURCE_KEY_MAP.put(SkinSelectors.LINK_STYLE_CLASS,
- _TRAIN_ENABLED_LINK);
+
+ private static final String[] _EMPTY_STRING_ARRAY;
+
+ private static final Map<String, String> _RESOURCE_KEY_MAP;
+
+ static
+ {
+ _EMPTY_STRING_ARRAY = new String[0];
+
+ // Not adding the base link classes as before, those are a nuisance
+ // while defining the skin since oyu cannot inhibit them as they're
+ // on the same level as the train selectors.
+ _RESOURCE_KEY_MAP = new TreeMap<String, String>();
+ _RESOURCE_KEY_MAP.put(SkinSelectors.LINK_STYLE_CLASS,
+ SkinSelectors.AF_TRAIN_LINK_STYLE_CLASS);
+ _RESOURCE_KEY_MAP.put(SkinSelectors.LINK_DISABLED_STYLE_CLASS,
+ SkinSelectors.AF_TRAIN_LINK_STYLE_CLASS);
}
-
}
Modified: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinProperties.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinProperties.java?view=diff&rev=451772&r1=451771&r2=451772
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinProperties.java (original)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinProperties.java Sun Oct 1 10:26:55 2006
@@ -39,14 +39,18 @@
// FIXME: Name inconsistency, should be AF_PANEL_HEADER
public static final String AF_PANELHEADER_INDENT_CONTENT =
"af|panelHeader-ora-indent-content";
+ public static final String AF_PANEL_BORDER_LAYOUT_SPACER_WIDTH =
+ "af|panelBorderLayout-ora-spacer-width";
public static final String AF_PANEL_LIST_DEFAULT_COLUMNS =
"af|panelList-ora-default-columns";
public static final String AF_TABLE_REPEAT_CONTROL_BAR =
"af|table-ora-repeat-control-bar";
public static final String AF_TABLE_SELECTION_BAR_IN_TABLE =
"af|table-ora-selection-bar-in-table";
+ public static final String AF_TRAIN_RENDER_PARENT_TRAIN =
+ "af|train-ora-render-parent-train";
+ public static final String AF_TRAIN_VISIBLE_STOP_COUNT =
+ "af|train-ora-visible-stop-count";
public static final String AF_TREE_TABLE_SPACER_WIDTH =
"af|treeTable-ora-spacer-width";
- public static final String AF_PANEL_BORDER_LAYOUT_SPACER_WIDTH =
- "af|panelBorderLayout-ora-spacer-width";
}
RE: svn commit: r451772 [1/8] - in
/incubator/adffaces/trunk/trinidad: src/site/xdoc/
trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/desktop/
trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xh
Posted by Pavitra Subramaniam <pa...@oracle.com>.
Hello Simon,
Thanks for checking in the new train renderer. I have one comment.
- Can you update the af|train::link to be af|train::stop-link, like we agreed upon? ::link is too generic as I have to support a version where the stop icons are links besides the stop label as well.
Thanks
- Pavitra
> -----Original Message-----
> From: slessard@apache.org [mailto:slessard@apache.org]
> Sent: Sunday, October 01, 2006 10:27 AM
> To: adffaces-commits@incubator.apache.org
> Subject: svn commit: r451772 [1/8] - in
> /incubator/adffaces/trunk/trinidad: src/site/xdoc/
> trinidad-impl/src/main/java/org/apache/myfaces/trinidadinterna
l/renderkit/core/desktop/ trinidad-> impl/src/main/java/org/apache/myfaces/trinidadinternal/renderk
> it/core/xht...
>
> Author: slessard
> Date: Sun Oct 1 10:26:55 2006
> New Revision: 451772
>
> URL: http://svn.apache.org/viewvc?view=rev&rev=451772
> Log:
> Applied patch for ADFFACES-60 with some small changes to
> compile with the new public rendering API.
>
> Modified:
> incubator/adffaces/trunk/trinidad/src/site/xdoc/skin-selectors.xml
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/
org/apache/myfaces/trinidadinternal/renderkit/core/desktop/TrainRenderer.> java
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/
org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinProperties.j> ava
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/
org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinSelectors.ja> va
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/resou
rces/META-INF/adf/styles/base-desktop.xss
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/resou
rces/META-INF/adf/styles/minimal-desktop.xss
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resou
rces/org/apache/myfaces/trinidadinternal/renderkit/golden/train-minimal-> golden.xml
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resou
rces/org/apache/myfaces/trinidadinternal/renderkit/golden/train-> minimalIE-golden.xml
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resou
rces/org/apache/myfaces/trinidadinternal/renderkit/golden/train-> minimalIERtl-golden.xml
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resou
rces/org/apache/myfaces/trinidadinternal/renderkit/golden/train-> minimalInacc-golden.xml
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resou
rces/org/apache/myfaces/trinidadinternal/renderkit/golden/train-> minimalSaf-golden.xml
>
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/resou
rces/org/apache/myfaces/trinidadinternal/renderkit/golden/train-> minimalScrRdr-golden.xml
>
> Modified:
> incubator/adffaces/trunk/trinidad/src/site/xdoc/skin-selectors.xml
> URL:
> http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad
> /src/site/xdoc/skin-selectors.xml?view=diff&rev=451772&r1=4517
> 71&r2=451772
> ==============================================================
> ================
> ---
> incubator/adffaces/trunk/trinidad/src/site/xdoc/skin-selectors
> .xml (original)
> +++
> incubator/adffaces/trunk/trinidad/src/site/xdoc/skin-selectors
> .xml Sun Oct 1 10:26:55 2006
> @@ -2954,7 +2954,52 @@
> </tr>
> </table>
> </subsection>
> - <subsection name="tr:processTrain Component">
> + <subsection name="tr:train Component">
> + <table>
> + <tr>
> + <th colspan="2">
> + <i>Properties</i>
> + </th>
> + </tr>
> + <tr>
> + <th>Name</th>
> + <th>Description</th>
> + </tr>
> + <tr>
> + <td>-ora-render-parent-train</td>
> + <td>Boolean value that specifies if parent train
> icons should be
> + rendered if this train is a sub-train. A
> sub-train is a process
> + not located at the root of its TreeModel.</td>
> + </tr>
> + <tr>
> + <td>-ora-visible-stop-count</td>
> + <td>Strictly positive integer value specifying
> the maximum amount of
> + stops visible at a time.</td>
> + </tr>
> + </table>
> + <table>
> + <tr>
> + <th colspan="2">
> + <i>Aliases</i>
> + </th>
> + </tr>
> + <tr>
> + <th>Name</th>
> + <th>Description</th>
> + </tr>
> + <tr>
> + <td>.AFTrainContent:alias</td>
> + <td>Styles all train station content.</td>
> + </tr>
> + <tr>
> + <td>.AFTrainIconCell:alias</td>
> + <td>Styles all train station icons.</td>
> + </tr>
> + <tr>
> + <td>.AFTrainJoin:alias</td>
> + <td>Styles all train station joins.</td>
> + </tr>
> + </table>
> <table>
> <tr>
> <th colspan="2">
> @@ -2966,33 +3011,215 @@
> <th>Description</th>
> </tr>
> <tr>
> - <td>af|processTrain::step-active</td>
> - <td>Styles the active train station.</td>
> + <td>af|train</td>
> + <td>Styles the whole train.</td>
> + </tr>
> + <tr>
> + <td>af|train::stop</td>
> + <td>Styles a train stop. A stop include both the
> icon and its content.
> + This selector is often combined with one or
> more station pseudo-classes like
> + :selected, :unvisited, :disabled, :read-only
> and .p_AFVisited and
> + used in descendant selector, e.g.
> "af|train::stop:unvisited af|train::link"
> + would style the link generated for an
> unvisited stop.</td>
> + </tr>
> + <tr>
> + <td>af|train::stop-icon-cell</td>
> + <td>Styles the icon section of the stop. This
> selector is combinable
> + with state pseudo-classes. This selector
> includes .AFTrainIconCell:alias.
> + </td>
> </tr>
> <tr>
> - <td>af|processTrain::step-visited</td>
> - <td>Styles the visited train stations.</td>
> + <td>af|train::stop-content</td>
> + <td>Styles the content section of the stop. This
> selector is combinable
> + with state pseudo-classes. This selector
> includes .AFTrainContent:alias.
> + </td>
> </tr>
> <tr>
> - <td>af|processTrain::step-disabled</td>
> - <td>Styles the disabled train stations.</td>
> + <td>af|train::join</td>
> + <td>Styles the join between stop icons. This
> selector is combinable with state
> + pseudo-classes, except :selected. This
> selector includes .AFTrainJoin:alias.
> + </td>
> </tr>
> <tr>
> - <td>af|processTrain::step-unvisited</td>
> - <td>Styles the unvisited train stations.</td>
> + <td>af|train::overflow-start</td>
> + <td>Styles a train start overflow. A start
> overflow is generated when the amount
> + of steps in the process is higher than the
> amount of visibled stop defined by
> + the -ora-visible-stop-count property. In LTR
> mode, this selector represents
> + the left side overflow (previous step
> group). This selector includes both the
> + icon and its content. This selector is
> combinable with state pseudo-classes.</td>
> </tr>
> <tr>
> - <td>.AFTrainStation:alias</td>
> - <td>Style that is included by all of the
> af|processTrain* style
> - classes.</td>
> + <td>af|train::overflow-start-icon-cell</td>
> + <td>Styles the icon section of the
> overflow-start. This selector is combinable
> + with state pseudo-classes. This selector
> includes .AFTrainIconCell:alias.
> + </td>
> </tr>
> <tr>
> - <td>af|processTrain::step-visited
> af|processTrain:: link</td>
> - <td>Styles the visited train stations links.</td>
> + <td>af|train::overflow-start-content</td>
> + <td>Styles the content section of the
> overflow-start. This selector is combinable
> + with state pseudo-classes. This selector
> includes .AFTrainContent:alias.
> + </td>
> + </tr>
> + <tr>
> + <td>af|train::overflow-end</td>
> + <td>Styles a train end overflow. A end overflow
> is generated when the amount
> + of steps in the process is higher than the
> amount of visibled stop defined by
> + the -ora-visible-stop-count property. In LTR
> mode, this selector represents
> + the right side overflow (next step group).
> This selector includes both the
> + icon and its content. This selector is
> combinable with state pseudo-classes.</td>
> + </tr>
> + <tr>
> + <td>af|train::overflow-end-icon-cell</td>
> + <td>Styles the icon section of the overflow-end.
> This selector is combinable
> + with state pseudo-classes. This selector
> includes .AFTrainIconCell:alias.
> + </td>
> + </tr>
> + <tr>
> + <td>af|train::overflow-end-content</td>
> + <td>Styles the content section of the
> overflow-end. This selector is combinable
> + with state pseudo-classes. This selector
> includes .AFTrainContent:alias.
> + </td>
> + </tr>
> + <tr>
> + <td>af|train::join-overflow</td>
> + <td>Styles the join between overflows and stop
> icons. This selector is combinable
> + with state pseudo-classes, except :selected.
> This selector includes
> + .AFTrainJoin:alias.</td>
> + </tr>
> + <tr>
> + <td>af|train::parent-start</td>
> + <td>Styles a train start parent. A parent is
> generated when the current train is
> + not located at the root of its TreeModel and
> that -ora-render-parent-train
> + property is set to true. In LTR mode this
> will be rendered to the left of the
> + first step's stop. This selector includes
> both the icon and its content.
> + This selector is NOT combinable with state
> pseudo-classes.</td>
> + </tr>
> + <tr>
> + <td>af|train::parent-start-icon-cell</td>
> + <td>Styles the icon section of the parent-start.
> This selector is NOT combinable
> + with state pseudo-classes. This selector
> includes .AFTrainIconCell:alias.
> + </td>
> + </tr>
> + <tr>
> + <td>af|train::parent-start-content</td>
> + <td>Styles the content section of the
> parent-start. This selector is NOT combinable
> + with state pseudo-classes. This selector
> includes .AFTrainContent:alias.
> + </td>
> + </tr>
> + <tr>
> + <td>af|train::parent-end</td>
> + <td>Styles a train end parent. A parent is
> generated when the current train is
> + not located at the root of its TreeModel and
> that -ora-render-parent-train
> + property is set to true. In LTR mode this
> will be rendered to the right of
> + the last step's stop. This selector includes
> both the icon and its content.
> + This selector is NOT combinable with state
> pseudo-classes.</td>
> + </tr>
> + <tr>
> + <td>af|train::parent-end-icon-cell</td>
> + <td>Styles the icon section of the parent-end.
> This selector is NOT combinable
> + with state pseudo-classes. This selector
> includes .AFTrainIconCell:alias.
> + </td>
> + </tr>
> + <tr>
> + <td>af|train::parent-end-content</td>
> + <td>Styles the content section of the
> parent-end. This selector is NOT combinable
> + with state pseudo-classes. This selector
> includes .AFTrainContent:alias.
> + </td>
> + </tr>
> + <tr>
> + <td>af|train::join-parent</td>
> + <td>Styles the join between parent and stop
> icons. This selector is NOT combinable
> + with state pseudo-classes. This selector
> includes .AFTrainJoin:alias.</td>
> + </tr>
> + <tr>
> + <td>af|train::link</td>
> + <td>Styles the links generated within the stop's
> content. This selector is
> + NOT combinable with state pseudo-classes</td>
> + </tr>
> + </table>
> + <table>
> + <tr>
> + <th colspan="2">
> + <i>Icons</i>
> + </th>
> + </tr>
> + <tr>
> + <th>Name</th>
> + <th>Description</th>
> </tr>
> <tr>
> - <td>af|processTrain::step-unvisited
> af|processTrain::link</td>
> - <td>Styles the unvisited train stations links.</td>
> + <td colspan="2">
> + Stop and overflow icons are combinable with
> one or more state pseudo-classes.
> + For example, it's possible to build icons for
> a very specific situations like
> + a read-only visited stop being different from
> a read-only unvisited stop. The
> + valid classes are:
> + <ul>
> + <li>:visited for steps that were already
> completed (assumed to be all steps
> + before the current one, this might
> change in the future);</li>
> + <li>:selected for the current step. This
> state is not available to overflows;
> + </li>
> + <li>:unvisited for steps that were not
> completed by the user (assumed to be
> + all steps after the current one, this
> might change in the future);</li>
> + <li>:read-only for steps that cannot be
> accessed directly by the user by
> + clicking on the link (clicking on the
> icon is not implemented at this
> + time). This state is combinable with any
> of the previous three states,
> + but must be placed after them, e.g.
> :selected:read-only-icon is valid,
> + while :read-only:selected is not;</li>
> + <li>:disabled for steps that cannot be
> accessed by the user using the link
> + and should theorically not be accessible
> at all until some condition is
> + met. This state has absolute priority
> and is not combinable with any other
> + state.</li>
> + </ul>
> + </td>
> + </tr>
> + <tr>
> + <td>af|train::stop<states>-icon</td>
> + <td>Define the icons for stops. At least one
> state must be specified.
> + For example:
> + <ul>
> + <li>VALID: af|train::stop:selected-icon;</li>
> + <li>INVALID: af|train::stop-icon;</li>
> + </ul></td>
> + </tr>
> + <tr>
> + <td>af|train::overflow-start<states>-icon</td>
> + <td>Define the icons for overflows toward the
> previous step group. At least one
> + state must be specified.
> + For example:
> + <ul>
> + <li>VALID:
> af|train::overflow-start:read-only-icon;</li>
> + <li>INVALID: af|train::overflow-start-icon;</li>
> + </ul></td>
> + </tr>
> + <tr>
> + <td>af|train::overflow-end<states>-icon</td>
> + <td>Define the icons for overflows toward the
> next step group. At least one
> + state must be specified.
> + For example:
> + <ul>
> + <li>VALID:
> af|train::overflow-end:read-only-icon;</li>
> + <li>INVALID: af|train::overflow-end-icon;</li>
> + </ul></td>
> + </tr>
> + <tr>
> + <td>af|train::parent-start<states>-icon</td>
> + <td>Define the icons for the parent train that
> include this train.
> + It appears before the first stop's icon.
> This icon is NOT
> + combinable with state pseudo-classes. For example:
> + <ul>
> + <li>VALID: af|train::parent-start-icon;</li>
> + <li>INVALID:
> af|train::parent-start:read-only-icon;</li>
> + </ul></td>
> + </tr>
> + <tr>
> + <td>af|train::parent-end<states>-icon</td>
> + <td>Define the icons for the parent train that
> follow the parent train
> + including this train. It appears after the
> last stop's icon. This
> + icon is NOT combinable with state
> pseudo-classes. For example:
> + <ul>
> + <li>VALID: af|train::parent-end-icon;</li>
> + <li>INVALID:
> af|train::parent-end:read-only-icon;</li>
> + </ul></td>
> </tr>
> </table>
> </subsection>
> @@ -3119,7 +3346,7 @@
> </tr>
> </table>
> </subsection>
> - <subsection name="tr:selectInputDate Component">
> + <subsection name="tr:inputDate Component">
> <table>
> <tr>
> <th colspan="2">
>
> Modified:
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/
org/apache/myfaces/trinidadinternal/renderkit/core/desktop/TrainRenderer.> java
> URL:
> http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad
> /trinidad-impl/src/main/java/org/apache/myfaces/trinidadintern
al/renderkit/core/desktop/TrainRenderer.java?view=diff&rev=451772&r1=> 451771&r2=451772
> ==============================================================
> ================
> ---
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/
org/apache/myfaces/trinidadinternal/renderkit/core/desktop/TrainRenderer.> java (original)
> +++
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/
org/apache/myfaces/trinidadinternal/renderkit/core/desktop/TrainRenderer.> java Sun Oct 1 10:26:55 2006
> @@ -18,8 +18,14 @@
>
>
> import java.io.IOException;
> -import java.util.HashMap;
> +import java.util.ArrayList;
> +import java.util.Collections;
> +import java.util.Iterator;
> +import java.util.LinkedList;
> +import java.util.List;
> +import java.util.ListIterator;
> import java.util.Map;
> +import java.util.TreeMap;
>
> import javax.faces.component.UIComponent;
> import javax.faces.context.FacesContext;
> @@ -29,11 +35,14 @@
> import org.apache.myfaces.trinidad.bean.FacesBean;
> import org.apache.myfaces.trinidad.component.UIXProcess;
> import org.apache.myfaces.trinidad.component.core.nav.CoreTrain;
> -import org.apache.myfaces.trinidad.logging.TrinidadLogger;
> +import org.apache.myfaces.trinidad.context.Agent;
> import org.apache.myfaces.trinidad.context.FormData;
> import org.apache.myfaces.trinidad.context.RenderingContext;
> +import org.apache.myfaces.trinidad.logging.TrinidadLogger;
> +import org.apache.myfaces.trinidad.skin.Icon;
> import
> org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.OutputUtils;
> import
> org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.ProcessUtils;
> +import
> org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SkinP
> roperties;
> import
> org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SkinS
> electors;
> import
> org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.Xhtml
> Constants;
> import
> org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.Xhtml
> Renderer;
> @@ -41,7 +50,7 @@
>
> /**
> * Renderer for process train components
> - * * <p>
> + *
> */
> public class TrainRenderer
> extends XhtmlRenderer
> @@ -144,49 +153,78 @@
>
> @Override
> protected void encodeAll(
> - FacesContext context,
> + FacesContext context,
> RenderingContext arc,
> - UIComponent component,
> - FacesBean bean)
> + UIComponent component,
> + FacesBean bean)
> throws IOException
> {
> + if(!(component instanceof UIXProcess))
> + {
> + throw new ClassCastException("TrainRenderer can only
> renders instances of " +
> + UIXProcess.class.getName() +
> + ", found " +
> + component.getClass().getName());
> + }
> +
> UIXProcess process = (UIXProcess) component;
> UIComponent stamp = process.getNodeStamp();
>
> if (stamp != null)
> {
> - Object oldPath = process.getRowKey();
> - Object newPath = null;
> - boolean isNewPath = _setNewPath(process);
> - if (isNewPath)
> + Train train = new Train(context, arc, process, stamp);
> + try
> {
> + process.setRowKey(train.getFocusRowKey());
> +
> + // Renders some fields and scripts
> + _renderHiddenFields(context, arc, train);
> +
> ResponseWriter writer = context.getResponseWriter();
> -
> - TrainRenderer.TrainState trainState =
> - _getTrainState(context, arc, process);
> - _renderHiddenFields(context, arc, trainState);
> -
> - writer.startElement("table", component);
> - OutputUtils.renderLayoutTableAttributes(context,
> arc, "0", null);
> - writer.writeAttribute("align", "center", null);
> - newPath = process.getRowKey();
> - process.setRowKey(oldPath);
> +
> + // Need to render the frame even if there's no
> visible station
> + // to support PPR.
> + writer.startElement(XhtmlConstants.TABLE_ELEMENT, component);
> + process.setRowKey(train.getInitialRowKey());
> renderId(context, component);
> - process.setRowKey(newPath);
> renderAllAttributes(context, arc, bean);
> -
> - int length = process.getRowCount();
> -
> - if (length == 0)
> - return;
> -
> - _encodeChildren(context, arc, process, stamp,
> trainState, length);
> -
> - writer.endElement("table");
> -
> - process.setRowKey(oldPath);
> + // Does not seem to be needed and this is not XHTML
> 1.0 Strict compliant
> + // writer.writeAttribute("align", "center", null);
> +
> + if(!train.getStations().isEmpty())
> + {
> + // There're visible stations currently, let render them.
> +
> writer.startElement(XhtmlConstants.TABLE_BODY_ELEMENT, null);
> + _renderTrain(context, arc, process, bean, stamp, train);
> + writer.endElement(XhtmlConstants.TABLE_BODY_ELEMENT);
> + }
> +
> + writer.endElement(XhtmlConstants.TABLE_ELEMENT);
> }
> + finally
> + {
> + // Always restore the model, whatever happened
> + process.setRowKey(train.getInitialRowKey());
> + }
> + }
> + else
> + {
> + _LOG.warning("Train expect a nodeStamp facet, " +
> + "no such facet was found for train " + component);
> }
> + /*
> + _encodeChildren(context, arc, process, stamp,
> trainState, length);
> + */
> + }
> +
> + @Override
> + protected void renderAllAttributes(
> + FacesContext context,
> + RenderingContext arc,
> + FacesBean bean) throws IOException
> + {
> + super.renderAllAttributes(context, arc, bean);
> + OutputUtils.renderLayoutTableAttributes(context, arc, "0", null);
> }
>
> /**
> @@ -195,603 +233,1631 @@
> */
> @Override
> protected void renderStyleAttributes(
> - FacesContext context,
> + FacesContext context,
> RenderingContext arc,
> - FacesBean bean)
> + FacesBean bean)
> throws IOException
> {
> - renderStyleAttributes(context, arc, bean,
> -
> SkinSelectors.AF_PROCESS_TRAIN_STYLE_CLASS);
> + renderStyleAttributes(context,
> + arc,
> + bean,
> + SkinSelectors.AF_TRAIN_ROOT_STYLE_CLASS);
> + }
> +
> + private void _preRenderIconBlock(
> + FacesContext context,
> + RenderingContext arc) throws IOException
> + {
> + ResponseWriter writer = context.getResponseWriter();
> +
> + // Icon cell
> + writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
> +
> + // Icons need to be in a table to stretch well
> + writer.startElement(XhtmlConstants.TABLE_ELEMENT, null);
> + OutputUtils.renderLayoutTableAttributes(context, arc, "0", null);
> + writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE,
> "width: 100%", null);
> +
> + writer.startElement(XhtmlConstants.TABLE_BODY_ELEMENT, null);
> + writer.startElement(XhtmlConstants.TABLE_ROW_ELEMENT, null);
> + }
> +
> + private void _postRenderIconBlock(FacesContext context)
> throws IOException
> + {
> + ResponseWriter writer = context.getResponseWriter();
> +
> + writer.endElement(XhtmlConstants.TABLE_ROW_ELEMENT);
> + writer.endElement(XhtmlConstants.TABLE_BODY_ELEMENT);
> + writer.endElement(XhtmlConstants.TABLE_ELEMENT);
> + writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
> }
>
> -
> - /**
> - * Initialize the station state
> - */
> - private void _initializeStationState(
> - FacesContext context,
> + private void _renderHiddenFields(
> + FacesContext context,
> RenderingContext arc,
> - TrainRenderer.TrainState train,
> - TrainRenderer.StationState station,
> - int currVisChildIndex,
> - int prevVisChildIndex,
> - int nextVisChildIndex,
> - boolean isCurrChildDisabled,
> - boolean isPrevChildDisabled,
> - boolean isNextChildDisabled)
> + Train train)
> + throws IOException
> {
> - station.isPreviousLink = false;
> - station.isMoreLink = false;
> - station.isDisabled = false;
> - station.isNextDisabled = false;
> - station.isPrevDisabled = false;
> - station.index = currVisChildIndex;
> + if((train.getFormName() != null) && supportsScripting(arc))
> + {
> + // render hidden fields to hold the form data
> + FormData formData = arc.getFormData();
> + if (formData != null)
> + {
> + formData.addNeededValue(XhtmlConstants.EVENT_PARAM);
> + formData.addNeededValue(XhtmlConstants.SOURCE_PARAM);
> + formData.addNeededValue(XhtmlConstants.VALUE_PARAM);
> + formData.addNeededValue(XhtmlConstants.SIZE_PARAM);
> + }
>
> - // train.startIndex is the index into the List that is the
> - // start of the train. The algorithm is dependent upon
> the BLAF spec.
> - if (currVisChildIndex == train.startIndex - 1)
> + // Render script submission code.
> + ProcessUtils.renderNavSubmitScript(context, arc);
> + }
> + }
> +
> + private void _renderContentRowLtr(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + UIComponent stamp,
> + Train train) throws IOException
> + {
> + ParentTrain parentTrain = train.getParentTrain();
> +
> + // Render parent start
> + if(parentTrain != null && parentTrain.hasParentStart())
> + {
> + _renderParentContent(context, arc,
> parentTrain.getParentStart());
> + }
> +
> + for(Station station : train.getStations())
> + {
> + _renderStationContent(context, arc, process, stamp, station);
> + }
> +
> + // Render parent end
> + if(parentTrain != null && parentTrain.hasParentEnd())
> {
> - station.isPreviousLink = true;
> + _renderParentContent(context, arc, parentTrain.getParentEnd());
> }
> - else if (currVisChildIndex == train.startIndex +
> _MAX_NUM_LINK_INDEX)
> + }
> +
> + private void _renderContentRowRtl(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + UIComponent stamp,
> + Train train) throws IOException
> + {
> + ParentTrain parentTrain = train.getParentTrain();
> +
> + // Render parent start
> + if(parentTrain != null && parentTrain.hasParentEnd())
> + {
> + _renderParentContent(context, arc, parentTrain.getParentEnd());
> + }
> +
> + List<Station> stations = train.getStations();
> + ListIterator<Station> iterator =
> stations.listIterator(stations.size());
> + while(iterator.hasPrevious())
> + {
> + _renderStationContent(context, arc, process, stamp,
> iterator.previous());
> + }
> +
> + // Render parent end
> + if(parentTrain != null && parentTrain.hasParentStart())
> {
> - station.isMoreLink = true;
> + _renderParentContent(context, arc,
> parentTrain.getParentStart());
> }
> + }
> +
> + private void _renderIconBlock(
> + FacesContext context,
> + RenderingContext arc,
> + List<String> iconNames,
> + String shortDesc,
> + String styleClass,
> + String iconStyleClass,
> + List<String> stateStyleClasses) throws IOException
> + {
> + ResponseWriter writer = context.getResponseWriter();
>
> - // selected nodes cannot be disabled,
> - // so don't bother getting disabled attribute for the
> selected node
> -
> - if (currVisChildIndex != NO_CHILD_INDEX &&
> - currVisChildIndex != train.selectedIndex)
> + writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
> +
> + stateStyleClasses.add(styleClass);
> + stateStyleClasses.add(iconStyleClass);
> +
> + renderStyleClasses(context,
> + arc,
> +
> stateStyleClasses.toArray(_EMPTY_STRING_ARRAY));
> +
> + if(iconNames != null)
> + {
> + // Render the first valid icon found. The list should be in
> + // decreasing priority order.
> + for(String iconName : iconNames)
> + {
> + Icon icon = arc.getIcon(iconName);
> + if(icon != null)
> + {
> + OutputUtils.renderIcon(context, arc, icon,
> shortDesc, null);
> + break;
> + }
> + }
> + }
> +
> + writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
> + }
> +
> + private void _renderIconRowLtr(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + UIComponent stamp,
> + Train train) throws IOException
> + {
> + ParentTrain parentTrain = train.getParentTrain();
> +
> + // Render parent start
> + if(parentTrain != null && parentTrain.hasParentStart())
> + {
> + _renderParentStartLtr(context, arc, process, train);
> + }
> +
> + for(Station station : train.getStations())
> + {
> + _renderStationIconLtr(context, arc, process, station);
> + }
> +
> + // Render parent end
> + if(parentTrain != null && parentTrain.hasParentEnd())
> {
> - station.isDisabled = isCurrChildDisabled;
> + _renderParentEndLtr(context, arc, process, train);
> }
> -
> - // get disabled information about the previous and the
> next child.
> - // selectedIndex cannot act disabled
> - //
> - if (prevVisChildIndex != NO_CHILD_INDEX &&
> - prevVisChildIndex != train.selectedIndex)
> + }
> +
> + private void _renderIconRowRtl(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + UIComponent stamp,
> + Train train) throws IOException
> + {
> + ParentTrain parentTrain = train.getParentTrain();
> +
> + // Render parent end
> + if(parentTrain != null && parentTrain.hasParentEnd())
> + {
> + _renderParentEndRtl(context, arc, process, train);
> + }
> +
> + List<Station> stations = train.getStations();
> + ListIterator<Station> iterator =
> stations.listIterator(stations.size());
> + while(iterator.hasPrevious())
> + {
> + _renderStationIconRtl(context, arc, process,
> iterator.previous());
> + }
> +
> + // Render parent start
> + if(parentTrain != null && parentTrain.hasParentStart())
> {
> - station.isPrevDisabled = isPrevChildDisabled;
> + _renderParentStartRtl(context, arc, process, train);
> }
> -
> - if (nextVisChildIndex != NO_CHILD_INDEX &&
> - nextVisChildIndex != train.selectedIndex)
> +
> + }
> +
> + private void _renderJoin(
> + FacesContext context,
> + RenderingContext arc,
> + String stateStyleClass,
> + boolean overflow) throws IOException
> + {
> + if(stateStyleClass == _STATE_PARENT)
> + {
> + _renderJoin(context,
> + arc,
> + SkinSelectors.AF_TRAIN_PARENT_JOIN_STYLE_CLASS,
> + null);
> + }
> + else if(overflow)
> + {
> + _renderJoin(context,
> + arc,
> + SkinSelectors.AF_TRAIN_OVERFLOW_JOIN_STYLE_CLASS,
> + stateStyleClass);
> + }
> + else
> {
> - station.isNextDisabled = isNextChildDisabled;
> -
> + _renderJoin(context,
> + arc,
> + SkinSelectors.AF_TRAIN_JOIN_STYLE_CLASS,
> + stateStyleClass);
> }
> + }
> +
> + private void _renderJoin(
> + FacesContext context,
> + RenderingContext arc,
> + String joinStyleClass,
> + String stateStyleClass) throws IOException
> + {
> + ResponseWriter writer = context.getResponseWriter();
>
> - //
> - // get the selected and visited flags for our node
> - //
> - station.isSelected = (currVisChildIndex == train.selectedIndex);
> - station.isVisited = (currVisChildIndex <= train.maxVisitedIndex);
> - station.isNextVisited = (currVisChildIndex <
> train.maxVisitedIndex);
> - station.isNext = (currVisChildIndex ==
> (train.maxVisitedIndex + 1));
> - // if previous station is "next", and disabled, mark
> this as "next".
> - if ((currVisChildIndex - 1 == (train.maxVisitedIndex + 1)) &&
> - (station.isPrevDisabled))
> + writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
> + renderStyleClasses(context,
> + arc,
> + new String[]{
> + joinStyleClass,
> + stateStyleClass});
> +
> + writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
> + }
> +
> + private void _renderJoinIconBlock(
> + FacesContext context,
> + RenderingContext arc,
> + String stateStyleClass,
> + boolean overflow) throws IOException
> + {
> + if(stateStyleClass == _STATE_PARENT)
> + {
> + _renderJoinIconBlock(context,
> + arc,
> +
> SkinSelectors.AF_TRAIN_PARENT_JOIN_STYLE_CLASS,
> + null);
> + }
> + else if(overflow)
> + {
> + _renderJoinIconBlock(context,
> + arc,
> +
> SkinSelectors.AF_TRAIN_OVERFLOW_JOIN_STYLE_CLASS,
> + stateStyleClass);
> + }
> + else
> {
> - station.isNext = true;
> + _renderJoinIconBlock(context,
> + arc,
> + SkinSelectors.AF_TRAIN_JOIN_STYLE_CLASS,
> + stateStyleClass);
> }
> }
> -
> - /**
> - * Returns the MAX_VISITED_ATTR
> - * @todo =-=jmw Hopefully the controller will tell us this someday.
> - */
> - private static Object _getMaxVisited(
> - RenderingContext arc,
> - UIComponent component)
> +
> + private void _renderJoinIconBlock(
> + FacesContext context,
> + RenderingContext arc,
> + String joinStyleClass,
> + String stateStyleClass) throws IOException
> {
> - // return component.getAttributes().get("maxVisited");
> - return null;
> - }
> + ResponseWriter writer = context.getResponseWriter();
>
> - /**
> - * Get the maxVisited attribute from the node and return it.
> - */
> - private int _getMaxVisitedIndex(
> - RenderingContext arc,
> - UIComponent component)
> + writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
> + writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE,
> "width: 50%", null);
> + renderStyleClasses(context,
> + arc,
> + new String[]{
> + joinStyleClass,
> + stateStyleClass});
> + writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
> + }
> +
> + private void _renderParentContent(
> + FacesContext context,
> + RenderingContext arc,
> + Station parent) throws IOException
> {
> - int maxVisitedIndex = NO_CHILD_INDEX;
> - Integer maxVisited = (Integer) _getMaxVisited(arc, component);
> - if (maxVisited != null)
> - {
> - maxVisitedIndex = maxVisited.intValue();
> + ResponseWriter writer = context.getResponseWriter();
> +
> + String baseStyleClass = parent.getBaseStyleClass();
> + writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
> + writer.writeAttribute(XhtmlConstants.COLSPAN_ATTRIBUTE,
> "3", null);
> + renderStyleClasses(context,
> + arc,
> + new String[]{
> + baseStyleClass,
> + baseStyleClass + _SUFFIX_CONTENT});
> +
> + /* -= Simon =-
> + * FIXME HACK for MSIE CSS bug involving composite style classes.
> + * Since the bug is most obvious with join
> background images
> + * I hard code background-image to none to fix it.
> + * See Jira for issue ADFFACES-206.
> + */
> +
> if(arc.getAgent().getAgentName().equalsIgnoreCase(Agent.AGENT_IE))
> + {
> + writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE,
> + "background-image:none;",
> + null);
> }
> - return maxVisitedIndex;
> +
> + writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
> }
> -
> - /**
> - * Return what the starting index into the stations List.
> - */
> - private int _getStartIndex(int numPages, int originalSelectedIndex)
> +
> + private void _renderParentEnd(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Train train,
> + String leftState,
> + String rightState) throws IOException
> + {
> + // Add join
> + _renderJoin(context, arc, leftState, false);
> +
> + // Icon cell
> + _preRenderIconBlock(context, arc);
> +
> + // Add join
> + _renderJoinIconBlock(context, arc, leftState, false);
> +
> + // Add the parent's stop icon
> + _renderParentEndIconBlock(context, arc, process, train);
> +
> + // Add join
> + _renderJoinIconBlock(context, arc, rightState, false);
> +
> + // End icon cell
> + _postRenderIconBlock(context);
> +
> + // Add join
> + _renderJoin(context, arc, rightState, false);
> + }
> +
> + private void _renderParentEndLtr(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Train train) throws IOException
> + {
> + _renderParentEnd(context,
> + arc,
> + process,
> + train,
> + _STATE_PARENT,
> + null);
> + }
> +
> + private void _renderParentEndRtl(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Train train) throws IOException
> + {
> + _renderParentEnd(context,
> + arc,
> + process,
> + train,
> + null,
> + _STATE_PARENT);
> + }
> +
> + private void _renderParentEndIconBlock(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Train train) throws IOException
> + {
> + assert train.getParentTrain().hasParentEnd();
> +
> + Station parent = train.getParentTrain().getParentEnd();
> +
> + process.setRowKey(parent.getRowKey());
> +
> + _renderStationIconBlock(context, arc, process, parent);
> +
> + // Restore model
> + process.setRowKey(train.getInitialRowKey());
> + }
> +
> + private void _renderParentStartIconBlock(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Train train) throws IOException
> + {
> + assert train.getParentTrain().hasParentStart();
> +
> + Station parent = train.getParentTrain().getParentStart();
> +
> + process.setRowKey(parent.getRowKey());
> +
> + _renderStationIconBlock(context, arc, process, parent);
> +
> + // Restore model
> + process.setRowKey(train.getInitialRowKey());
> + }
> +
> + private void _renderParentStart(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Train train,
> + String leftState,
> + String rightState) throws IOException
> + {
> + // Add join
> + _renderJoin(context, arc, leftState, false);
> +
> + // Icon cell
> + _preRenderIconBlock(context, arc);
> +
> + // Add join
> + _renderJoinIconBlock(context, arc, leftState, false);
> +
> + // Add the parent's stop icon
> + _renderParentStartIconBlock(context, arc, process, train);
> +
> + // Add join
> + _renderJoinIconBlock(context, arc, rightState, false);
> +
> + _postRenderIconBlock(context);
> + // End icon cell
> +
> + // Add join
> + _renderJoin(context, arc, rightState, false);
> + }
> +
> + private void _renderParentStartLtr(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Train train) throws IOException
> + {
> + _renderParentStart(context,
> + arc,
> + process,
> + train,
> + null,
> + _STATE_PARENT);
> + }
> +
> + private void _renderParentStartRtl(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Train train) throws IOException
> + {
> + _renderParentStart(context,
> + arc,
> + process,
> + train,
> + _STATE_PARENT,
> + null);
> + }
> +
> + private void _renderStationContent(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + UIComponent stamp,
> + Station station) throws IOException
> {
> - int currentMinIndex = 0;
> -
> - if (numPages <= _MAX_NUM_LINK_INDEX)
> - return currentMinIndex;
> -
> - int selectedIndex = originalSelectedIndex;
> - int currentMaxIndex = _MAX_NUM_LINK_INDEX - 1;
> -
> - if (selectedIndex < currentMaxIndex)
> + ResponseWriter writer = context.getResponseWriter();
> +
> + writer.startElement(XhtmlConstants.TABLE_DATA_ELEMENT, null);
> +
> + writer.writeAttribute(XhtmlConstants.COLSPAN_ATTRIBUTE,
> "3", null);
> +
> + String baseStyleClass = station.getBaseStyleClass();
> +
> + List<String> stateStyleClasses = station.getStates();
> + stateStyleClasses.add(baseStyleClass);
> + stateStyleClasses.add(baseStyleClass + _SUFFIX_CONTENT);
> +
> + renderStyleClasses(context,
> + arc,
> +
> stateStyleClasses.toArray(_EMPTY_STRING_ARRAY));
> +
> + /* -= Simon =-
> + * FIXME HACK for MSIE CSS bug involving composite style classes.
> + * Since the bug is most obvious with join
> background images
> + * I hard code background-image to none to fix it.
> + * See Jira for issue ADFFACES-206.
> + */
> +
> if(arc.getAgent().getAgentName().equalsIgnoreCase(Agent.AGENT_IE))
> + {
> + writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE,
> + "background-image:none;",
> + null);
> + }
> +
> + Map<String, String> originalMap = arc.getSkinResourceKeyMap();
> +
> + // Init the model
> + process.setRowIndex(station.getRowIndex());
> + try
> {
> - return currentMinIndex; //0
> + arc.setSkinResourceKeyMap(_RESOURCE_KEY_MAP);
> + encodeChild(context, stamp);
> }
> -
> - // the algorithm below works, but I thought it was too cryptic
> - // return (selectedIndex -
> - // (((selectedIndex-1)%(_MAX_NUM_LINK_INDEX-2))+1));
> -
> - // loop until the selectedIndex range is found or
> - // we have gone past the number of nodes in the train.
> - // Then we'll know what index to start the visible
> portion of the train.
> - while (numPages > currentMaxIndex)
> + finally
> {
> - currentMinIndex = currentMaxIndex - 1;
> - currentMaxIndex += (_MAX_NUM_LINK_INDEX - 2);
> - if (selectedIndex > currentMinIndex &&
> - selectedIndex < currentMaxIndex)
> - return currentMinIndex;
> + arc.setSkinResourceKeyMap(originalMap);
> }
> -
> - return currentMinIndex;
> +
> + writer.endElement(XhtmlConstants.TABLE_DATA_ELEMENT);
> }
> -
> -
> - /**
> - * Gather up the train state: selectedIndex,
> maxVisitedIndex, startIndex,
> - * isSubTrain, formName, id,.
> - * This way all the parameters we need to pass around to
> various methods
> - * are all in one place, the TrainState
> - * @param arc RenderingContext
> - * @param context FacesContext
> - * @param process the UIXProcess component.
> - * @return
> - */
> - private TrainState _getTrainState(
> - FacesContext context,
> - RenderingContext arc,
> - UIXProcess process)
> - {
> - TrainRenderer.TrainState state =
> - new TrainRenderer.TrainState();
> -
> - state.selectedIndex = process.getRowIndex();
> -
> - // get highest node in train visited
> - state.maxVisitedIndex = _getMaxVisitedIndex(arc, process);
> -
> - // default to selectedIndex if it wasn't set
> - // or if it was set to be greater than selectedIndex
> - if (state.maxVisitedIndex == NO_CHILD_INDEX ||
> - state.maxVisitedIndex < state.selectedIndex)
> - {
> - state.maxVisitedIndex = state.selectedIndex;
> - }
> -
> - int totalPages = process.getRowCount();
> - state.startIndex = _getStartIndex(totalPages,
> state.selectedIndex);
> -
> - state.subTrain = _isSubTrain(process);
> -
> - state.formName = arc.getFormData().getName();
> -
> - String id = process.getClientId(context);
> - state.id = (id != null)? id: null;
> -
> - return state;
> +
> + private void _renderStationIcon(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Station station,
> + String leftJoinState,
> + String rightJoinState,
> + boolean overflowLeft,
> + boolean overflowRight) throws IOException
> + {
> + // Add join
> + _renderJoin(context, arc, leftJoinState, overflowLeft);
> +
> + // Icon cell
> + _preRenderIconBlock(context, arc);
> +
> + // Add join
> + _renderJoinIconBlock(context, arc, leftJoinState, overflowLeft);
> +
> + // Add the parent's stop icon
> + _renderStationIconBlock(context, arc, process, station);
> +
> + // Add join
> + _renderJoinIconBlock(context, arc, rightJoinState,
> overflowRight);
> +
> + // End icon cell
> + _postRenderIconBlock(context);
> +
> + // Add join
> + _renderJoin(context, arc, rightJoinState, overflowRight);
> }
> -
> -
> - /**
> - * Get the subTrain attribute from the node and return it.
> - */
> - private boolean _isSubTrain(UIXProcess component)
> - {
> - Object focusRowKey = component.getFocusRowKey();
> - if (focusRowKey != null && (component.getDepth(focusRowKey) > 0))
> - return true;
> -
> - return false;
> +
> + private void _renderStationIconBlock(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Station station) throws IOException
> + {
> + process.setRowIndex(station.getRowIndex());
> +
> + String baseStyleClass = station.getBaseStyleClass();
> +
> + _renderIconBlock(context,
> + arc,
> + station.getIconNames(),
> + station.getLabel(),
> + baseStyleClass,
> + baseStyleClass + _SUFFIX_ICON_CELL,
> + station.getStates());
> }
> -
> -
> - private void _encodeChildren(
> - FacesContext context,
> - RenderingContext arc,
> - UIXProcess process,
> - UIComponent stamp,
> - TrainState train,
> - int length)
> - throws IOException
> +
> + private void _renderStationIconLtr(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Station station) throws IOException
> + {
> + _renderStationIcon(context,
> + arc,
> + process,
> + station,
> + station.getStartJoinState(),
> + station.getEndJoinState(),
> + station.hasPrevious() &&
> station.getPrevious().isOverflowStart(),
> + station.hasNext() &&
> station.getNext().isOverflowEnd());
> + }
> +
> + private void _renderStationIconRtl(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + Station station) throws IOException
> + {
> + _renderStationIcon(context,
> + arc,
> + process,
> + station,
> + station.getEndJoinState(),
> + station.getStartJoinState(),
> + station.hasNext() &&
> station.getNext().isOverflowEnd(),
> + station.hasPrevious() &&
> station.getPrevious().isOverflowStart());
> + }
> +
> + private void _renderTrain(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + FacesBean bean,
> + UIComponent stamp,
> + Train train) throws IOException
> {
> -
> ResponseWriter writer = context.getResponseWriter();
>
> - // start FOR SUBTRAIN
> - // If subTrain, add a row and on the first and last cells, render
> - // a border which looks like a sub-train
> - if (train.subTrain)
> - {
> - _renderSubTrainRow(context, arc, train, length, writer);
> -
> - writer.startElement("tr", null);
> - writer.startElement("td", null);
> - writer.endElement("td");
> + // Start of the icon row
> + writer.startElement(XhtmlConstants.TABLE_ROW_ELEMENT, null);
> +
> + if(arc.isRightToLeft())
> + {
> + _renderIconRowRtl(context, arc, process, stamp, train);
> }
> else
> {
> - writer.startElement("tr", null);
> + _renderIconRowLtr(context, arc, process, stamp, train);
> }
> +
> + writer.endElement(XhtmlConstants.TABLE_ROW_ELEMENT);
>
> - // loop through each rendered station.
> - int lastTrainIndex = train.startIndex +
> _getMaxLinks(arc, process);
> -
> - if (length <= lastTrainIndex)
> + // Start of the content row
> + writer.startElement(XhtmlConstants.TABLE_ROW_ELEMENT, null);
> +
> + if(arc.isRightToLeft())
> {
> - lastTrainIndex = length;
> + _renderContentRowRtl(context, arc, process, stamp, train);
> }
> else
> {
> - lastTrainIndex++; // length of train is larger than the visible
> - // number of train stations, so make room for the more
> - // by adding one to the lastTrainIndex.
> + _renderContentRowLtr(context, arc, process, stamp, train);
> }
> - int currVisChildIndex = Math.max(0, train.startIndex - 1);
> - boolean isPrevVisChildDisabled = false;
> - boolean isCurrVisChildDisabled = false;
> - boolean isNextVisChildDisabled = false;
> -
> - process.setRowIndex(currVisChildIndex);
> -
> - isCurrVisChildDisabled =
> - Boolean.TRUE.equals(stamp.getAttributes().get("disabled"));
> - // getBooleanAttributeValue(context, stamp,
> DISABLED_ATTR, false);
> -
> - for (; currVisChildIndex < lastTrainIndex; currVisChildIndex++)
> +
> + writer.endElement(XhtmlConstants.TABLE_ROW_ELEMENT);
> + }
> +
> + private static class Train
> + {
> + public Train(
> + FacesContext context,
> + RenderingContext arc,
> + UIXProcess process,
> + UIComponent stamp)
> + {
> + // Save the model state
> + int maxVisitedIndex = _getMaxVisitedIndex(arc, process);
> + int activeIndex = _loadStations(process, stamp,
> maxVisitedIndex);
> + int visibleStopCount = _getVisibleStopCount(arc);
> +
> + _formName = arc.getFormData().getName();
> + _isSubTrain = _loadIsSubTrain(process);
> +
> + if(!_stations.isEmpty())
> + {
> + // There's something visible in the train
> + if(_stations.size() > visibleStopCount)
> + {
> + // We have overflow, let resolve it
> + _resolveOverflow(visibleStopCount, activeIndex);
> + }
> + else
> + {
> + // No overflow, yay!
> + _resolveStandard();
> + }
> +
> + _initLabels(arc, process, stamp);
> + _initParentTrain(arc, process, stamp);
> + }
> + }
> +
> + public Object getFocusRowKey()
> {
> - //
> - // get index of the child and
> - // determine if it is within the range in which it
> will be rendered.
> - //
> - int prevVisChildIndex =
> - ((currVisChildIndex == 0)? NO_CHILD_INDEX:
> currVisChildIndex - 1);
> - int nextVisChildIndex =
> - ((currVisChildIndex == length - 1)? NO_CHILD_INDEX:
> - currVisChildIndex + 1);
> -
> - process.setRowIndex(nextVisChildIndex);
> -
> - isNextVisChildDisabled =
> - Boolean.TRUE.equals(stamp.getAttributes().get("disabled"));
> -
> - process.setRowIndex(currVisChildIndex);
> -
> - // initialized state of the station
> - TrainRenderer.StationState station = train.station;
> - _initializeStationState(context, arc, train, station,
> - currVisChildIndex, prevVisChildIndex,
> - nextVisChildIndex,
> isCurrVisChildDisabled,
> - isPrevVisChildDisabled,
> - isNextVisChildDisabled);
> -
> - // set up for next pass
> - isPrevVisChildDisabled = isCurrVisChildDisabled;
> - isCurrVisChildDisabled = isNextVisChildDisabled;
> -
> - Object label = stamp.getAttributes().get("text");
> -
> - String currVisChildText = null;
> -
> - // Get text from link, or Previous or More text if appropriate
> - currVisChildText = _getTextForStation(arc, station, label);
> -
> - String currVisChildID = null;
> -
> - process.setRowIndex(currVisChildIndex);
> - _renderLink(context, arc, stamp, writer, train,
> currVisChildText,
> - currVisChildID, station);
> -
> + return _focusRowKey;
> }
> -
> - if (train.subTrain)
> +
> + public String getFormName()
> {
> - writer.startElement("td", null);
> - writer.endElement("td");
> + return _formName;
> + }
> +
> + public Object getInitialRowKey()
> + {
> + return _initialRowKey;
> + }
> +
> + public ParentTrain getParentTrain()
> + {
> + return _parent;
> + }
> +
> + public List<Station> getStations()
> + {
> + return _stations;
> + }
> +
> + public boolean isSubTrain()
> + {
> + return _isSubTrain;
> + }
> +
> + private void _createStation(
> + UIXProcess process,
> + UIComponent stamp,
> + int index,
> + boolean active,
> + boolean visited)
> + {
> + process.setRowIndex(index);
> + if(stamp.isRendered())
> + {
> + // The station will be visible.
> + _stations.add(new Station(this,
> + stamp,
> + index,
> + process.getRowKey(),
> + active,
> + visited));
> + }
> }
>
> - writer.endElement("tr");
> - }
> -
> - /**
> - * Renders the link under the train node
> - *
> - */
> - private void _renderLink(
> - FacesContext context,
> - RenderingContext arc,
> - UIComponent stamp,
> - ResponseWriter writer,
> - TrainRenderer.TrainState train,
> - String currVisChildText,
> - String currVisChildID,
> - TrainRenderer.StationState station)
> - throws IOException
> - {
> - //
> - // Write the link under the train node.
> - //
> - writer.startElement("td", null);
> - writer.writeAttribute("colspan", "2", null);
> -
> - String styleClass =
> - (station.isSelected)?
> SkinSelectors.AF_PROCESS_TRAIN_ACTIVE_STYLE_CLASS:
> - (station.isDisabled && !station.isMoreLink)?
> - SkinSelectors.AF_PROCESS_TRAIN_DISABLED_STYLE_CLASS:
> - (station.isVisited)?
> - SkinSelectors.AF_PROCESS_TRAIN_VISITED_STYLE_CLASS:
> - SkinSelectors.AF_PROCESS_TRAIN_UNVISITED_STYLE_CLASS;
> -
> - renderStyleClass(context, arc, styleClass);
> + /**
> + * Get the maxVisited attribute from the node and return it.
> + */
> + private int _getMaxVisitedIndex(
> + RenderingContext arc,
> + UIComponent component)
> + {
> + int maxVisitedIndex = NO_CHILD_INDEX;
> + Integer maxVisited = (Integer) _getMaxVisited(arc, component);
> + if (maxVisited != null)
> + {
> + maxVisitedIndex = maxVisited.intValue();
> + }
> + return maxVisitedIndex;
> + }
>
> - Map<String, String> originalResourceKeyMap =
> arc.getSkinResourceKeyMap();
> - try
> + /**
> + * Returns the MAX_VISITED_ATTR
> + * @todo =-=jmw Hopefully the controller will tell us
> this someday.
> + */
> + private static Object _getMaxVisited(
> + RenderingContext arc,
> + UIComponent component)
> + {
> + // return component.getAttributes().get("maxVisited");
> + return null;
> + }
> +
> + private int _getVisibleStopCount(RenderingContext arc)
> + {
> + Object propValue =
> +
> arc.getSkin().getProperty(SkinProperties.AF_TRAIN_VISIBLE_STOP_COUNT);
> +
> + if(propValue == null)
> + {
> + return DEFAULT_MAX_VISIBLE_STOP_COUNT;
> + }
> +
> + try
> + {
> + int count = Integer.parseInt(propValue.toString());
> + if(count <= 0)
> + {
> + _LOG.warning("Visible stop count must be > 0,
> found " + count);
> + return DEFAULT_MAX_VISIBLE_STOP_COUNT;
> + }
> +
> + return count;
> + }
> + catch(NumberFormatException e)
> + {
> + _LOG.warning("Visible stop count must be an integer,
> found " + propValue);
> + return DEFAULT_MAX_VISIBLE_STOP_COUNT;
> + }
> + }
> +
> + private void _initLabels(
> + RenderingContext arc,
> + UIXProcess process,
> + UIComponent stamp)
> {
> - arc.setSkinResourceKeyMap(_RESOURCE_KEY_MAP);
> - _renderStamp(context, stamp);
> + for(Station s : _stations)
> + {
> + process.setRowIndex(s.getRowIndex());
> + s.initLabel(arc, stamp);
> + }
> }
> - finally
> +
> + private void _initParentTrain(
> + RenderingContext arc,
> + UIXProcess process,
> + UIComponent stamp)
> {
> - arc.setSkinResourceKeyMap(originalResourceKeyMap);
> + if(_isSubTrain)
> + {
> + if(_shouldRenderParentTrain(arc))
> + {
> + _parent = new ParentTrain(arc, process, stamp, this);
> + if(!_parent.hasParentStart() && !_parent.hasParentEnd())
> + {
> + _isSubTrain = false;
> + }
> + }
> + else
> + {
> + _isSubTrain = false;
> + }
> + }
> }
> - writer.endElement("td");
> - }
> -
> - /**
> - * Called to render a child. This method does not update the
> - * rendering context (by calling pushChild() and popChild()
> - * as needed); subclasses need to use renderIndexedChild() or
> - * renderNamedChild() for that purpose.
> - * <p>
> - * @param context the faces context
> - * @param child the child under consideration
> - */
> - private void _renderStamp(FacesContext context, UIComponent child)
> - throws IOException
> - {
> - if (child != null)
> +
> + /**
> + * Determine if this train is a sub-train.
> + */
> + private boolean _loadIsSubTrain(UIXProcess process)
> {
> - encodeChild(context, child);
> - // child.render(context);
> + Object focusRowKey = process.getFocusRowKey();
> + if (focusRowKey != null && (process.getDepth(focusRowKey) > 0))
> + {
> + return true;
> + }
> +
> + return false;
> }
> - }
> -
> - /**
> - * return the string to use for the text of the station
> - * it is the text of the link or "Previous" or "More"
> - */
> - private String _getTextForStation(
> - RenderingContext arc,
> - TrainRenderer.StationState station,
> - Object textObj)
> - {
> - String textValue = (textObj == null)? null: textObj.toString();
> - final String currText;
> +
> + private int _loadStations(
> + UIXProcess process,
> + UIComponent stamp,
> + int maxVisitedIndex)
> + {
> + _initialRowKey = process.getRowKey();
> + try
> + {
> + // Set the model on the focus item
> + _focusRowKey = process.getFocusRowKey();
> + process.setRowKey(_focusRowKey);
> +
> + int count = process.getRowCount();
> + int activeIndex = process.getRowIndex();
> + int index = 0;
> +
> + assert activeIndex < count;
> +
> + _stations = new ArrayList<Station>(count);
> +
> + // Process visited stations
> + for(; index < activeIndex; index++)
> + {
> + _createStation(process, stamp, index, false, true);
> + }
> +
> + assert index == activeIndex;
> +
> + _createStation(process, stamp, index, true, true);
> + index++;
> + // Might have an invisible active station. Thsi is
> weird, but still.
> + // You never know what users want to do, but let support
> + // it nevertheless for now.
> + // selectedIndex is either the active station index
> or the index
> + // of the station just before the selected one if
> active is not visible.
> + activeIndex = _stations.size() - 1;
> +
> + if(maxVisitedIndex != NO_CHILD_INDEX)
> + {
> + for(; index < maxVisitedIndex; index++)
> + {
> + _createStation(process, stamp, index, false, true);
> + }
> + }
> +
> + for(; index < count; index++)
> + {
> + _createStation(process, stamp, index, false, false);
> + }
> +
> + return activeIndex;
> + }
> + finally
> + {
> + // Restore the model's state
> + process.setRowKey(_initialRowKey);
> + }
> + }
> +
> + private void _resolveOverflow(
> + int visibleStopCount,
> + int activeIndex)
> + {
> + assert _stations != null;
> + assert activeIndex >= -1;
> + assert activeIndex < _stations.size();
> +
> + // First, resolve chaining
> + _resolveStandard();
> +
> + // We have more stations than the max available, so we
> have an overflow
> + // for sure.
> + if(activeIndex <= 0)
> + {
> + // Overflow to the following group only
> + _resolveOverflowEnd(visibleStopCount);
> + _stations = _stations.subList(0, visibleStopCount + 1);
> + }
> + else
> + {
> + // Get the visible group index
> + int groupIndex = activeIndex / visibleStopCount;
> + int startIndex = 0;
> + int endIndex = _stations.size();
> + if(groupIndex > 0)
> + {
> + // We have a previous overflow
> + startIndex = groupIndex * visibleStopCount - 1;
> + _resolveOverflowStart(startIndex);
> + }
> +
> + int maxGroupIndex = (_stations.size() - 1) /
> visibleStopCount;
> +
> + if(groupIndex < maxGroupIndex)
> + {
> + // We have a next overflow
> + int overflowIndex = (groupIndex + 1) * visibleStopCount;
> +
> + // endIndex is exclusive
> + endIndex = overflowIndex + 1;
> +
> + _resolveOverflowEnd(overflowIndex);
> + }
>
> - if (textValue != null && !station.isPreviousLink &&
> - !station.isMoreLink)
> + _stations = _stations.subList(startIndex, endIndex);
> + }
> + }
> +
> + private void _resolveOverflowEnd(int index)
> + {
> + assert _stations != null;
> + assert index >= 0;
> + assert index < _stations.size();
> +
> + Station station = _stations.get(index);
> + station.setOverflowEnd(true);
> + if(station.hasPrevious() && station.getPrevious().isDisabled())
> + {
> + // If previous stop is disabled, so is the overflow
> + station.setDisabled(true);
> + }
> +
> + station.setNext(null);
> + }
> +
> + private void _resolveOverflowStart(int index)
> + {
> + assert _stations != null;
> + assert index >= 0;
> + assert index < _stations.size();
> +
> + Station station = _stations.get(index);
> + station.setOverflowStart(true);
> + if(station.hasNext() && station.getNext().isDisabled())
> + {
> + // If next stop is disabled, so is the overflow
> + station.setDisabled(true);
> + }
> +
> + station.setPrevious(null);
> + }
> +
> + private void _resolveStandard()
> + {
> + if(_stations.size() > 1)
> + {
> + Iterator<Station> iterator = _stations.iterator();
> +
> + Station previous = null;
> + Station current = iterator.next();
> + Station next = iterator.next();
> +
> + _updateStation(current, previous, next);
> +
> + while(iterator.hasNext())
> + {
> + previous = current;
> + current = next;
> + next = iterator.next();
> + _updateStation(current, previous, next);
> + }
> +
> + next.setPrevious(current);
> + }
> + }
> +
> + private boolean _shouldRenderParentTrain(RenderingContext arc)
> + {
> + Object propValue =
> +
> arc.getSkin().getProperty(SkinProperties.AF_TRAIN_RENDER_PAREN
> T_TRAIN);
> +
> + if(propValue == null)
> + {
> + return DEFAULT_RENDER_PARENT_TRAIN;
> + }
> +
> + return Boolean.TRUE.equals(propValue);
> + }
> +
> + private void _updateStation(
> + Station current,
> + Station previous,
> + Station next)
> + {
> + current.setPrevious(previous);
> + current.setNext(next);
> + }
> +
> + private Object _focusRowKey;
> + private String _formName;
> + private Object _initialRowKey;
> + private boolean _isSubTrain;
> + private ParentTrain _parent;
> + private List<Station> _stations;
> + }
> +
> + private static class Station
> + {
> + public Station(
> + Train train,
> + int index,
> + Object rowKey)
> + {
> + _rowIndex = index;
> + _rowKey = rowKey;
> + _active = false;
> + _visited = false;
> + _disabled = false;
> + _readOnly = false;
> + _parentEnd = false;
> + _parentStart = false;
> + _train = train;
> + }
> +
> + @SuppressWarnings("unchecked")
> + public Station(
> + Train train,
> + UIComponent stamp,
> + int index,
> + Object rowKey,
> + boolean active,
> + boolean visited)
> + {
> + Map<String, Object> attributes = stamp.getAttributes();
> +
> + _rowIndex = index;
> + _rowKey = rowKey;
> + _active = active;
> + _visited = visited;
> + _disabled = _getBooleanAttribute(attributes,
> "disabled", false);
> + _readOnly = _getBooleanAttribute(attributes,
> "readOnly", false);
> + _parentEnd = false;
> + _parentStart = false;
> + _train = train;
> + }
> +
> + public String getBaseStyleClass()
> {
> - // if we are in screen reader mode, then we must
> render more descriptive
> - // text.
> - // see bug 1801348 REMOVE ONE SET OF TRAIN TEXT IN
> ACCESSIBLE MODE
> - if (isScreenReaderMode(arc))
> + if(isOverflowEnd())
> + {
> + return SkinSelectors.AF_TRAIN_OVERFLOW_END_STYLE_CLASS;
> + }
> + else if(isOverflowStart())
> + {
> + return SkinSelectors.AF_TRAIN_OVERFLOW_START_STYLE_CLASS;
> + }
> + else if(isParentStart())
> + {
> + return SkinSelectors.AF_TRAIN_PARENT_START_STYLE_CLASS;
> + }
> + else if(isParentEnd())
> {
> - currText = _getDisabledUserText(arc, station, textValue);
> + return SkinSelectors.AF_TRAIN_PARENT_END_STYLE_CLASS;
> }
> else
> {
> - currText = textValue;
> + return SkinSelectors.AF_TRAIN_STOP_STYLE_CLASS;
> }
> }
> - else if (station.isPreviousLink)
> +
> + public String getEndJoinState()
> {
> - currText = arc.getTranslatedString(_PREVIOUS_KEY);
> + if(isOverflowEnd())
> + {
> + return null;
> + }
> + else if(!hasNext())
> + {
> + ParentTrain parent = _train.getParentTrain();
> + if(parent != null && parent.hasParentEnd())
> + {
> + return _STATE_PARENT;
> + }
> + else
> + {
> + return null;
> + }
> + }
> + else if(isDisabled() || getNext().isDisabled())
> + {
> + return _STATE_DISABLED;
> + }
> + else if(getNext().isVisited())
> + {
> + return _STATE_VISITED;
> + }
> + else
> + {
> + return _STATE_UNVISITED;
> + }
> }
> - else if (station.isMoreLink)
> +
> + public List<String> getIconNames()
> {
> - currText = arc.getTranslatedString(_MORE_KEY);
> + if(isOverflowEnd())
> + {
> + return _getOverflowEndIconNames();
> + }
> + else if(isOverflowStart())
> + {
> + return _getOverflowStartIconNames();
> + }
> + else if(isParentStart())
> + {
> + return
> Collections.singletonList(SkinSelectors.AF_TRAIN_PARENT_START_
> ICON_NAME);
> + }
> + else if(isParentEnd())
> + {
> + return
> Collections.singletonList(SkinSelectors.AF_TRAIN_PARENT_END_IC
> ON_NAME);
> + }
> + else
> + {
> + return _getStopIconNames();
> + }
> }
> - else
> - currText = null;
> -
> - return currText;
> - }
> -
> - private String _getDisabledUserText(
> - RenderingContext arc,
> - TrainRenderer.StationState station,
> - String textString)
> - {
> - String altTextKey =
> - station.isSelected? _ACTIVE_KEY: station.isVisited?
> _VISITED_KEY:
> - _NEXT_KEY;
> -
> - String[] parameters = new String[]
> - { textString };
> -
> - String altText =
> -
> XhtmlUtils.getFormattedString(arc.getTranslatedString(altTextKey),
> - parameters);
> - return altText;
> - }
> -
> - /**
> - * Returns the max number of links to show
> - */
> - private int _getMaxLinks(
> - RenderingContext arc,
> - UIComponent component)
> - {
> - return _MAX_NUM_LINK_INDEX;
> - }
> -
> - private void _renderSubTrainRow(
> - FacesContext context,
> - RenderingContext arc,
> - TrainRenderer.TrainState train,
> - int length,
> - ResponseWriter writer)
> - throws IOException
> - {
> - boolean isRTL = arc.getLocaleContext().isRightToLeft();
> -
> - writer.startElement("tr", null);
> -
> - if (isRTL)
> - _renderSubTrainCell(context, arc,
> - SkinSelectors.TRAIN_SUB_RIGHT_STYLE_CLASS,
> - writer);
> - else
> - _renderSubTrainCell(context, arc,
> -
> SkinSelectors.AF_PROCESS_TRAIN_SUB_START_STYLE_CLASS,
> - writer);
> -
> - _renderSubTrainBlankCells(train, length, writer);
> -
> - if (isRTL)
> - _renderSubTrainCell(context, arc,
> -
> SkinSelectors.AF_PROCESS_TRAIN_SUB_START_STYLE_CLASS,
> - writer);
> - else
> - _renderSubTrainCell(context, arc,
> - SkinSelectors.TRAIN_SUB_RIGHT_STYLE_CLASS,
> - writer);
> -
> - writer.endElement("tr");
> - }
> -
> - private void _renderSubTrainCell(
> - FacesContext context,
> - RenderingContext arc,
> - String style,
> - ResponseWriter writer)
> - throws IOException
> - {
> - writer.startElement("td", null);
> - renderStyleClass(context, arc, style);
> - renderSpacer(context, arc, "14", "2");
> - writer.endElement("td");
> - }
> -
> - /**
> - * renders a td with colSpan equal to the number of
> visible stations
> - * including the Previous and More if they are there.
> - * @param train
> - * @param length
> - * @param writer
> - * @throws IOException
> - */
> - private void
> _renderSubTrainBlankCells(TrainRenderer.TrainState train,
> - int length,
> ResponseWriter writer)
> - throws IOException
> - {
> - writer.startElement("td", null);
> -
> - // figure out the number of stations
> - int startIndex = Math.max(0, train.startIndex - 1);
> - int lastTrainIndex = train.startIndex + _MAX_NUM_LINK_INDEX;
> - if (length <= lastTrainIndex)
> - lastTrainIndex = length;
> - else
> +
> + public String getLabel()
> {
> - // when the length of train is larger than the visible
> - // number of train stations, we render a More link.
> - // so make room for the more
> - // by adding one to the lastTrainIndex.
> - lastTrainIndex++;
> - }
> - String numberOfStations =
> - Integer.toString((lastTrainIndex - startIndex) * 2);
> - writer.writeAttribute("colspan", numberOfStations, null);
> - writer.endElement("td");
> - }
> + return _label;
> + }
> +
> + public Station getNext()
> + {
> + return _next;
> + }
> +
> + public Station getPrevious()
> + {
> + return _previous;
> + }
> +
> + public int getRowIndex()
> + {
> + return _rowIndex;
> + }
> +
> + public Object getRowKey()
> + {
> + return _rowKey;
> + }
> +
> + public String getStartJoinState()
> + {
> + if(isOverflowStart())
> + {
> + return null;
> + }
> + else if(!hasPrevious())
> + {
> + ParentTrain parent = _train.getParentTrain();
> + if(parent != null && parent.hasParentStart())
> + {
> + return _STATE_PARENT;
> + }
> + else
> + {
> + return null;
> + }
> + }
> + else if(isDisabled() || getPrevious().isDisabled())
> + {
> + return _STATE_DISABLED;
> + }
> + else if(isVisited())
> + {
> + return _STATE_VISITED;
> + }
> + else
> + {
> + return _STATE_UNVISITED;
> + }
> + }
> +
> + public List<String> getStates()
> + {
> + List<String> states = new ArrayList<String>(5);
> + if(isParentStart() || isParentEnd())
> + {
> + return states;
> + }
> +
> + if(isDisabled())
> + {
> + states.add(_STATE_DISABLED);
> + return states;
> + }
> +
> + if(isActive())
> + {
> + states.add(_STATE_ACTIVE);
> + }
> + else if(isVisited())
> + {
> + states.add(_STATE_VISITED);
> + }
> + else
> + {
> + states.add(_STATE_UNVISITED);
> + }
> +
> + if(isReadOnly())
> + {
> + states.add(_STATE_READ_ONLY);
> + }
> +
> + return states;
> + }
> +
> + public boolean hasNext()
> + {
> + return _next != null;
> + }
> +
> + public boolean hasPrevious()
> + {
> + return _previous != null;
> + }
>
>
> - private void _renderHiddenFields(
> - FacesContext context,
> - RenderingContext arc,
> - TrainState train)
> - throws IOException
> - {
> - if ((train.formName != null) && supportsScripting(arc))
> + /**
> + * return the string to use for the text of the station
> + * it is the text of the link or "Previous" or "More"
> + */
> + public void initLabel(
> + RenderingContext arc,
> + UIComponent stamp)
> {
> - // render hidden fields to hold the form data
> - FormData fData = arc.getFormData();
> - if (fData != null)
> + if(isOverflowStart())
> {
> - fData.addNeededValue(XhtmlConstants.EVENT_PARAM);
> - fData.addNeededValue(XhtmlConstants.SOURCE_PARAM);
> - fData.addNeededValue(XhtmlConstants.VALUE_PARAM);
> - fData.addNeededValue(XhtmlConstants.SIZE_PARAM);
> + _label = arc.getTranslatedString(_PREVIOUS_KEY);
> + }
> + else if(isOverflowEnd())
> + {
> + _label = arc.getTranslatedString(_MORE_KEY);
> + }
> + else
> + {
> + Object text = stamp.getAttributes().get("text");
> + if(text != null)
> + {
> + _label = text.toString();
> + if (isScreenReaderMode(arc))
> + {
> + _label = _getDisabledUserText(arc, _label);
> + }
> + }
> + else
> + {
> + _label = null;
> + }
> }
> -
> - // Render script submission code.
> - ProcessUtils.renderNavSubmitScript(context, arc);
> }
> - }
> +
> + public boolean isActive()
> + {
> + return _active;
> + }
> +
> + public boolean isDisabled()
> + {
> + return _disabled;
> + }
> +
> + public boolean isNextDisabled()
> + {
> + return hasNext() && _next.isDisabled();
> + }
> +
> + public boolean isOverflowEnd()
> + {
> + return _overflowEnd;
> + }
> +
> + public boolean isOverflowStart()
> + {
> + return _overflowStart;
> + }
> +
> + public boolean isParentEnd()
> + {
> + return _parentEnd;
> + }
> +
> + public boolean isParentStart()
> + {
> + return _parentStart;
> + }
> +
> + public boolean isPreviousDisabled()
> + {
> + return hasPrevious() && _previous.isDisabled();
> + }
> +
> + public boolean isReadOnly()
> + {
> + return _readOnly;
> + }
> +
> + public boolean isVisited()
> + {
> + return _visited;
> + }
> +
> + public void setDisabled(boolean disabled)
> + {
> + _disabled = disabled;
> + }
> +
> + public void setNext(Station next)
> + {
> + _next = next;
> + }
> +
> + public void setOverflowEnd(boolean overflowEnd)
> + {
> + _overflowEnd = overflowEnd;
> + }
> +
> + public void setOverflowStart(boolean overflowStart)
> + {
> + _overflowStart = overflowStart;
> + _visited = true;
> + }
> +
> + public void setParentEnd(boolean parentEnd)
> + {
> + _parentEnd = parentEnd;
> + }
> +
> + public void setParentStart(boolean parentStart)
> + {
> + _parentStart = parentStart;
> + }
> +
> + public void setPrevious(Station previous)
> + {
> + _previous = previous;
> + }
> +
> + public void setReadOnly(boolean readOnly)
> + {
> + _readOnly = readOnly;
> + }
> +
> + private boolean _getBooleanAttribute(
> + Map<String, Object> attributes,
> + String attributeName,
> + boolean defaultValue)
> + {
> + Object value = attributes.get(attributeName);
> + if(value == null)
> + {
> + return defaultValue;
> + }
> +
> + return Boolean.TRUE.equals(value);
> + }
>
> + private String _getDisabledUserText(
> + RenderingContext arc,
> + String text)
> + {
> + String altTextKey;
> + if(isActive())
> + {
> + altTextKey = _ACTIVE_KEY;
> + }
> + else if(isVisited())
> + {
> + altTextKey = _VISITED_KEY;
> + }
> + else
> + {
> + altTextKey = _NEXT_KEY;
> + }
>
> - private boolean _setNewPath(UIXProcess component)
> - {
> - Object focusPath = component.getFocusRowKey();
> - component.setRowKey(focusPath);
> - return true;
> + String altText =
> +
> XhtmlUtils.getFormattedString(arc.getTranslatedString(altTextKey),
> + new String[]{text});
> +
> + return altText;
> + }
> +
> + private List<String> _getIconNames(String baseSelector)
> + {
> + LinkedList<String> names = new LinkedList<String>();
> +
> + StringBuilder builder = new StringBuilder(64);
> + builder.append(baseSelector);
> +
> + int suffixLength = SkinSelectors.ICON_SUFFIX.length();
> + int baseIndex = builder.length();
> +
> + builder.append(SkinSelectors.ICON_SUFFIX);
> + names.addFirst(builder.toString());
> + builder.delete(baseIndex, baseIndex + suffixLength);
> +
> + if(isDisabled())
> + {
> + builder.append(_SUFFIX_DISABLED);
> + builder.append(SkinSelectors.ICON_SUFFIX);
> + names.addFirst(builder.toString());
> + }
> + else
> + {
> + if(isActive())
> + {
> + builder.append(_SUFFIX_ACTIVE);
> + }
> + else if(isVisited())
> + {
> + builder.append(_SUFFIX_VISITED);
> + }
> + else
> + {
> + builder.append(_SUFFIX_UNVISITED);
> + }
> +
> + baseIndex = builder.length();
> +
> + builder.append(SkinSelectors.ICON_SUFFIX);
> + names.addFirst(builder.toString());
> + builder.delete(baseIndex, baseIndex + suffixLength);
> +
> + if(isReadOnly())
> + {
> + builder.append(_SUFFIX_READ_ONLY);
> + builder.append(SkinSelectors.ICON_SUFFIX);
> + names.addFirst(builder.toString());
> + }
> + }
> +
> + return names;
> + }
> +
> + private List<String> _getOverflowEndIconNames()
> + {
> + return
> _getIconNames(SkinSelectors.AF_TRAIN_OVERFLOW_END_STYLE_CLASS);
> + }
> +
> + private List<String> _getOverflowStartIconNames()
> + {
> + return
> _getIconNames(SkinSelectors.AF_TRAIN_OVERFLOW_START_STYLE_CLASS);
> + }
> +
> + private List<String> _getStopIconNames()
> + {
> + return _getIconNames(SkinSelectors.AF_TRAIN_STOP_STYLE_CLASS);
> + }
> +
> + private boolean _active; // Is this station the active one?
> + private boolean _disabled; // Disabled attribute
> + private boolean _overflowEnd; // Is this station the
> next step set link?
> + private boolean _overflowStart; // Is this station the
> prev step set link?
> + private boolean _parentEnd; // Is this station a parent end?
> + private boolean _parentStart; // Is this station a parent start?
> + private boolean _readOnly; // Read only attribute
> + private boolean _visited; // Is this station visited?
> +
> + private int _rowIndex; // Row index
> +
> + private Object _rowKey; // Row key
> +
> + private String _label; // This station's label
> +
> + private Station _next;
> + private Station _previous;
> +
> + private Train _train;
> }
> -
> - protected static class TrainState
> +
> + private static class ParentTrain
> {
> - public TrainState()
> + public ParentTrain(
> + RenderingContext arc,
> + UIXProcess process,
> + UIComponent stamp,
> + Train train)
> + {
> + List<Station> stations = train.getStations();
> + int stationCount = stations.size();
> +
> + boolean hasParentStart = !stations.get(0).isOverflowStart();
> + boolean hasParentEnd = !stations.get(stationCount -
> 1).isOverflowEnd();
> +
> + if(hasParentStart || hasParentEnd)
> + {
> + Object parentStartRowKey = process.getContainerRowKey();
> + process.setRowKey(parentStartRowKey);
> + int rowIndex = process.getRowIndex();
> + if(hasParentStart)
> + {
> + _parentStart = new Station(train, rowIndex,
> parentStartRowKey);
> + _parentStart.setParentStart(true);
> + _parentStart.initLabel(arc, stamp);
> + }
> +
> + rowIndex = rowIndex + 1;
> +
> + // Check if the parent has more steps, render it
> only if it does
> + hasParentEnd = rowIndex < process.getRowCount();
> + if(hasParentEnd)
> + {
> + process.setRowIndex(rowIndex);
> + _parentEnd = new Station(train, rowIndex,
> process.getRowKey());
> + _parentEnd.setParentEnd(true);
> + _parentEnd.initLabel(arc, stamp);
> + }
> +
> + // Restore the model
> + process.setRowKey(train.getInitialRowKey());
> + }
> + }
> +
> + public Station getParentEnd()
> {
> - station = new TrainRenderer.StationState();
> + return _parentEnd;
> }
> - public int startIndex;
> - public int maxVisitedIndex;
> - public int selectedIndex;
> - public boolean subTrain;
> - public String formName;
> - public String id;
> - public TrainRenderer.StationState station;
> - }
> -
> - protected static class StationState
> - {
> -
> - public boolean isSelected;
> - // is this the station that is right AFTER the selected station.
> - public boolean isNext;
> - public boolean isVisited; // has this station been
> visited already?
> - public boolean isPreviousLink; // is this the Previous link?
> - public boolean isMoreLink; // is this the More link?
> - public boolean isDisabled; // is this station disabled?
> - public boolean isNextDisabled; // is the next station disabled?
> - public boolean isPrevDisabled; // is the previous
> station disabled?
> - public boolean isNextVisited; // is the next station visited?
> - public int index; // the index of this node
> - } //end StationState
> +
> + public Station getParentStart()
> + {
> + return _parentStart;
> + }
> +
> + public boolean hasParentEnd()
> + {
> + return _parentEnd != null;
> + }
> +
> + public boolean hasParentStart()
> + {
> + return _parentStart != null;
> + }
> +
> + private Station _parentEnd;
> + private Station _parentStart;
> + }
>
> - private static final int _MAX_NUM_LINK_INDEX =
> - 6; //number of visible links
> + /**
> + * Gives the amount of visible stops that get rendered by
> default if no
> + * amount is specified by the -ora-visible-stop-count skin
> property.
> + */
> + public static final int DEFAULT_MAX_VISIBLE_STOP_COUNT = 6;
> +
> + /**
> + * Determines if the parent train of sub-trains should be
> rendered by
> + * default if not specified by the
> -ora-render-parent-train skin property.
> + */
> + public static final boolean DEFAULT_RENDER_PARENT_TRAIN = false;
> +
> + private static final String _STATE_ACTIVE =
> SkinSelectors.STATE_PREFIX + "Selected";
> + private static final String _STATE_DISABLED =
> SkinSelectors.STATE_PREFIX + "Disabled";
> + private static final String _STATE_PARENT =
> SkinSelectors.STATE_PREFIX + "Parent";
> + private static final String _STATE_READ_ONLY =
> SkinSelectors.STATE_PREFIX + "ReadOnly";
> + private static final String _STATE_UNVISITED =
> SkinSelectors.STATE_PREFIX + "Unvisited";
> + private static final String _STATE_VISITED =
> SkinSelectors.STATE_PREFIX + "Visited";
> +
> + private static final String _SUFFIX_CONTENT = "-content";
> + private static final String _SUFFIX_ICON_CELL = "-icon-cell";
> +
> + private static final String _SUFFIX_ACTIVE = ":selected";
> + private static final String _SUFFIX_DISABLED = ":disabled";
> + private static final String _SUFFIX_READ_ONLY = ":read-only";
> + private static final String _SUFFIX_UNVISITED = ":unvisited";
> + private static final String _SUFFIX_VISITED = ":visited";
>
> /**
> - * The following keys are used to get at the corresponding translated
> - * strings.
> - */
> + * The following keys are used to get at the corresponding
> translated
> + * strings.
> + */
> private static final String _VISITED_KEY = "af_train.VISITED_TIP";
> private static final String _ACTIVE_KEY = "af_train.ACTIVE_TIP";
> private static final String _NEXT_KEY = "af_train.NEXT_TIP";
> @@ -800,23 +1866,22 @@
>
> private static final TrinidadLogger _LOG =
> TrinidadLogger.createTrinidadLogger(TrainRenderer.class);
> -
> - // for now keep the OraLink/OraDisabledLink styles on the 'a', and
> - // append train link style class.
> - private static final Map<String, String> _RESOURCE_KEY_MAP =
> - new HashMap<String, String>();
> - private static final String _TRAIN_DISABLED_LINK =
> - SkinSelectors.LINK_DISABLED_STYLE_CLASS + " " +
> - SkinSelectors.AF_PROCESS_TRAIN_LINK_STYLE_CLASS;
> - private static final String _TRAIN_ENABLED_LINK =
> - SkinSelectors.LINK_STYLE_CLASS + " " +
> - SkinSelectors.AF_PROCESS_TRAIN_LINK_STYLE_CLASS;
> -
> - static {
> - _RESOURCE_KEY_MAP.put(SkinSelectors.LINK_DISABLED_STYLE_CLASS,
> - _TRAIN_DISABLED_LINK);
> - _RESOURCE_KEY_MAP.put(SkinSelectors.LINK_STYLE_CLASS,
> - _TRAIN_ENABLED_LINK);
> +
> + private static final String[] _EMPTY_STRING_ARRAY;
> +
> + private static final Map<String, String> _RESOURCE_KEY_MAP;
> +
> + static
> + {
> + _EMPTY_STRING_ARRAY = new String[0];
> +
> + // Not adding the base link classes as before, those are
> a nuisance
> + // while defining the skin since oyu cannot inhibit them
> as they're
> + // on the same level as the train selectors.
> + _RESOURCE_KEY_MAP = new TreeMap<String, String>();
> + _RESOURCE_KEY_MAP.put(SkinSelectors.LINK_STYLE_CLASS,
> + SkinSelectors.AF_TRAIN_LINK_STYLE_CLASS);
> + _RESOURCE_KEY_MAP.put(SkinSelectors.LINK_DISABLED_STYLE_CLASS,
> + SkinSelectors.AF_TRAIN_LINK_STYLE_CLASS);
> }
> -
> }
>
> Modified:
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/
org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinProperties.j> ava
> URL:
> http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad
> /trinidad-impl/src/main/java/org/apache/myfaces/trinidadintern
al/renderkit/core/xhtml/SkinProperties.java?view=diff&rev=451772&r1=> 451771&r2=451772
> ==============================================================
> ================
> ---
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/
org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinProperties.j> ava (original)
> +++
> incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/
org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SkinProperties.j> ava Sun Oct 1 10:26:55 2006
> @@ -39,14 +39,18 @@
> // FIXME: Name inconsistency, should be AF_PANEL_HEADER
> public static final String AF_PANELHEADER_INDENT_CONTENT =
> "af|panelHeader-ora-indent-content";
> + public static final String AF_PANEL_BORDER_LAYOUT_SPACER_WIDTH =
> + "af|panelBorderLayout-ora-spacer-width";
> public static final String AF_PANEL_LIST_DEFAULT_COLUMNS =
> "af|panelList-ora-default-columns";
> public static final String AF_TABLE_REPEAT_CONTROL_BAR =
> "af|table-ora-repeat-control-bar";
> public static final String AF_TABLE_SELECTION_BAR_IN_TABLE =
> "af|table-ora-selection-bar-in-table";
> + public static final String AF_TRAIN_RENDER_PARENT_TRAIN =
> + "af|train-ora-render-parent-train";
> + public static final String AF_TRAIN_VISIBLE_STOP_COUNT =
> + "af|train-ora-visible-stop-count";
> public static final String AF_TREE_TABLE_SPACER_WIDTH =
> "af|treeTable-ora-spacer-width";
> - public static final String AF_PANEL_BORDER_LAYOUT_SPACER_WIDTH =
> - "af|panelBorderLayout-ora-spacer-width";
> }
>
>
>
>