1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
21
22 import org.apache.myfaces.tobago.ajax.AjaxUtils;
23 import org.apache.myfaces.tobago.component.Attributes;
24 import org.apache.myfaces.tobago.component.Facets;
25 import org.apache.myfaces.tobago.component.RendererTypes;
26 import org.apache.myfaces.tobago.component.UIBox;
27 import org.apache.myfaces.tobago.component.UIButton;
28 import org.apache.myfaces.tobago.component.UICell;
29 import org.apache.myfaces.tobago.component.UICommand;
30 import org.apache.myfaces.tobago.component.UIGridLayout;
31 import org.apache.myfaces.tobago.component.UIMessages;
32 import org.apache.myfaces.tobago.component.UIPanel;
33 import org.apache.myfaces.tobago.component.UIPopup;
34 import org.apache.myfaces.tobago.config.Configurable;
35 import org.apache.myfaces.tobago.context.Markup;
36 import org.apache.myfaces.tobago.context.ResourceManagerUtils;
37 import org.apache.myfaces.tobago.internal.ajax.AjaxInternalUtils;
38 import org.apache.myfaces.tobago.internal.component.AbstractUIPage;
39 import org.apache.myfaces.tobago.internal.util.FacesContextUtils;
40 import org.apache.myfaces.tobago.layout.Measure;
41 import org.apache.myfaces.tobago.renderkit.LayoutComponentRendererBase;
42 import org.apache.myfaces.tobago.renderkit.css.Classes;
43 import org.apache.myfaces.tobago.renderkit.css.Style;
44 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
45 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
46 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
47 import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
48 import org.apache.myfaces.tobago.util.ComponentUtils;
49 import org.apache.myfaces.tobago.util.CreateComponentUtils;
50 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 import javax.faces.application.FacesMessage;
55 import javax.faces.component.UIComponent;
56 import javax.faces.context.FacesContext;
57 import java.io.IOException;
58 import java.util.List;
59 import java.util.Map;
60
61 public class MessagesRenderer extends LayoutComponentRendererBase {
62
63 private static final Logger LOG = LoggerFactory.getLogger(MessagesRenderer.class);
64
65 public static final String CLOSE_POPUP = "closePopup";
66
67 @Override
68 public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
69
70 UIMessages messages = (UIMessages) component;
71
72 if (messages.isConfirmation()) {
73 createPopup(facesContext, messages);
74 return;
75 }
76
77 TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
78
79 if (LOG.isDebugEnabled()) {
80 LOG.debug("facesContext is " + facesContext.getClass().getName());
81 }
82 List<UIMessages.Item> messageList = messages.createMessageList(facesContext);
83
84 if (messageList.size() > 0) {
85 writer.startElement(HtmlElements.SPAN, messages);
86 writer.writeClassAttribute(Classes.create(messages));
87 HtmlRendererUtils.writeDataAttributes(facesContext, writer, messages);
88 writer.writeStyleAttribute(new Style(facesContext, messages));
89
90
91
92
93
94
95
96
97
98
99
100
101 for (UIMessages.Item item : messageList) {
102 encodeMessage(writer, messages, item.getFacesMessage(), item.getClientId());
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116
117 writer.endElement(HtmlElements.SPAN);
118 if (messages.getFor() == null) {
119 String clientId = messages.getClientId(facesContext);
120 writer.startElement(HtmlElements.INPUT, null);
121 writer.writeAttribute(HtmlAttributes.VALUE, Boolean.TRUE.toString(), false);
122 writer.writeAttribute(HtmlAttributes.ID,
123 clientId + ComponentUtils.SUB_SEPARATOR + "messagesExists", false);
124 writer.writeAttribute(HtmlAttributes.NAME,
125 clientId + ComponentUtils.SUB_SEPARATOR + "messagesExists", false);
126 writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
127 writer.endElement(HtmlElements.INPUT);
128 }
129 }
130 if (messages.getFor() == null
131 && !AjaxUtils.isAjaxRequest(facesContext)) {
132 AjaxInternalUtils.storeMessagesClientIds(facesContext, messages);
133 }
134 }
135
136 private void createPopup(FacesContext facesContext, UIMessages messages) {
137 if (LOG.isDebugEnabled()) {
138 LOG.debug("POPUP");
139 }
140 String id = messages.getId() != null ? messages.getId() + "popup" : facesContext.getViewRoot().createUniqueId();
141 final UIPopup popup = (UIPopup)
142 CreateComponentUtils.createComponent(facesContext, UIPopup.COMPONENT_TYPE, RendererTypes.POPUP, id);
143 popup.getAttributes().put(Attributes.Z_INDEX, 10);
144
145 AbstractUIPage page = ComponentUtils.findPage(facesContext, messages);
146
147 popup.setWidth(page.getCurrentWidth().subtract(200));
148 popup.setHeight(page.getCurrentHeight().subtract(200));
149 popup.setLeft(Measure.valueOf(100));
150 popup.setTop(Measure.valueOf(100));
151 popup.setRendered(true);
152 popup.setActivated(true);
153 popup.onComponentPopulated(facesContext, messages);
154 FacesContextUtils.addPopup(facesContext, popup);
155
156 Map<String, Object> okButtonAttributes = popup.getAttributes();
157 okButtonAttributes.put(Attributes.POPUP_RESET, Boolean.TRUE);
158
159 final UIComponent box = CreateComponentUtils.createComponent(
160 facesContext, UIBox.COMPONENT_TYPE, RendererTypes.BOX);
161 popup.getChildren().add(box);
162 box.setId("box");
163
164 box.getAttributes().put(Attributes.LABEL, ResourceManagerUtils.getPropertyNotNull(
165 facesContext, "tobago", "tobago.message.confirmation.title"));
166 UIComponent layout = CreateComponentUtils.createComponent(
167 facesContext, UIGridLayout.COMPONENT_TYPE, RendererTypes.GRID_LAYOUT, "layout");
168 box.getFacets().put(Facets.LAYOUT, layout);
169 layout.getAttributes().put(Attributes.ROWS, "*;auto");
170 layout.getAttributes().put(Attributes.MARGIN, Measure.valueOf(10));
171
172 final UICell scrollPanel = (UICell)
173 CreateComponentUtils.createComponent(facesContext, UICell.COMPONENT_TYPE, "Cell", "messagePanel");
174 box.getChildren().add(scrollPanel);
175
176 messages.getParent().getChildren().remove(messages);
177 messages.setConfirmation(false);
178 scrollPanel.onComponentPopulated(facesContext, messages);
179 scrollPanel.setScrollbars("auto");
180 scrollPanel.getChildren().add(messages);
181
182 UIComponent buttonPanel = CreateComponentUtils.createComponent(
183 facesContext, UIPanel.COMPONENT_TYPE, RendererTypes.PANEL, "buttonPanel");
184 layout = CreateComponentUtils.createComponent(
185 facesContext, UIGridLayout.COMPONENT_TYPE, RendererTypes.GRID_LAYOUT, "buttonPanelLayout");
186 buttonPanel.getFacets().put(Facets.LAYOUT, layout);
187 layout.getAttributes().put(Attributes.COLUMNS, "*;100px");
188 layout.getAttributes().put(Attributes.ROWS, "auto");
189
190 box.getChildren().add(buttonPanel);
191
192 final UICell space = (UICell)
193 CreateComponentUtils.createComponent(facesContext, UICell.COMPONENT_TYPE, "Cell", "space");
194 buttonPanel.getChildren().add(space);
195 space.onComponentPopulated(facesContext, messages);
196
197 final UICommand okButton = (UICommand) CreateComponentUtils.createComponent(
198 facesContext, UIButton.COMPONENT_TYPE, RendererTypes.BUTTON, CLOSE_POPUP);
199 buttonPanel.getChildren().add(okButton);
200 okButtonAttributes = okButton.getAttributes();
201 okButtonAttributes.put(Attributes.LABEL, ResourceManagerUtils.getPropertyNotNull(
202 facesContext, "tobago", "tobago.message.confirmation.okay"));
203 okButtonAttributes.put("popupClose", "immediate");
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219 private void encodeMessage(TobagoResponseWriter writer, UIMessages messages, FacesMessage message, String clientId)
220 throws IOException {
221
222 String summary = message.getSummary();
223 String detail = message.getDetail();
224 writer.startElement(HtmlElements.LABEL, null);
225 if (clientId != null) {
226 writer.writeAttribute(HtmlAttributes.FOR, clientId, false);
227 }
228 writer.writeAttribute(HtmlAttributes.TITLE, detail, true);
229 final Markup markup = ComponentUtils.markupOfSeverity(message.getSeverity());
230 writer.writeClassAttribute(Classes.create(messages, "item", markup));
231 boolean writeEmptyText = true;
232 if (summary != null && messages.isShowSummary()) {
233 writer.writeText(summary);
234 writeEmptyText = false;
235 if (detail != null && messages.isShowDetail()) {
236 writer.writeText(" ");
237 }
238 }
239 if (detail != null && messages.isShowDetail()) {
240 writeEmptyText = false;
241 writer.writeText(detail);
242 }
243 if (writeEmptyText) {
244 writer.writeText("");
245 }
246 writer.endElement(HtmlElements.LABEL);
247 writer.startElement(HtmlElements.BR, null);
248 writer.endElement(HtmlElements.BR);
249 }
250
251 @Override
252 public Measure getPreferredHeight(FacesContext facesContext, Configurable component) {
253 Measure measure = super.getPreferredHeight(facesContext, component);
254 UIMessages messages = (UIMessages) component;
255 int count = messages.createMessageList(facesContext).size();
256 return measure.multiply(count);
257 }
258 }