1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.view.facelets.tag.ui;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Map.Entry;
27
28 import javax.faces.component.UIComponent;
29 import javax.faces.component.UIComponentBase;
30 import javax.faces.context.FacesContext;
31 import javax.faces.context.ResponseWriter;
32 import javax.servlet.http.HttpServletResponse;
33
34 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
35 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
36 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
37 import org.apache.myfaces.renderkit.ErrorPageWriter;
38 import org.apache.myfaces.view.facelets.util.FastWriter;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 @JSFComponent(name="ui:debug")
56 @JSFJspProperty(name = "binding", tagExcluded=true)
57 public final class UIDebug extends UIComponentBase
58 {
59 public static final String COMPONENT_TYPE = "facelets.ui.Debug";
60 public static final String COMPONENT_FAMILY = "facelets";
61 public static final String DEFAULT_HOTKEY = "D";
62
63 private static final String KEY = "facelets.ui.DebugOutput";
64
65 private static long nextId = System.currentTimeMillis();
66
67 private String _hotkey = DEFAULT_HOTKEY;
68
69 public UIDebug()
70 {
71 setTransient(true);
72 setRendererType(null);
73 }
74
75 public String getFamily()
76 {
77 return COMPONENT_FAMILY;
78 }
79
80 public List<UIComponent> getChildren()
81 {
82 return new ArrayList<UIComponent>()
83 {
84 public boolean add(UIComponent o)
85 {
86 throw new IllegalStateException("<ui:debug> does not support children");
87 }
88
89 public void add(int index, UIComponent o)
90 {
91 throw new IllegalStateException("<ui:debug> does not support children");
92 }
93 };
94 }
95
96 public void encodeBegin(FacesContext faces) throws IOException
97 {
98 boolean partialRequest = faces.getPartialViewContext().isPartialRequest();
99
100 String actionId = faces.getApplication().getViewHandler()
101 .getActionURL(faces, faces.getViewRoot().getViewId());
102
103 StringBuilder sb = new StringBuilder(512);
104 sb.append("<script language=\"javascript\" type=\"text/javascript\">\n");
105 if (!partialRequest)
106 {
107 sb.append("//<![CDATA[\n");
108 }
109 sb.append("function faceletsDebug(URL) { day = new Date(); id = day.getTime(); eval(\"page\" + id + \" "
110 + "= window.open(URL, '\" + id + \"', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,"
111 + "resizable=1,width=800,height=600,left = 240,top = 212');\"); };");
112 sb.append("var faceletsOrigKeyup = document.onkeyup; document.onkeyup = function(e) { "
113 + "if (window.event) e = window.event; if (String.fromCharCode(e.keyCode) == '"
114 + this.getHotkey() + "' & e.shiftKey & e.ctrlKey) faceletsDebug('");
115 sb.append(actionId);
116
117 int index = actionId.indexOf('?');
118 if (index != -1)
119 {
120 sb.append('&');
121 }
122 else
123 {
124 sb.append('?');
125 }
126 sb.append(KEY);
127 sb.append('=');
128 sb.append(writeDebugOutput(faces));
129 sb.append("'); else if (faceletsOrigKeyup) faceletsOrigKeyup(e); };\n");
130 if (!partialRequest)
131 {
132 sb.append("//]]>\n");
133 }
134 sb.append("</script>\n");
135
136 ResponseWriter writer = faces.getResponseWriter();
137 writer.write(sb.toString());
138 }
139
140 @SuppressWarnings("unchecked")
141 private static String writeDebugOutput(FacesContext faces) throws IOException
142 {
143 FastWriter fw = new FastWriter();
144 ErrorPageWriter.debugHtml(fw, faces);
145
146 Map<String, Object> session = faces.getExternalContext().getSessionMap();
147 Map<String, String> debugs = (Map<String, String>) session.get(KEY);
148 if (debugs == null)
149 {
150 debugs = new LinkedHashMap<String, String>()
151 {
152 protected boolean removeEldestEntry(Entry<String, String> eldest)
153 {
154 return (this.size() > 5);
155 }
156 };
157
158 session.put(KEY, debugs);
159 }
160
161 String id = String.valueOf(nextId++);
162
163 debugs.put(id, fw.toString());
164
165 return id;
166 }
167
168 @SuppressWarnings("unchecked")
169 private static String fetchDebugOutput(FacesContext faces, String id)
170 {
171 Map<String, Object> session = faces.getExternalContext().getSessionMap();
172 Map<String, String> debugs = (Map<String, String>) session.get(KEY);
173 if (debugs != null)
174 {
175 return debugs.get(id);
176 }
177
178 return null;
179 }
180
181 public static boolean debugRequest(FacesContext faces)
182 {
183 String id = (String) faces.getExternalContext().getRequestParameterMap().get(KEY);
184 if (id != null)
185 {
186 Object resp = faces.getExternalContext().getResponse();
187 if (!faces.getResponseComplete() && resp instanceof HttpServletResponse)
188 {
189 try
190 {
191 HttpServletResponse httpResp = (HttpServletResponse) resp;
192 String page = fetchDebugOutput(faces, id);
193 if (page != null)
194 {
195 httpResp.setContentType("text/html");
196 httpResp.getWriter().write(page);
197 }
198 else
199 {
200 httpResp.setContentType("text/plain");
201 httpResp.getWriter().write("No Debug Output Available");
202 }
203 httpResp.flushBuffer();
204 faces.responseComplete();
205 }
206 catch (IOException e)
207 {
208 return false;
209 }
210
211 return true;
212 }
213 }
214
215 return false;
216 }
217
218 @JSFProperty(tagExcluded=true)
219 @Override
220 public String getId()
221 {
222
223 return super.getId();
224 }
225
226
227
228
229
230
231
232
233 @JSFProperty
234 public String getHotkey()
235 {
236 return _hotkey;
237 }
238
239 public void setHotkey(String hotkey)
240 {
241 _hotkey = (hotkey != null) ? hotkey.toUpperCase() : "";
242 }
243 }