001: /*
002: * Copyright 2005 Joe Walker
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.directwebremoting.servlet;
017:
018: import java.io.IOException;
019: import java.io.PrintWriter;
020: import java.lang.reflect.Field;
021: import java.lang.reflect.Modifier;
022: import java.util.Collection;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.Map;
026: import java.util.SortedMap;
027: import java.util.TreeMap;
028:
029: import javax.servlet.http.HttpServletRequest;
030: import javax.servlet.http.HttpServletResponse;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034: import org.directwebremoting.Container;
035: import org.directwebremoting.WebContext;
036: import org.directwebremoting.WebContextFactory;
037: import org.directwebremoting.extend.Handler;
038: import org.directwebremoting.util.LocalUtil;
039: import org.directwebremoting.util.Messages;
040: import org.directwebremoting.util.MimeConstants;
041:
042: /**
043: * A monitoring system so we can see what is going on inside DWR
044: * @author Joe Walker [joe at getahead dot ltd dot uk]
045: */
046: public class MonitorHandler implements Handler {
047: /* (non-Javadoc)
048: * @see org.directwebremoting.extend.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
049: */
050: public void handle(HttpServletRequest request,
051: HttpServletResponse response) throws IOException {
052: if (!debug) {
053: log
054: .warn("Failed attempt to access test pages outside of debug mode. Set the debug init-parameter to true to enable.");
055: throw new SecurityException(
056: Messages
057: .getString("DefaultDebugPageGenerator.AccessDenied"));
058: }
059:
060: response.setContentType(MimeConstants.MIME_HTML);
061: PrintWriter out = response.getWriter();
062: out
063: .print("<html><head><title>DWR - System Monitor</title></head><body>");
064:
065: WebContext webContext = WebContextFactory.get();
066:
067: out.print("<h1>DWR - System Monitor</h1>");
068: out.print("<h2>Global Settings:</h2>");
069:
070: String contextPath = webContext.getContextPath();
071: out.print("<p>ContextPath: " + contextPath + "</p>");
072: out.print("<p>Current Page: " + webContext.getCurrentPage()
073: + "</p>");
074:
075: //ScriptSession scriptSession = webContext.getScriptSession();
076:
077: Container container = webContext.getContainer();
078: SortedMap<String, Object> beans = new TreeMap<String, Object>();
079: SortedMap<String, String> settings = new TreeMap<String, String>();
080: SortedMap<String, String> urls = new TreeMap<String, String>();
081: for (String name : container.getBeanNames()) {
082: Object bean = container.getBean(name);
083: if (name.startsWith("url:")) {
084: urls.put(name.substring(4), bean.getClass().getName());
085: } else if (bean instanceof String) {
086: settings.put(name, bean.toString());
087: } else {
088: beans.put(name, bean);
089: }
090: }
091:
092: // Add all the beans to an ID map for <a name=ID>
093: IdManager ids = new IdManager();
094:
095: // Remove the URL re-writers from the Settings map
096: for (Map.Entry<String, String> urlEntry : urls.entrySet()) {
097: for (Iterator<Map.Entry<String, String>> it = settings
098: .entrySet().iterator(); it.hasNext();) {
099: Map.Entry<String, String> settingEntry = it.next();
100: if (urlEntry.getKey().equals(settingEntry.getValue())) {
101: it.remove();
102: urls.put(urlEntry.getKey(), urlEntry.getValue()
103: + " (" + settingEntry.getKey() + ")");
104: }
105: }
106: }
107:
108: out.print("<h2>Beans:</h2>");
109: for (Map.Entry<String, Object> entry : beans.entrySet()) {
110: String name = entry.getKey();
111: Object object = entry.getValue();
112:
113: digWhatever(out, ids, name, object);
114: }
115:
116: out.print("<h2>Settings:</h2>");
117: for (Map.Entry<String, String> entry : settings.entrySet()) {
118: out.print("<p>" + entry.getKey() + ": \""
119: + entry.getValue() + "\"</p>");
120: }
121:
122: out.print("<h2>URLs:</h2>");
123: String prefix = contextPath
124: + webContext.getHttpServletRequest().getServletPath();
125: for (Map.Entry<String, String> entry : urls.entrySet()) {
126: out.print("<p><a href='" + prefix + entry.getKey() + "'>"
127: + entry.getKey() + "</a>: " + entry.getValue()
128: + "</p>");
129: }
130:
131: webContext.getContextPath();
132: out.print("</body></html>");
133: }
134:
135: /**
136: * @param out
137: * @param ids
138: * @param name
139: * @param object
140: */
141: private void digWhatever(PrintWriter out, IdManager ids,
142: String name, Object object) {
143: if (object == null || object instanceof Number
144: || object instanceof Boolean) {
145: digSimple(out, name, object);
146: } else if (object instanceof Collection<?>) {
147: Collection<?> collection = (Collection<?>) object;
148: boolean simple = true;
149: for (Object child : collection) {
150: if (!(child instanceof Number)
151: && !(child instanceof Boolean)
152: && !(child instanceof String)) {
153: simple = false;
154: }
155: }
156: if (simple) {
157: digSimple(out, name, object);
158: } else {
159: digCollection(out, ids, name, collection);
160: }
161: } else if (object instanceof Map<?, ?>) {
162: digMap(out, ids, name, (Map<?, ?>) object);
163: } else if (object.getClass().getName().startsWith("java")
164: || object.getClass().getName().startsWith("com.sun")) {
165: digSimple(out, name, object);
166: } else if (object instanceof String) {
167: digString(out, name, (String) object);
168: } else {
169: digObject(out, ids, name, object);
170: }
171: }
172:
173: /**
174: * @param out
175: * @param name
176: * @param object
177: */
178: private void digSimple(PrintWriter out, String name, Object object) {
179: out.print("<div class='section'>");
180: out.print("<div class='title'>" + name + ": "
181: + object.toString() + "</div>");
182: out.print("</div>");
183: }
184:
185: /**
186: * @param out
187: * @param name
188: * @param object
189: */
190: private void digString(PrintWriter out, String name, String object) {
191: out.print("<div class='section'>");
192: out.print("<div class='title'>" + name + ": \"" + object
193: + "\"</div>");
194: out.print("</div>");
195: }
196:
197: /**
198: *
199: */
200: private void digCollection(PrintWriter out, IdManager ids,
201: String name, Collection<?> collection) {
202: out.print("<div class='section'>");
203: String id = ids.getIfExists(collection);
204: if (id != null) {
205: out.print("<div class='title'>" + name + ": <a href='#id"
206: + id + "'>Map</a></div>");
207: } else {
208: id = ids.allocate(collection);
209:
210: out.print("<div class='title'><a name='id" + id + "'>"
211: + name + "</a>: Map</div>");
212: out.print("<ul>");
213: int i = 0;
214: for (Object entry : collection) {
215: digWhatever(out, ids, "" + i, entry.toString());
216: i++;
217: }
218: out.print("</ul>");
219: }
220: }
221:
222: /**
223: *
224: */
225: private void digMap(PrintWriter out, IdManager ids, String name,
226: Map<?, ?> map) {
227: out.print("<div class='section'>");
228: String id = ids.getIfExists(map);
229: if (id != null) {
230: out.print("<div class='title'>" + name + ": <a href='#id"
231: + id + "'>Map</a></div>");
232: } else {
233: id = ids.allocate(map);
234:
235: out.print("<div class='title'><a name='id" + id + "'>"
236: + name + "</a>: Map</div>");
237: out.print("<ul>");
238: for (Map.Entry<?, ?> entry : map.entrySet()) {
239: Object value = entry.getValue();
240: digWhatever(out, ids, entry.getValue().toString(),
241: value);
242: }
243: out.print("</ul>");
244: }
245: }
246:
247: /**
248: *
249: */
250: private void digException(PrintWriter out, String name, Throwable ex) {
251: out.print("<div class='section'>");
252: out.print("<div class='title'>" + name + ": "
253: + ex.getClass().getSimpleName() + "(" + ex.getMessage()
254: + ")</div>");
255: out.print("</div>");
256: }
257:
258: /**
259: *
260: */
261: private void digObject(PrintWriter out, IdManager ids, String name,
262: Object object) {
263: Class<? extends Object> type = object.getClass();
264: if (object instanceof Log) {
265: return;
266: }
267:
268: out.print("<div class='section'>");
269: String id = ids.getIfExists(object);
270: if (id != null) {
271: out.print("<div class='title'>" + name + ": <a href='#id"
272: + id + "'>" + type.getSimpleName() + "</a></div>");
273: } else {
274: id = ids.allocate(object);
275:
276: out.print("<div class='title'><a name='id" + id + "'>"
277: + name + "</a>: " + type.getName() + "</div>");
278: out.print("<ul>");
279: for (Field field : LocalUtil.getAllFields(type)) {
280: try {
281: if (Modifier.isStatic(field.getModifiers())) {
282: continue;
283: }
284:
285: field.setAccessible(true);
286: Object value = field.get(object);
287: digWhatever(out, ids, field.getName(), value);
288: } catch (Exception ex) {
289: digException(out, field.getName(), ex);
290: }
291: }
292: out.print("</ul>");
293: }
294: }
295:
296: protected static class IdManager {
297: /**
298: *
299: */
300: public String getIfExists(Object object) {
301: return allocated.get(object);
302: }
303:
304: protected String allocate(Object object) {
305: if (allocated.containsKey(object)) {
306: throw new IllegalStateException("object already exists");
307: }
308:
309: String id = "id" + nextId;
310: nextId++;
311: allocated.put(object, id);
312:
313: return id;
314: }
315:
316: private int nextId;
317:
318: private Map<Object, String> allocated = new HashMap<Object, String>();
319: }
320:
321: /**
322: * Set the debug status
323: * @param debug The new debug setting
324: */
325: public void setDebug(boolean debug) {
326: this .debug = debug;
327: }
328:
329: /**
330: * Are we in debug mode?
331: */
332: protected boolean debug = false;
333:
334: /**
335: * The log stream
336: */
337: private static final Log log = LogFactory
338: .getLog(MonitorHandler.class);
339: }
|