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