1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.lifecycle;
20
21 import java.io.IOException;
22 import java.util.List;
23 import java.util.logging.Level;
24 import java.util.logging.Logger;
25
26 import javax.faces.FacesException;
27 import javax.faces.application.Application;
28 import javax.faces.application.FacesMessage;
29 import javax.faces.application.ProjectStage;
30 import javax.faces.application.ViewHandler;
31 import javax.faces.component.UIViewRoot;
32 import javax.faces.context.FacesContext;
33 import javax.faces.event.PhaseId;
34 import javax.faces.event.PreRenderViewEvent;
35 import javax.faces.view.ViewDeclarationLanguage;
36
37
38
39
40
41
42
43 class RenderResponseExecutor extends PhaseExecutor
44 {
45
46 private static final Logger log = Logger.getLogger(RenderResponseExecutor.class.getName());
47
48 public boolean execute(FacesContext facesContext)
49 {
50 Application application = facesContext.getApplication();
51 ViewHandler viewHandler = application.getViewHandler();
52 UIViewRoot root;
53 UIViewRoot previousRoot;
54 String viewId;
55 String newViewId;
56 boolean isNotSameRoot;
57 int loops = 0;
58 int maxLoops = 15;
59
60 if (facesContext.getViewRoot() == null)
61 {
62 throw new ViewNotFoundException("A view is required to execute "+facesContext.getCurrentPhaseId());
63 }
64
65 try
66 {
67
68 do
69 {
70 root = facesContext.getViewRoot();
71 previousRoot = root;
72 viewId = root.getViewId();
73
74 ViewDeclarationLanguage vdl = viewHandler.getViewDeclarationLanguage(
75 facesContext, viewId);
76 if (vdl != null)
77 {
78 vdl.buildView(facesContext, root);
79 }
80
81
82
83
84 application.publishEvent(facesContext, PreRenderViewEvent.class, root);
85
86
87 if (facesContext.getResponseComplete())
88 {
89 return false;
90 }
91
92 root = facesContext.getViewRoot();
93
94 newViewId = root.getViewId();
95
96 isNotSameRoot = !( (newViewId == null ? newViewId == viewId : newViewId.equals(viewId) ) &&
97 previousRoot.equals(root) );
98
99 loops++;
100 }
101 while ((newViewId == null && viewId != null)
102 || (newViewId != null && (!newViewId.equals(viewId) || isNotSameRoot ) ) && loops < maxLoops);
103
104 if (loops == maxLoops)
105 {
106
107 boolean production = facesContext.isProjectStage(ProjectStage.Production);
108 Level level = production ? Level.FINE : Level.WARNING;
109 if (log.isLoggable(level))
110 {
111 log.log(level, "Cicle over buildView-PreRenderViewEvent on RENDER_RESPONSE phase reaches maximal limit, please check " +
112 "listeners for infinite recursion.");
113 }
114 }
115
116 viewHandler.renderView(facesContext, root);
117
118
119
120
121
122 List<FacesMessage> messageList = facesContext.getMessageList();
123 if (!messageList.isEmpty())
124 {
125 StringBuilder builder = new StringBuilder();
126 boolean shouldLog = false;
127 for (int i = 0, size = messageList.size(); i < size; i++)
128 {
129 FacesMessage message = messageList.get(i);
130 if (!message.isRendered())
131 {
132 builder.append("\n- ");
133 builder.append(message.getDetail());
134
135 shouldLog = true;
136 }
137 }
138 if (shouldLog)
139 {
140 log.log(Level.WARNING, "There are some unhandled FacesMessages, " +
141 "this means not every FacesMessage had a chance to be rendered.\n" +
142 "These unhandled FacesMessages are: " + builder.toString());
143 }
144 }
145 }
146 catch (IOException e)
147 {
148 throw new FacesException(e.getMessage(), e);
149 }
150 return false;
151 }
152
153 public PhaseId getPhase()
154 {
155 return PhaseId.RENDER_RESPONSE;
156 }
157 }