001/** 002 * Copyright 2005-2018 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krad.uif.lifecycle; 017 018import java.util.Queue; 019import java.util.Set; 020 021import org.kuali.rice.krad.uif.UifConstants; 022import org.kuali.rice.krad.uif.component.Component; 023import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle.LifecycleEvent; 024import org.kuali.rice.krad.uif.util.LifecycleElement; 025import org.kuali.rice.krad.uif.util.RecycleUtils; 026 027/** 028 * Lifecycle phase processing task for rendering a component. 029 * 030 * @author Kuali Rice Team (rice.collab@kuali.org) 031 * @see ViewLifecycle#isRenderInLifecycle() 032 */ 033public class RenderComponentPhase extends ViewLifecyclePhaseBase { 034 035 private RenderComponentPhase renderParent; 036 private Set<String> pendingChildren; 037 038 /** 039 * {@inheritDoc} 040 */ 041 @Override 042 public void recycle() { 043 super.recycle(); 044 renderParent = null; 045 pendingChildren = null; 046 } 047 048 /** 049 * Create a new lifecycle phase processing task for finalizing a component. 050 * 051 * @param renderParent rendering phase to queue as a successor when all children have processed 052 * @param pendingChildren set of paths to child rendering phases to expect to be queued for 053 * processing before this phase 054 */ 055 void prepareRenderPhase(RenderComponentPhase renderParent, Set<String> pendingChildren) { 056 this.renderParent = renderParent; 057 this.pendingChildren = pendingChildren; 058 } 059 060 /** 061 * {@inheritDoc} 062 * 063 * @return UifConstants.ViewPhases.RENDER 064 */ 065 @Override 066 public String getViewPhase() { 067 return UifConstants.ViewPhases.RENDER; 068 } 069 070 /** 071 * {@inheritDoc} 072 * 073 * @return UifConstants.ViewStatus.FINAL 074 */ 075 @Override 076 public String getStartViewStatus() { 077 return UifConstants.ViewStatus.FINAL; 078 } 079 080 /** 081 * {@inheritDoc} 082 * 083 * @return UifConstants.ViewStatus.RENDERED 084 */ 085 @Override 086 public String getEndViewStatus() { 087 return UifConstants.ViewStatus.RENDERED; 088 } 089 090 /** 091 * {@inheritDoc} 092 */ 093 @Override 094 public LifecycleEvent getEventToNotify() { 095 return null; 096 } 097 098 /** 099 * 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}