1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.util;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24 import javax.faces.FacesException;
25 import javax.faces.component.*;
26 import javax.faces.context.FacesContext;
27 import javax.faces.el.MethodBinding;
28 import javax.faces.el.ValueBinding;
29 import javax.faces.event.FacesListener;
30 import javax.faces.validator.Validator;
31 import java.beans.BeanInfo;
32 import java.beans.IntrospectionException;
33 import java.beans.Introspector;
34 import java.beans.PropertyDescriptor;
35 import java.io.ByteArrayOutputStream;
36 import java.io.IOException;
37 import java.io.PrintStream;
38 import java.util.HashSet;
39 import java.util.Iterator;
40 import java.util.Map;
41
42
43
44
45
46
47
48
49 public class DebugUtils
50 {
51 private static final Log log = LogFactory.getLog(DebugUtils.class);
52
53
54 private static final HashSet IGNORE_ATTRIBUTES;
55 static
56 {
57 IGNORE_ATTRIBUTES = new HashSet();
58 IGNORE_ATTRIBUTES.add("attributes");
59 IGNORE_ATTRIBUTES.add("children");
60 IGNORE_ATTRIBUTES.add("childCount");
61 IGNORE_ATTRIBUTES.add("class");
62 IGNORE_ATTRIBUTES.add("facets");
63 IGNORE_ATTRIBUTES.add("facetsAndChildren");
64 IGNORE_ATTRIBUTES.add("parent");
65 IGNORE_ATTRIBUTES.add("actionListeners");
66 IGNORE_ATTRIBUTES.add("valueChangeListeners");
67 IGNORE_ATTRIBUTES.add("validators");
68 IGNORE_ATTRIBUTES.add("rowData");
69 IGNORE_ATTRIBUTES.add("javax.faces.webapp.COMPONENT_IDS");
70 IGNORE_ATTRIBUTES.add("javax.faces.webapp.FACET_NAMES");
71 IGNORE_ATTRIBUTES.add("javax.faces.webapp.CURRENT_VIEW_ROOT");
72 }
73
74 private static final String JSF_COMPONENT_PACKAGE = "javax.faces.component.";
75 private static final String MYFACES_COMPONENT_PACKAGE = "org.apache.myfaces.component.";
76
77
78 private DebugUtils()
79 {
80
81 }
82
83 public static void assertError(boolean condition, Log log_, String msg)
84 throws FacesException
85 {
86 if (!condition)
87 {
88 log_.error(msg);
89 throw new FacesException(msg);
90 }
91 }
92
93 public static void assertFatal(boolean condition, Log log_, String msg)
94 throws FacesException
95 {
96 if (!condition)
97 {
98 log_.fatal(msg);
99 throw new FacesException(msg);
100 }
101 }
102
103
104
105 public static void traceView(String additionalMsg)
106 {
107 if (log.isTraceEnabled())
108 {
109 FacesContext facesContext = FacesContext.getCurrentInstance();
110 if (facesContext == null)
111 {
112 log.error("Cannot not print view to console (no FacesContext).");
113 return;
114 }
115 UIViewRoot viewRoot = facesContext.getViewRoot();
116 if (viewRoot == null)
117 {
118 log.error("Cannot not print view to console (no ViewRoot in FacesContext).");
119 return;
120 }
121
122 traceView(additionalMsg, viewRoot);
123 }
124 }
125
126
127
128
129
130
131
132
133 private static void traceView(String additionalMsg, UIViewRoot viewRoot)
134 {
135 ByteArrayOutputStream baos = new ByteArrayOutputStream();
136 PrintStream ps = new PrintStream(baos);
137 if (additionalMsg != null)
138 {
139 ps.println(additionalMsg);
140 }
141 ps.println("========================================");
142 printView(viewRoot, ps);
143 ps.println("========================================");
144 ps.close();
145 log.trace(baos.toString());
146 }
147
148 public static void printView(UIViewRoot uiViewRoot, PrintStream stream)
149 {
150 printComponent(uiViewRoot, stream, 0, true, null);
151 }
152
153 public static void printComponent(UIComponent comp, PrintStream stream)
154 {
155 printComponent(comp, stream, 0, false, null);
156 }
157
158 private static void printComponent(UIComponent comp,
159 PrintStream stream,
160 int indent,
161 boolean withChildrenAndFacets,
162 String facetName)
163 {
164 printIndent(stream, indent);
165 stream.print('<');
166
167 String compType = comp.getClass().getName();
168 if (compType.startsWith(JSF_COMPONENT_PACKAGE))
169 {
170 compType = compType.substring(JSF_COMPONENT_PACKAGE.length());
171 }
172 else if (compType.startsWith(MYFACES_COMPONENT_PACKAGE))
173 {
174 compType = compType.substring(MYFACES_COMPONENT_PACKAGE.length());
175 }
176 stream.print(compType);
177
178 printAttribute(stream, "id", comp.getId());
179
180 if (facetName != null)
181 {
182 printAttribute(stream, "facetName", facetName);
183 }
184
185 for (Iterator it = comp.getAttributes().entrySet().iterator(); it.hasNext(); )
186 {
187 Map.Entry entry = (Map.Entry)it.next();
188 if (!"id".equals(entry.getKey()))
189 {
190 printAttribute(stream, (String)entry.getKey(), entry.getValue());
191 }
192 }
193
194
195
196
197 BeanInfo beanInfo;
198 try
199 {
200 beanInfo = Introspector.getBeanInfo(comp.getClass());
201 }
202 catch (IntrospectionException e)
203 {
204 throw new RuntimeException(e);
205 }
206
207 PropertyDescriptor propDescriptors[] = beanInfo.getPropertyDescriptors();
208 for (int i = 0; i < propDescriptors.length; i++)
209 {
210 if (propDescriptors[i].getReadMethod() != null)
211 {
212 String name = propDescriptors[i].getName();
213 if (!"id".equals(name))
214 {
215 ValueBinding vb = comp.getValueBinding(name);
216 if (vb != null)
217 {
218 printAttribute(stream, name, vb.getExpressionString());
219 }
220 else
221 {
222 if (name.equals("value") && comp instanceof ValueHolder)
223 {
224
225 }
226 else if (!IGNORE_ATTRIBUTES.contains(name))
227 {
228 try
229 {
230 Object value = comp.getAttributes().get(name);
231 printAttribute(stream, name, value);
232 }
233 catch (Exception e)
234 {
235 log.error(e);
236 printAttribute(stream, name, null);
237 }
238 }
239 }
240 }
241 }
242 }
243
244 boolean mustClose = true;
245 boolean nestedObjects = false;
246
247 if (comp instanceof UICommand)
248 {
249 FacesListener[] listeners = ((UICommand)comp).getActionListeners();
250 if (listeners != null && listeners.length > 0)
251 {
252 nestedObjects = true;
253 stream.println('>'); mustClose = false;
254 for (int i = 0; i < listeners.length; i++)
255 {
256 FacesListener listener = listeners[i];
257 printIndent(stream, indent + 1);
258 stream.print('<');
259 stream.print(listener.getClass().getName());
260 stream.println("/>");
261 }
262 }
263 }
264
265 if (comp instanceof UIInput)
266 {
267 FacesListener[] listeners = ((UIInput)comp).getValueChangeListeners();
268 if (listeners != null && listeners.length > 0)
269 {
270 nestedObjects = true;
271 stream.println('>'); mustClose = false;
272 for (int i = 0; i < listeners.length; i++)
273 {
274 FacesListener listener = listeners[i];
275 printIndent(stream, indent + 1);
276 stream.print('<');
277 stream.print(listener.getClass().getName());
278 stream.println("/>");
279 }
280 }
281
282 Validator[] validators = ((UIInput)comp).getValidators();
283 if (validators != null && validators.length > 0)
284 {
285 nestedObjects = true;
286 stream.println('>'); mustClose = false;
287 for (int i = 0; i < validators.length; i++)
288 {
289 Validator validator = validators[i];
290 printIndent(stream, indent + 1);
291 stream.print('<');
292 stream.print(validator.getClass().getName());
293 stream.println("/>");
294 }
295 }
296 }
297
298 if (withChildrenAndFacets)
299 {
300 int childCount = comp.getChildCount();
301 Map facetsMap = comp.getFacets();
302 if (childCount > 0 || !facetsMap.isEmpty())
303 {
304 nestedObjects = true;
305 if (mustClose)
306 {
307 stream.println('>');
308 mustClose = false;
309 }
310
311 if (childCount > 0)
312 {
313 for (Iterator it = comp.getChildren().iterator(); it.hasNext(); )
314 {
315 UIComponent child = (UIComponent)it.next();
316 printComponent(child, stream, indent + 1, true, null);
317 }
318 }
319
320 for (Iterator it = facetsMap.entrySet().iterator(); it.hasNext(); )
321 {
322 Map.Entry entry = (Map.Entry)it.next();
323 printComponent((UIComponent)entry.getValue(),
324 stream, indent + 1, true,
325 (String)entry.getKey());
326 }
327 }
328 }
329
330 if (nestedObjects)
331 {
332 if (mustClose)
333 {
334 stream.println("/>");
335 }
336 else
337 {
338 printIndent(stream, indent);
339 stream.print("</");
340 stream.print(compType);
341 stream.println('>');
342 }
343 }
344 else
345 {
346 stream.println("/>");
347 }
348 }
349
350 private static void printAttribute(PrintStream stream,
351 String name,
352 Object value)
353 {
354 if (IGNORE_ATTRIBUTES.contains(name)) return;
355 if (name.startsWith("javax.faces.webapp.UIComponentTag."))
356 {
357 name = name.substring("javax.faces.webapp.UIComponentTag.".length());
358 }
359 stream.print(' ');
360 stream.print(name.toString());
361 stream.print("=\"");
362 if (value != null)
363 {
364 if (value instanceof UIComponent)
365 {
366 stream.print("[id:");
367 stream.print(((UIComponent)value).getId());
368 stream.print(']');
369 }
370 else if (value instanceof MethodBinding)
371 {
372 stream.print(((MethodBinding)value).getExpressionString());
373 }
374 else
375 {
376 stream.print(value.toString());
377 }
378 }
379 else
380 {
381 stream.print("NULL");
382 }
383 stream.print('"');
384 }
385
386
387 private static void printIndent(PrintStream stream, int depth)
388 {
389 for (int i = 0; i < depth; i++)
390 {
391 stream.print(" ");
392 }
393 }
394
395 public static String componentAsString(UIComponent comp)
396 {
397 try
398 {
399 ByteArrayOutputStream baos = new ByteArrayOutputStream();
400 printComponent(comp, new PrintStream(baos));
401 baos.close();
402 return baos.toString();
403 }
404 catch (IOException e)
405 {
406 throw new RuntimeException(e);
407 }
408 }
409 }