Guest User

Untitled

a guest
Apr 3rd, 2015
511
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 29.64 KB | None | 0 0
  1. package pl.horus.wf.web.commons.component;
  2. /*
  3.  * This is a copy of com.sun.faces.facelets.component.UIRepeat from JSF 2.0.4
  4.  * adapted to support multiple nesting and DynamicInclude component.
  5.  * Changes include additional children state management for nested UIRepeat,
  6.  * DynamicInclude, UIForm and performance optimizations limiting state
  7.  * management to rendered DynamicInclude subtrees only. Also resetClientId was
  8.  * combined with restoreChildrenState in one tree traversal.
  9.  *
  10.  * Also contains static nested class to swap component implementation.
  11.  * Replace with more reasonable mechanism.
  12.  *
  13.  */
  14.  
  15.  
  16. /*
  17.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  18.  *
  19.  * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
  20.  *
  21.  * The contents of this file are subject to the terms of either the GNU
  22.  * General Public License Version 2 only ("GPL") or the Common Development
  23.  * and Distribution License("CDDL") (collectively, the "License").  You
  24.  * may not use this file except in compliance with the License.  You can
  25.  * obtain a copy of the License at
  26.  * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
  27.  * or packager/legal/LICENSE.txt.  See the License for the specific
  28.  * language governing permissions and limitations under the License.
  29.  *
  30.  * When distributing the software, include this License Header Notice in each
  31.  * file and include the License file at packager/legal/LICENSE.txt.
  32.  *
  33.  * GPL Classpath Exception:
  34.  * Oracle designates this particular file as subject to the "Classpath"
  35.  * exception as provided by Oracle in the GPL Version 2 section of the License
  36.  * file that accompanied this code.
  37.  *
  38.  * Modifications:
  39.  * If applicable, add the following below the License Header, with the fields
  40.  * enclosed by brackets [] replaced by your own identifying information:
  41.  * "Portions Copyright [year] [name of copyright owner]"
  42.  *
  43.  * Contributor(s):
  44.  * If you wish your version of this file to be governed by only the CDDL or
  45.  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  46.  * elects to include this software in this distribution under the [CDDL or GPL
  47.  * Version 2] license."  If you don't indicate a single choice of license, a
  48.  * recipient has the option to distribute your version of this file under
  49.  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  50.  * its licensees as provided above.  However, if you add GPL Version 2 code
  51.  * and therefore, elected the GPL Version 2 license, then the option applies
  52.  * only if the new code is made subject to such option by the copyright
  53.  * holder.
  54.  *
  55.  *
  56.  * This file incorporates work covered by the following copyright and
  57.  * permission notice:
  58.  *
  59.  * Copyright 2005-2007 The Apache Software Foundation
  60.  *
  61.  * Licensed under the Apache License, Version 2.0 (the "License");
  62.  * you may not use this file except in compliance with the License.
  63.  * You may obtain a copy of the License at
  64.  *
  65.  *     http://www.apache.org/licenses/LICENSE-2.0
  66.  *
  67.  * Unless required by applicable law or agreed to in writing, software
  68.  * distributed under the License is distributed on an "AS IS" BASIS,
  69.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  70.  * See the License for the specific language governing permissions and
  71.  * limitations under the License.
  72.  */
  73.  
  74. import com.sun.faces.component.visit.VisitUtils;
  75. import com.sun.faces.facelets.tag.IterationStatus;
  76.  
  77. import javax.el.ValueExpression;
  78. import javax.faces.FacesException;
  79. import javax.faces.application.Application;
  80. import javax.faces.application.FacesMessage;
  81. import javax.faces.component.*;
  82. import javax.faces.component.visit.VisitCallback;
  83. import javax.faces.component.visit.VisitContext;
  84. import javax.faces.component.visit.VisitResult;
  85. import javax.faces.context.FacesContext;
  86. import javax.faces.event.*;
  87. import javax.faces.model.*;
  88. import javax.faces.render.Renderer;
  89. import java.io.IOException;
  90. import java.io.Serializable;
  91. import java.sql.ResultSet;
  92. import java.util.*;
  93.  
  94. public class UIRepeat extends UINamingContainer {
  95.  
  96.   public static final String COMPONENT_TYPE = "facelets.ui.Repeat";
  97.  
  98.   public static final String COMPONENT_FAMILY = "facelets";
  99.  
  100.   private static final DataModel EMPTY_MODEL =
  101.       new ListDataModel<Object>(Collections.emptyList());
  102.  
  103.   // our data
  104.   private Object value;
  105.  
  106.   private transient DataModel model;
  107.  
  108.   // variables
  109.   private String var;
  110.  
  111.   private String varStatus;
  112.  
  113.   private int index = -1;
  114.  
  115.   private Integer begin;
  116.   private Integer end;
  117.   private Integer step;
  118.  
  119.   public UIRepeat() {
  120.     this.setRendererType("facelets.ui.Repeat");
  121.   }
  122.  
  123.   public String getFamily() {
  124.     return COMPONENT_FAMILY;
  125.   }
  126.  
  127.   public void setEnd(Integer end) {
  128.     this.end = end;
  129.   }
  130.  
  131.   public Integer getEnd() {
  132.  
  133.     if (this.end != null) {
  134.       return end;
  135.     }
  136.     ValueExpression ve = this.getValueExpression("end");
  137.     if (ve != null) {
  138.       return (Integer) ve.getValue(getFacesContext().getELContext());
  139.     }
  140.     return null;
  141.  
  142.   }
  143.  
  144.   public void setSize(Integer size) {
  145.     this.end = size;
  146.   }
  147.  
  148.   public Integer getSize() {
  149.  
  150.     if (this.end != null) {
  151.       return end;
  152.     }
  153.     ValueExpression ve = this.getValueExpression("size");
  154.     if (ve != null) {
  155.       return (Integer) ve.getValue(getFacesContext().getELContext());
  156.     }
  157.     return null;
  158.  
  159.   }
  160.  
  161.   public void setOffset(Integer offset) {
  162.     this.begin = offset;
  163.   }
  164.  
  165.   public Integer getOffset() {
  166.  
  167.     if (this.begin != null) {
  168.       return this.begin;
  169.     }
  170.     ValueExpression ve = this.getValueExpression("offset");
  171.     if (ve != null) {
  172.       return (Integer) ve.getValue(getFacesContext().getELContext());
  173.     }
  174.     return null;
  175.  
  176.   }
  177.  
  178.  
  179.   public void setBegin(Integer begin) {
  180.     this.begin = begin;
  181.   }
  182.  
  183.   public Integer getBegin() {
  184.  
  185.     if (this.begin != null) {
  186.       return this.begin;
  187.     }
  188.     ValueExpression ve = this.getValueExpression("begin");
  189.     if (ve != null) {
  190.       return (Integer) ve.getValue(getFacesContext().getELContext());
  191.     }
  192.     return null;
  193.  
  194.   }
  195.  
  196.   public void setStep(Integer step) {
  197.     this.step = step;
  198.   }
  199.  
  200.   public Integer getStep() {
  201.  
  202.     if (this.step != null) {
  203.       return this.step;
  204.     }
  205.     ValueExpression ve = this.getValueExpression("step");
  206.     if (ve != null) {
  207.       return (Integer) ve.getValue(getFacesContext().getELContext());
  208.     }
  209.     return null;
  210.  
  211.   }
  212.  
  213.  
  214.   public String getVar() {
  215.     return this.var;
  216.   }
  217.  
  218.   public void setVar(String var) {
  219.     this.var = var;
  220.   }
  221.  
  222.   public String getVarStatus() {
  223.     return varStatus;
  224.   }
  225.  
  226.   public void setVarStatus(String varStatus) {
  227.     this.varStatus = varStatus;
  228.   }
  229.  
  230.   private void resetDataModel() {
  231.     if (this.isNestedInIterator()) {
  232.       this.setDataModel(null);
  233.     }
  234.   }
  235.  
  236.   private void setDataModel(DataModel model) {
  237.     //noinspection unchecked
  238.     this.model = model;
  239.   }
  240.  
  241.   private DataModel getDataModel() {
  242.     if (this.model == null) {
  243.       Object val = this.getValue();
  244.       if (val == null) {
  245.         this.model = EMPTY_MODEL;
  246.       } else if (val instanceof DataModel) {
  247.         //noinspection unchecked
  248.         this.model = (DataModel<Object>) val;
  249.       } else if (val instanceof List) {
  250.         //noinspection unchecked
  251.         this.model = new ListDataModel<Object>((List<Object>) val);
  252.       } else if (Object[].class.isAssignableFrom(val.getClass())) {
  253.         this.model = new ArrayDataModel<Object>((Object[]) val);
  254.       } else if (val instanceof ResultSet) {
  255.         this.model = new ResultSetDataModel((ResultSet) val);
  256.       } else {
  257.         this.model = new ScalarDataModel<Object>(val);
  258.       }
  259.     }
  260.     return this.model;
  261.   }
  262.  
  263.   public Object getValue() {
  264.     if (this.value == null) {
  265.       ValueExpression ve = this.getValueExpression("value");
  266.       if (ve != null) {
  267.         return ve.getValue(getFacesContext().getELContext());
  268.       }
  269.     }
  270.     return this.value;
  271.   }
  272.  
  273.   public void setValue(Object value) {
  274.     this.value = value;
  275.   }
  276.  
  277.   private transient StringBuffer buffer;
  278.  
  279.   private StringBuffer getBuffer() {
  280.     if (this.buffer == null) {
  281.       this.buffer = new StringBuffer();
  282.     }
  283.     this.buffer.setLength(0);
  284.     return this.buffer;
  285.   }
  286.  
  287.   public String getClientId(FacesContext faces) {
  288.     String id = super.getClientId(faces);
  289.     if (this.index >= 0) {
  290.       id = this.getBuffer().append(id).append(
  291.           getSeparatorChar(faces)).append(this.index)
  292.           .toString();
  293.     }
  294.     return id;
  295.   }
  296.  
  297.   private transient Object origValueOfVar;
  298.   private transient Object origValueOfVarStatus;
  299.  
  300.   private void captureOrigValue(FacesContext ctx) {
  301.     if (this.var != null || this.varStatus != null) {
  302.       Map<String, Object> attrs = ctx.getExternalContext().getRequestMap();
  303.       if (this.var != null) {
  304.         this.origValueOfVar = attrs.get(this.var);
  305.       }
  306.       if (this.varStatus != null) {
  307.         this.origValueOfVarStatus = attrs.get(this.varStatus);
  308.       }
  309.     }
  310.   }
  311.  
  312.   private void restoreOrigValue(FacesContext ctx) {
  313.     if (this.var != null || this.varStatus != null) {
  314.       Map<String, Object> attrs = ctx.getExternalContext().getRequestMap();
  315.       if (this.var != null) {
  316.         if (this.origValueOfVar != null) {
  317.           attrs.put(this.var, this.origValueOfVar);
  318.         } else {
  319.           attrs.remove(this.var);
  320.         }
  321.       }
  322.       if (this.varStatus != null) {
  323.         if (this.origValueOfVarStatus != null) {
  324.           attrs.put(this.varStatus, this.origValueOfVarStatus);
  325.         } else {
  326.           attrs.remove(this.varStatus);
  327.         }
  328.       }
  329.     }
  330.   }
  331.  
  332.   private Map<String, SavedState> childState;
  333.  
  334.   private Map<String, SavedState> getChildState() {
  335.     if (this.childState == null) {
  336.       this.childState = new HashMap<String, SavedState>();
  337.     }
  338.     return this.childState;
  339.   }
  340.  
  341.   private void saveChildState(FacesContext ctx) {
  342.     if (this.getChildCount() > 0) {
  343.  
  344.       for (UIComponent uiComponent : this.getChildren()) {
  345.         this.saveChildState(ctx, uiComponent);
  346.       }
  347.     }
  348.   }
  349.  
  350.   private void saveChildState(FacesContext faces, UIComponent c) {
  351.  
  352.     if (shouldSaveState(c) && !c.isTransient()) {
  353.       String clientId = c.getClientId(faces);
  354.       SavedState ss = this.getChildState().get(clientId);
  355.       if (ss == null) {
  356.         ss = new SavedState();
  357.         this.getChildState().put(clientId, ss);
  358.       }
  359.       ss.populate(c);
  360.     }
  361.  
  362.     // Horus tweak: possibly skip state traversal
  363.     if (!(c instanceof UIRepeat) && !skipStateManagement(c)) {
  364.       Iterator itr = c.getFacetsAndChildren();
  365.       while (itr.hasNext())
  366.         saveChildState(faces, (UIComponent) itr.next());
  367.     }
  368.   }
  369.  
  370.   private boolean skipStateManagement(UIComponent component) {
  371.     return component instanceof DynamicInclude.DynamicIncludeComponent &&
  372.       !component.isRendered();
  373.   }
  374.  
  375.   private void restoreChildState(FacesContext ctx) {
  376.     if (this.getChildCount() > 0) {
  377.  
  378.       for (UIComponent uiComponent : this.getChildren())
  379.         this.restoreChildState(ctx, uiComponent);
  380.     }
  381.   }
  382.  
  383.   private void restoreChildState(FacesContext faces, UIComponent c) {
  384.     // this will reset client id
  385.     String id = c.getId();
  386.     c.setId(id);
  387.  
  388.     if (shouldSaveState(c)) {
  389.       String clientId = c.getClientId(faces);
  390.       SavedState ss = this.getChildState().get(clientId);
  391.       if (ss != null) {
  392.         ss.apply(c);
  393.       } else {
  394.         NullState.apply(c);
  395.       }
  396.     }
  397.  
  398.     // Horus tweak: possibly skip state traversal
  399.     if (!(c instanceof UIRepeat) && !skipStateManagement(c)) {
  400.       Iterator itr = c.getFacetsAndChildren();
  401.       while (itr.hasNext())
  402.         restoreChildState(faces, (UIComponent) itr.next());
  403.     }
  404.   }
  405.  
  406.   private boolean shouldSaveState(UIComponent c) {
  407.     return c instanceof EditableValueHolder ||
  408.       c instanceof UIRepeat || c instanceof DynamicInclude ||
  409.       c instanceof UIForm;
  410.   }
  411.  
  412.   private void resetChildId() {
  413.     if (this.getChildCount() > 0)
  414.       for (UIComponent uiComponent : this.getChildren())
  415.         this.resetChildId(uiComponent);
  416.   }
  417.  
  418.   private void resetChildId(UIComponent c) {
  419.     // reset id
  420.     String id = c.getId();
  421.     c.setId(id);
  422.  
  423.     Iterator itr = c.getFacetsAndChildren();
  424.     while (itr.hasNext()) {
  425.       resetChildId((UIComponent) itr.next());
  426.     }
  427.   }
  428.  
  429.   private boolean keepSaved(FacesContext context) {
  430.  
  431.     return (hasErrorMessages(context) || isNestedInIterator());
  432.  
  433.   }
  434.  
  435.   private boolean hasErrorMessages(FacesContext context) {
  436.  
  437.     FacesMessage.Severity sev = context.getMaximumSeverity();
  438.     return (sev != null && (FacesMessage.SEVERITY_ERROR.compareTo(sev) >= 0));
  439.  
  440.   }
  441.  
  442.   private boolean isNestedInIterator() {
  443.     UIComponent parent = this.getParent();
  444.     while (parent != null) {
  445.       if (parent instanceof UIData || parent instanceof UIRepeat) {
  446.         return true;
  447.       }
  448.       parent = parent.getParent();
  449.     }
  450.     return false;
  451.   }
  452.  
  453.   private void setIndex(FacesContext ctx, int index) {
  454.     // save child state
  455.     this.saveChildState(ctx);
  456.  
  457.     this.index = index;
  458.     DataModel localModel = getDataModel();
  459.     localModel.setRowIndex(index);
  460.  
  461.     if (this.index != -1 && this.var != null && localModel.isRowAvailable()) {
  462.       Map<String, Object> attrs = ctx.getExternalContext().getRequestMap();
  463.       attrs.put(var, localModel.getRowData());
  464.     }
  465.  
  466.     // reset child clientId and restore child state
  467.     this.restoreChildState(ctx);
  468.   }
  469.  
  470.   private void updateIterationStatus(FacesContext ctx, IterationStatus status) {
  471.     if (this.varStatus != null) {
  472.       Map<String, Object> attrs = ctx.getExternalContext().getRequestMap();
  473.       attrs.put(varStatus, status);
  474.     }
  475.   }
  476.  
  477.   private boolean isIndexAvailable() {
  478.     return this.getDataModel().isRowAvailable();
  479.   }
  480.  
  481.   public void process(FacesContext faces, PhaseId phase) {
  482.  
  483.     // stop if not rendered
  484.     if (!this.isRendered())
  485.       return;
  486.  
  487.     // clear datamodel
  488.     this.resetDataModel();
  489.  
  490.     // reset index
  491.     this.captureOrigValue(faces);
  492.     this.setIndex(faces, -1);
  493.  
  494.     try {
  495.       // has children
  496.       if (this.getChildCount() > 0) {
  497.         Iterator itr;
  498.         UIComponent c;
  499.  
  500.         Integer begin = this.getBegin();
  501.         Integer step = this.getStep();
  502.         Integer end = this.getEnd();
  503.  
  504.         // grab renderer
  505.         String rendererType = getRendererType();
  506.         Renderer renderer = null;
  507.         if (rendererType != null) {
  508.           renderer = getRenderer(faces);
  509.         }
  510.  
  511.         int rowCount = getDataModel().getRowCount();
  512.         int i = ((begin != null) ? begin : 0);
  513.         int e = ((end != null) ? end : rowCount);
  514.         int s = ((step != null) ? step : 1);
  515.         validateIterationControlValues(rowCount, i, e);
  516.  
  517.         this.setIndex(faces, i);
  518.         this.updateIterationStatus(faces, new IterationStatus(true, (i + s > e || rowCount == 1), i, begin, end, step));
  519.         while (i <= e && this.isIndexAvailable()) {
  520.  
  521.           if (PhaseId.RENDER_RESPONSE.equals(phase)
  522.               && renderer != null) {
  523.             renderer.encodeChildren(faces, this);
  524.           } else {
  525.             itr = this.getChildren().iterator();
  526.             while (itr.hasNext()) {
  527.               c = (UIComponent) itr.next();
  528.               if (PhaseId.APPLY_REQUEST_VALUES.equals(phase)) {
  529.                 c.processDecodes(faces);
  530.               } else if (PhaseId.PROCESS_VALIDATIONS
  531.                   .equals(phase)) {
  532.                 c.processValidators(faces);
  533.               } else if (PhaseId.UPDATE_MODEL_VALUES
  534.                   .equals(phase)) {
  535.                 c.processUpdates(faces);
  536.               } else if (PhaseId.RENDER_RESPONSE.equals(phase)) {
  537.                 c.encodeAll(faces);
  538.               }
  539.             }
  540.           }
  541.           i += s;
  542.           this.setIndex(faces, i);
  543.           this.updateIterationStatus(faces, new IterationStatus(false, i + s >= e, i, begin, end, step));
  544.         }
  545.       }
  546.     } catch (IOException e) {
  547.       throw new FacesException(e);
  548.     } finally {
  549.       this.setIndex(faces, -1);
  550.       // Horus tweak: since we may have skipped some traversals, do full reset here
  551.       if (!isNestedInIterator())
  552.         this.resetChildId();
  553.       this.restoreOrigValue(faces);
  554.     }
  555.   }
  556.  
  557.   public boolean invokeOnComponent(FacesContext faces, String clientId,
  558.                                    ContextCallback callback) throws FacesException {
  559.     String id = super.getClientId(faces);
  560.     if (clientId.equals(id)) {
  561.       callback.invokeContextCallback(faces, this);
  562.       return true;
  563.     } else if (clientId.startsWith(id)) {
  564.       int prevIndex = this.index;
  565.       int idxStart = clientId.indexOf(getSeparatorChar(faces), id
  566.           .length());
  567.       if (idxStart != -1
  568.           && Character.isDigit(clientId.charAt(idxStart + 1))) {
  569.         int idxEnd = clientId.indexOf(getSeparatorChar(faces),
  570.             idxStart + 1);
  571.         if (idxEnd != -1) {
  572.           int newIndex = Integer.parseInt(clientId.substring(
  573.               idxStart + 1, idxEnd));
  574.           boolean found = false;
  575.           try {
  576.             this.captureOrigValue(faces);
  577.             this.setIndex(faces, newIndex);
  578.             if (this.isIndexAvailable()) {
  579.               found = super.invokeOnComponent(faces, clientId,
  580.                   callback);
  581.             }
  582.           } finally {
  583.             this.setIndex(faces, prevIndex);
  584.             this.restoreOrigValue(faces);
  585.           }
  586.           return found;
  587.         }
  588.       } else {
  589.         return super.invokeOnComponent(faces, clientId, callback);
  590.       }
  591.     }
  592.     return false;
  593.   }
  594.  
  595.   @Override
  596.   public boolean visitTree(VisitContext context, VisitCallback callback) {
  597.     // First check to see whether we are visitable.  If not
  598.     // short-circuit out of this subtree, though allow the
  599.     // visit to proceed through to other subtrees.
  600.     if (!isVisitable(context)) {
  601.       return false;
  602.     }
  603.  
  604.     FacesContext facesContext = context.getFacesContext();
  605.     boolean visitRows = requiresRowIteration(facesContext);
  606.     int oldRowIndex = -1;
  607.     if (visitRows) {
  608.       oldRowIndex = getDataModel().getRowIndex();
  609.       // Horus tweak: same as second step in process().
  610.       // visitTree does not use process but decides about descent based on
  611.       // presence of rows in the model.
  612.       if (isNestedInIterator())
  613.         this.resetDataModel();
  614.       setIndex(facesContext, -1);
  615.     }
  616.  
  617.     // Push ourselves to EL
  618.     pushComponentToEL(facesContext, null);
  619.  
  620.     try {
  621.  
  622.       // Visit ourselves.  Note that we delegate to the
  623.       // VisitContext to actually perform the visit.
  624.       VisitResult result = context.invokeVisitCallback(this, callback);
  625.  
  626.       // If the visit is complete, short-circuit out and end the visit
  627.       if (result == VisitResult.COMPLETE) {
  628.         return true;
  629.       }
  630.  
  631.       // Visit children, short-circuiting as necessary
  632.       if ((result == VisitResult.ACCEPT) && doVisitChildren(context)) {
  633.  
  634.         // And finally, visit rows
  635.         if (!visitRows) {
  636.           // visit rows without model access
  637.           for (UIComponent kid : getChildren()) {
  638.             if (kid.visitTree(context, callback)) {
  639.               return true;
  640.             }
  641.           }
  642.         } else {
  643.           if (visitChildren(context, callback)) {
  644.             return true;
  645.           }
  646.         }
  647.       }
  648.     } finally {
  649.       // Clean up - pop EL and restore old row index
  650.       popComponentFromEL(facesContext);
  651.       if (visitRows) {
  652.         setIndex(facesContext, oldRowIndex);
  653.         // Horus change: this is needed in case of partial rendering where
  654.         // visitTree is used instead of UIRepeat.process
  655.         if (!isNestedInIterator())
  656.           this.resetChildId();
  657.       }
  658.     }
  659.  
  660.     // Return false to allow the visit to continue
  661.     return false;
  662.   }
  663.  
  664.   private boolean requiresRowIteration(FacesContext ctx) {
  665.  
  666.     return !VisitUtils.isSkippingIteration(ctx);
  667.  
  668.   }
  669.  
  670.   // Tests whether we need to visit our children as part of
  671.   // a tree visit
  672.   private boolean doVisitChildren(VisitContext context) {
  673.  
  674.     // Just need to check whether there are any ids under this
  675.     // subtree.  Make sure row index is cleared out since
  676.     // getSubtreeIdsToVisit() needs our row-less client id.
  677.     setIndex(context.getFacesContext(), -1);
  678.     Collection<String> idsToVisit = context.getSubtreeIdsToVisit(this);
  679.     assert (idsToVisit != null);
  680.  
  681.     // All ids or non-empty collection means we need to visit our children.
  682.     return (!idsToVisit.isEmpty());
  683.  
  684.   }
  685.  
  686.  
  687.   private void validateIterationControlValues(int rowCount,
  688.                                               int begin,
  689.                                               int end) {
  690.  
  691.     if (rowCount == 0) {
  692.       return;
  693.     }
  694.     // PENDING i18n
  695.     if (begin > rowCount) {
  696.       throw new FacesException("Iteration start index is greater than the number of available rows.");
  697.     }
  698.     if (begin > end) {
  699.       throw new FacesException("Iteration start index is greater than the end index.");
  700.     }
  701.     if (end > rowCount) {
  702.       throw new FacesException("Iteration end index is greater than the number of available rows.");
  703.     }
  704.   }
  705.  
  706.  
  707.   private boolean visitChildren(VisitContext context, VisitCallback callback) {
  708.  
  709.     Integer begin = this.getBegin();
  710.     Integer end = this.getEnd();
  711.     Integer step = this.getStep();
  712.  
  713.     int rowCount = getDataModel().getRowCount();
  714.     int i = ((begin != null) ? begin : 0);
  715.     int e = ((end != null) ? end : rowCount);
  716.     int s = ((step != null) ? step : 1);
  717.     validateIterationControlValues(rowCount, i, e);
  718.     FacesContext faces = context.getFacesContext();
  719.     this.setIndex(faces, i);
  720.     this.updateIterationStatus(faces,
  721.         new IterationStatus(true,
  722.             (i + s > e || rowCount == 1),
  723.             i,
  724.             begin,
  725.             end,
  726.             step));
  727.     while (i <= e && this.isIndexAvailable()) {
  728.  
  729.       this.setIndex(faces, i);
  730.       this.updateIterationStatus(faces,
  731.           new IterationStatus(false,
  732.               i + s >= e,
  733.               i,
  734.               begin,
  735.               end,
  736.               step));
  737.       for (UIComponent kid : getChildren()) {
  738.         if (kid.visitTree(context, callback)) {
  739.           return true;
  740.         }
  741.       }
  742.       i += s;
  743.     }
  744.  
  745.  
  746.     return false;
  747.   }
  748.  
  749.  
  750.   public void processDecodes(FacesContext faces) {
  751.     if (!this.isRendered())
  752.       return;
  753.     this.setDataModel(null);
  754.     if (!this.keepSaved(faces)) this.childState = null;
  755.     this.process(faces, PhaseId.APPLY_REQUEST_VALUES);
  756.     this.decode(faces);
  757.   }
  758.  
  759.   public void processUpdates(FacesContext faces) {
  760.     if (!this.isRendered()) return;
  761.     this.resetDataModel();
  762.     this.process(faces, PhaseId.UPDATE_MODEL_VALUES);
  763.   }
  764.  
  765.   public void processValidators(FacesContext faces) {
  766.     if (!this.isRendered()) return;
  767.     this.resetDataModel();
  768.     Application app = faces.getApplication();
  769.     app.publishEvent(faces, PreValidateEvent.class, this);
  770.     this.process(faces, PhaseId.PROCESS_VALIDATIONS);
  771.     app.publishEvent(faces, PostValidateEvent.class, this);
  772.   }
  773.  
  774.   private static final SavedState NullState = new SavedState();
  775.  
  776.   // from RI
  777.   private static final class SavedState implements Serializable {
  778.  
  779.     private Object submittedValue;
  780.     private static final long serialVersionUID = 2920252657338389849L;
  781.     private boolean valid = true;
  782.     private Object value;
  783.     private boolean localValueSet;
  784.     private boolean submitted = true;
  785.  
  786.     public String toString() {
  787.       return ("submittedValue: " + submittedValue + " value: " + value
  788.           + " localValueSet: " + localValueSet);
  789.     }
  790.  
  791.     public void populate(UIComponent c) {
  792.       // Horus tweak: support for additional types
  793.       if (c instanceof EditableValueHolder) {
  794.         EditableValueHolder evh = (EditableValueHolder) c;
  795.         this.value = evh.getLocalValue();
  796.         this.valid = evh.isValid();
  797.         this.submittedValue = evh.getSubmittedValue();
  798.         this.localValueSet = evh.isLocalValueSet();
  799.       } else if (c instanceof UIForm) {
  800.         this.submitted = ((UIForm)c).isSubmitted();
  801.       } else if (c instanceof UIRepeat) {
  802.         this.value = ((UIRepeat)c).getChildState();
  803.       } else if (c instanceof DynamicInclude) {
  804.         this.value = ((DynamicInclude)c).getSrc();
  805.       }
  806.     }
  807.  
  808.     public void apply(UIComponent c) {
  809.       // Horus tweak: support for additional types
  810.       if (c instanceof EditableValueHolder) {
  811.         EditableValueHolder evh = (EditableValueHolder) c;
  812.         if (this.localValueSet)
  813.           evh.setValue(this.value);
  814.         evh.setValid(this.valid);
  815.         evh.setSubmittedValue(this.submittedValue);
  816.         evh.setLocalValueSet(this.localValueSet);
  817.       } else if (c instanceof UIForm) {
  818.         ((UIForm)c).setSubmitted(this.submitted);
  819.       } else if (c instanceof UIRepeat) {
  820.         ((UIRepeat)c).childState = (Map<String, SavedState>) this.value;
  821.       } else if (c instanceof DynamicInclude) {
  822.         ((DynamicInclude)c).setSrc((String)this.value);
  823.       }
  824.     }
  825.   }
  826.  
  827.   private static final class IndexedEvent extends FacesEvent {
  828.  
  829.     private final FacesEvent target;
  830.  
  831.     private final int index;
  832.  
  833.     public IndexedEvent(UIRepeat owner, FacesEvent target, int index) {
  834.       super(owner);
  835.       this.target = target;
  836.       this.index = index;
  837.     }
  838.  
  839.     public PhaseId getPhaseId() {
  840.       return (this.target.getPhaseId());
  841.     }
  842.  
  843.     public void setPhaseId(PhaseId phaseId) {
  844.       this.target.setPhaseId(phaseId);
  845.     }
  846.  
  847.     public boolean isAppropriateListener(FacesListener listener) {
  848.       return this.target.isAppropriateListener(listener);
  849.     }
  850.  
  851.     public void processListener(FacesListener listener) {
  852.       UIRepeat owner = (UIRepeat) this.getComponent();
  853.       int prevIndex = owner.index;
  854.       FacesContext ctx = FacesContext.getCurrentInstance();
  855.       try {
  856.         owner.setIndex(ctx, this.index);
  857.         if (owner.isIndexAvailable()) {
  858.           this.target.processListener(listener);
  859.         }
  860.       } finally {
  861.         owner.setIndex(ctx, prevIndex);
  862.       }
  863.     }
  864.  
  865.     public int getIndex() {
  866.       return index;
  867.     }
  868.  
  869.     public FacesEvent getTarget() {
  870.       return target;
  871.     }
  872.  
  873.   }
  874.  
  875.   public void broadcast(FacesEvent event) throws AbortProcessingException {
  876.     if (event instanceof IndexedEvent) {
  877.       IndexedEvent idxEvent = (IndexedEvent) event;
  878.       this.resetDataModel();
  879.       int prevIndex = this.index;
  880.       FacesContext ctx = FacesContext.getCurrentInstance();
  881.       FacesEvent target = idxEvent.getTarget();
  882.       UIComponent source = target.getComponent();
  883.       UIComponent compositeParent = null;
  884.       try {
  885.         int rowCount = getDataModel().getRowCount();
  886.         int idx = idxEvent.getIndex();
  887.         this.setIndex(ctx, idx);
  888.         Integer begin = this.getBegin();
  889.         Integer end = this.getEnd();
  890.         Integer step = this.getStep();
  891.         int b = ((end != null) ? end : 0);
  892.         int e = ((end != null) ? end : rowCount);
  893.         int s = ((step != null) ? step : 1);
  894.         this.updateIterationStatus(ctx,
  895.             new IterationStatus(idx == b,
  896.                 (idx + s >= e || rowCount == 1),
  897.                 idx,
  898.                 begin,
  899.                 end,
  900.                 step));
  901.         if (this.isIndexAvailable()) {
  902.           if (!UIComponent.isCompositeComponent(source)) {
  903.             compositeParent = UIComponent
  904.                 .getCompositeComponentParent(source);
  905.           }
  906.           if (compositeParent != null) {
  907.             compositeParent.pushComponentToEL(ctx, null);
  908.           }
  909.           source.pushComponentToEL(ctx, null);
  910.           source.broadcast(target);
  911.  
  912.         }
  913.       } finally {
  914.         source.popComponentFromEL(ctx);
  915.         if (compositeParent != null) {
  916.           compositeParent.popComponentFromEL(ctx);
  917.         }
  918.         this.updateIterationStatus(ctx, null);
  919.         this.setIndex(ctx, prevIndex);
  920.         if (!isNestedInIterator())
  921.           this.resetChildId();
  922.       }
  923.     } else {
  924.       super.broadcast(event);
  925.     }
  926.   }
  927.  
  928.   public void queueEvent(FacesEvent event) {
  929.     super.queueEvent(new IndexedEvent(this, event, this.index));
  930.   }
  931.  
  932.   public void restoreState(FacesContext faces, Object object) {
  933.     if (faces == null) {
  934.       throw new NullPointerException();
  935.     }
  936.     if (object == null) {
  937.       return;
  938.     }
  939.     Object[] state = (Object[]) object;
  940.     super.restoreState(faces, state[0]);
  941.     //noinspection unchecked
  942.     this.childState = (Map<String, SavedState>) state[1];
  943.     this.begin = (Integer) state[2];
  944.     this.end = (Integer) state[3];
  945.     this.step = (Integer) state[4];
  946.     this.var = (String) state[5];
  947.     this.varStatus = (String) state[6];
  948.     this.value = state[7];
  949.   }
  950.  
  951.   public Object saveState(FacesContext faces) {
  952.     if (faces == null) {
  953.       throw new NullPointerException();
  954.     }
  955.     Object[] state = new Object[8];
  956.     state[0] = super.saveState(faces);
  957.     state[1] = this.childState;
  958.     state[2] = this.begin;
  959.     state[3] = this.end;
  960.     state[4] = this.step;
  961.     state[5] = this.var;
  962.     state[6] = this.varStatus;
  963.     state[7] = this.value;
  964.     return state;
  965.   }
  966.  
  967.   public void encodeChildren(FacesContext faces) throws IOException {
  968.     if (!isRendered()) {
  969.       return;
  970.     }
  971.     this.setDataModel(null);
  972.     if (!this.keepSaved(faces)) {
  973.       this.childState = null;
  974.     }
  975.     this.process(faces, PhaseId.RENDER_RESPONSE);
  976.   }
  977.  
  978.   public boolean getRendersChildren() {
  979.     if (getRendererType() != null) {
  980.       Renderer renderer = getRenderer(getFacesContext());
  981.       if (renderer != null) {
  982.         return renderer.getRendersChildren();
  983.       }
  984.     }
  985.     return true;
  986.   }
  987. }
Advertisement
Add Comment
Please, Sign In to add comment