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