View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.uif.lifecycle;
17  
18  import java.util.Queue;
19  import java.util.Set;
20  
21  import org.kuali.rice.krad.uif.UifConstants;
22  import org.kuali.rice.krad.uif.component.Component;
23  import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle.LifecycleEvent;
24  import org.kuali.rice.krad.uif.util.LifecycleElement;
25  import org.kuali.rice.krad.uif.util.RecycleUtils;
26  
27  /**
28   * Lifecycle phase processing task for rendering a component.
29   *
30   * @author Kuali Rice Team (rice.collab@kuali.org)
31   * @see ViewLifecycle#isRenderInLifecycle()
32   */
33  public class RenderComponentPhase extends ViewLifecyclePhaseBase {
34  
35      private RenderComponentPhase renderParent;
36      private Set<String> pendingChildren;
37  
38      /**
39       * {@inheritDoc}
40       */
41      @Override
42      public void recycle() {
43          super.recycle();
44          renderParent = null;
45          pendingChildren = null;
46      }
47  
48      /**
49       * Create a new lifecycle phase processing task for finalizing a component.
50       *
51       * @param renderParent rendering phase to queue as a successor when all children have processed
52       * @param pendingChildren set of paths to child rendering phases to expect to be queued for
53       * processing before this phase
54       */
55      void prepareRenderPhase(RenderComponentPhase renderParent, Set<String> pendingChildren) {
56          this.renderParent = renderParent;
57          this.pendingChildren = pendingChildren;
58      }
59  
60      /**
61       * {@inheritDoc}
62       *
63       * @return UifConstants.ViewPhases.RENDER
64       */
65      @Override
66      public String getViewPhase() {
67          return UifConstants.ViewPhases.RENDER;
68      }
69  
70      /**
71       * {@inheritDoc}
72       *
73       * @return UifConstants.ViewStatus.FINAL
74       */
75      @Override
76      public String getStartViewStatus() {
77          return UifConstants.ViewStatus.FINAL;
78      }
79  
80      /**
81       * {@inheritDoc}
82       *
83       * @return UifConstants.ViewStatus.RENDERED
84       */
85      @Override
86      public String getEndViewStatus() {
87          return UifConstants.ViewStatus.RENDERED;
88      }
89  
90      /**
91       * {@inheritDoc}
92       */
93      @Override
94      public LifecycleEvent getEventToNotify() {
95          return null;
96      }
97  
98      /**
99       * Verify that the all pending children have completed.
100      */
101     @Override
102     protected void verifyCompleted() {
103         if (pendingChildren != null) {
104             ViewLifecycle.reportIllegalState("Render phase is not complete, children are still pending "
105                     + pendingChildren + "\n" + this);
106         }
107     }
108 
109     /**
110      * {@inheritDoc}
111      */
112     @Override
113     protected void initializeSuccessors(Queue<ViewLifecyclePhase> successors) {
114         if (renderParent == null || renderParent.pendingChildren == null) {
115             trace(renderParent == null ? "no-parent" : "no-children");
116             return;
117         }
118 
119         synchronized (renderParent) {
120             // InitializeSuccessors is invoked right after processing.
121             // Once the last sibling is processed, then queue the parent phase as a successor.
122             if (!renderParent.pendingChildren.remove(getParentPath())) {
123                 ViewLifecycle.reportIllegalState("Render phase isn't a pending child\n"
124                         + this + "\nRender Parent: " + renderParent);
125             }
126 
127             trace("remove-child " + renderParent.getElement().getId() + " " +
128                     renderParent.getViewPath() + " " + getParentPath() + " "
129                     + renderParent.pendingChildren);
130 
131             if (renderParent.pendingChildren.isEmpty()) {
132                 successors.add(renderParent);
133                 renderParent.trace("pend-rend");
134                 
135                 Set<String> toRecycle = renderParent.pendingChildren;
136                 renderParent.pendingChildren = null;
137                 RecycleUtils.recycle(toRecycle);
138             }
139         }
140     }
141 
142     /**
143      * {@inheritDoc}
144      */
145     @Override
146     protected ViewLifecyclePhase initializeSuccessor(LifecycleElement nestedElement, String nestedPath,
147             Component parent) {
148         return null;
149     }
150 
151 }