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 + \" "
111 + "= window.open(URL, '\" + id + \"', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,"
112 + "resizable=1,width=800,height=600,left = 240,top = 212');\"); };");
113 sb.append("var faceletsOrigKeyup = document.onkeyup; document.onkeyup = function(e) { "
114 + "if (window.event) e = window.event; if (String.fromCharCode(e.keyCode) == '"
115 + this.getHotkey() + "' & e.shiftKey & e.ctrlKey) faceletsDebug('");
116 sb.append(actionId);
117
118 int index = actionId.indexOf ("?");
119 if (index != -1)
120 {
121 sb.append("&");
122 }
123 else
124 {
125 sb.append('?');
126 }
127 sb.append(KEY);
128 sb.append('=');
129 sb.append(writeDebugOutput(faces));
130 sb.append("'); else if (faceletsOrigKeyup) faceletsOrigKeyup(e); };\n");
131 if (!partialRequest)
132 {
133 sb.append("//]]>\n");
134 }
135 sb.append("</script>\n");
136
137 ResponseWriter writer = faces.getResponseWriter();
138 writer.write(sb.toString());
139 }
140
141 @SuppressWarnings("unchecked")
142 private static String writeDebugOutput(FacesContext faces) throws IOException
143 {
144 FastWriter fw = new FastWriter();
145 ErrorPageWriter.debugHtml(fw, faces);
146
147 Map<String, Object> session = faces.getExternalContext().getSessionMap();
148 Map<String, String> debugs = (Map<String, String>) session.get(KEY);
149 if (debugs == null)
150 {
151 debugs = new LinkedHashMap<String, String>()
152 {
153 protected boolean removeEldestEntry(Entry<String, String> eldest)
154 {
155 return (this.size() > 5);
156 }
157 };
158
159 session.put(KEY, debugs);
160 }
161
162 String id = String.valueOf(nextId++);
163
164 debugs.put(id, fw.toString());
165
166 return id;
167 }
168
169 @SuppressWarnings("unchecked")
170 private static String fetchDebugOutput(FacesContext faces, String id)
171 {
172 Map<String, Object> session = faces.getExternalContext().getSessionMap();
173 Map<String, String> debugs = (Map<String, String>) session.get(KEY);
174 if (debugs != null)
175 {
176 return debugs.get(id);
177 }
178
179 return null;
180 }
181
182 public static boolean debugRequest(FacesContext faces)
183 {
184 String id = (String) faces.getExternalContext().getRequestParameterMap().get(KEY);
185 if (id != null)
186 {
187 Object resp = faces.getExternalContext().getResponse();
188 if (!faces.getResponseComplete() && resp instanceof HttpServletResponse)
189 {
190 try
191 {
192 HttpServletResponse httpResp = (HttpServletResponse) resp;
193 String page = fetchDebugOutput(faces, id);
194 if (page != null)
195 {
196 httpResp.setContentType("text/html");
197 httpResp.getWriter().write(page);
198 }
199 else
200 {
201 httpResp.setContentType("text/plain");
202 httpResp.getWriter().write("No Debug Output Available");
203 }
204 httpResp.flushBuffer();
205 faces.responseComplete();
206 }
207 catch (IOException e)
208 {
209 return false;
210 }
211
212 return true;
213 }
214 }
215
216 return false;
217 }
218
219 @JSFProperty(tagExcluded=true)
220 @Override
221 public String getId()
222 {
223
224 return super.getId();
225 }
226
227
228
229
230
231
232
233
234 @JSFProperty
235 public String getHotkey()
236 {
237 return _hotkey;
238 }
239
240 public void setHotkey(String hotkey)
241 {
242 _hotkey = (hotkey != null) ? hotkey.toUpperCase() : "";
243 }
244 }