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 @Override
76 public String getFamily()
77 {
78 return COMPONENT_FAMILY;
79 }
80
81 @Override
82 public List<UIComponent> getChildren()
83 {
84 return new ArrayList<UIComponent>()
85 {
86 public boolean add(UIComponent o)
87 {
88 throw new IllegalStateException("<ui:debug> does not support children");
89 }
90
91 public void add(int index, UIComponent o)
92 {
93 throw new IllegalStateException("<ui:debug> does not support children");
94 }
95 };
96 }
97
98 public void encodeBegin(FacesContext faces) throws IOException
99 {
100 boolean partialRequest = faces.getPartialViewContext().isPartialRequest();
101
102 String actionId = faces.getApplication().getViewHandler()
103 .getActionURL(faces, faces.getViewRoot().getViewId());
104
105 StringBuilder sb = new StringBuilder(512);
106 sb.append("<script language=\"javascript\" type=\"text/javascript\">\n");
107 if (!partialRequest)
108 {
109 sb.append("//<![CDATA[\n");
110 }
111 sb.append("function faceletsDebug(URL) { day = new Date(); id = day.getTime(); eval(\"page\" + id + \" "
112 + "= window.open(URL, '\" + id + \"', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,"
113 + "resizable=1,width=800,height=600,left = 240,top = 212');\"); };");
114 sb.append("var faceletsOrigKeyup = document.onkeyup; document.onkeyup = function(e) { "
115 + "if (window.event) e = window.event; if (String.fromCharCode(e.keyCode) == '"
116 + this.getHotkey() + "' & e.shiftKey & e.ctrlKey) faceletsDebug('");
117 sb.append(actionId);
118
119 int index = actionId.indexOf('?');
120 if (index != -1)
121 {
122 sb.append('&');
123 }
124 else
125 {
126 sb.append('?');
127 }
128 sb.append(KEY);
129 sb.append('=');
130 sb.append(writeDebugOutput(faces));
131 sb.append("'); else if (faceletsOrigKeyup) faceletsOrigKeyup(e); };\n");
132 if (!partialRequest)
133 {
134 sb.append("//]]>\n");
135 }
136 sb.append("</script>\n");
137
138 ResponseWriter writer = faces.getResponseWriter();
139 writer.write(sb.toString());
140 }
141
142 @SuppressWarnings("unchecked")
143 private static String writeDebugOutput(FacesContext faces) throws IOException
144 {
145 FastWriter fw = new FastWriter();
146 ErrorPageWriter.debugHtml(fw, faces);
147
148 Map<String, Object> session = faces.getExternalContext().getSessionMap();
149 Map<String, String> debugs = (Map<String, String>) session.get(KEY);
150 if (debugs == null)
151 {
152 debugs = new LinkedHashMap<String, String>()
153 {
154 protected boolean removeEldestEntry(Entry<String, String> eldest)
155 {
156 return (this.size() > 5);
157 }
158 };
159
160 session.put(KEY, debugs);
161 }
162
163 String id = String.valueOf(nextId++);
164
165 debugs.put(id, fw.toString());
166
167 return id;
168 }
169
170 @SuppressWarnings("unchecked")
171 private static String fetchDebugOutput(FacesContext faces, String id)
172 {
173 Map<String, Object> session = faces.getExternalContext().getSessionMap();
174 Map<String, String> debugs = (Map<String, String>) session.get(KEY);
175 if (debugs != null)
176 {
177 return debugs.get(id);
178 }
179
180 return null;
181 }
182
183 public static boolean debugRequest(FacesContext faces)
184 {
185 String id = (String) faces.getExternalContext().getRequestParameterMap().get(KEY);
186 if (id != null)
187 {
188 Object resp = faces.getExternalContext().getResponse();
189 if (!faces.getResponseComplete() && resp instanceof HttpServletResponse)
190 {
191 try
192 {
193 HttpServletResponse httpResp = (HttpServletResponse) resp;
194 String page = fetchDebugOutput(faces, id);
195 if (page != null)
196 {
197 httpResp.setContentType("text/html");
198 httpResp.getWriter().write(page);
199 }
200 else
201 {
202 httpResp.setContentType("text/plain");
203 httpResp.getWriter().write("No Debug Output Available");
204 }
205 httpResp.flushBuffer();
206 faces.responseComplete();
207 }
208 catch (IOException e)
209 {
210 return false;
211 }
212
213 return true;
214 }
215 }
216
217 return false;
218 }
219
220 @JSFProperty(tagExcluded=true)
221 @Override
222 public String getId()
223 {
224
225 return super.getId();
226 }
227
228
229
230
231
232
233
234
235 @JSFProperty
236 public String getHotkey()
237 {
238 return _hotkey;
239 }
240
241 public void setHotkey(String hotkey)
242 {
243 _hotkey = (hotkey != null) ? hotkey.toUpperCase() : "";
244 }
245 }