View Javadoc

1   package org.jmux.app.component;
2   
3   import org.jmux.app.App;
4   import org.jmux.app.component.config.Config;
5   
6   import javax.servlet.ServletException;
7   import javax.servlet.http.HttpServlet;
8   import javax.servlet.http.HttpServletRequest;
9   import javax.servlet.http.HttpServletResponse;
10  import java.io.IOException;
11  import java.io.PrintWriter;
12  import java.lang.reflect.Field;
13  import java.lang.reflect.Modifier;
14  import java.util.Date;
15  import java.util.HashMap;
16  import java.util.IdentityHashMap;
17  import java.util.Map;
18  
19  /******************************************************************************
20   jmux - Java Modules Using XML
21   Copyright © 2006 jmux.org
22  
23   This library is free software; you can redistribute it and/or
24   modify it under the terms of the GNU Lesser General Public
25   License as published by the Free Software Foundation; either
26   version 2.1 of the License, or (at your option) any later version.
27  
28   This library is distributed in the hope that it will be useful,
29   but WITHOUT ANY WARRANTY; without even the implied warranty of
30   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
31   Lesser General Public License for more details.
32  
33   You should have received a copy of the GNU Lesser General Public
34   License along with this library; if not, write to the Free Software
35   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
36   *****************************************************************************/
37  
38  /***
39   * @author donaldw
40   */
41  public class Inspector extends AbstractComponent {
42  
43      @Wire
44      private JettyControl jettyControl;
45  
46      @Wire
47      private ControlManager controlManager;
48  
49      private static App app;
50  
51      public void configure(Config config, App app) {
52          super.configure(config, app);
53  
54          jettyControl.addServlet(Servlet.class, "/Inspect");
55          Inspector.app = app;
56      }
57  
58      public static class Servlet extends HttpServlet {
59          private Map<String, Object> stringToObject = new HashMap<String, Object>();
60          private Map<Object, String> objectToString = new IdentityHashMap<Object, String>();
61  
62          private long nextObjectId;
63  
64  
65          protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
66                  throws ServletException, IOException {
67  
68              String objectId = httpServletRequest.getParameter("object");
69  
70              PrintWriter writer = httpServletResponse.getWriter();
71              try {
72                  Object object = getObject(objectId);
73                  dumpObject(writer, object);
74              } catch (Exception e) {
75                  throw new ServletException("Exception whilst dumping object: ", e);
76              }
77          }
78  
79          private void dumpObject(PrintWriter writer, Object object) throws Exception {
80              writer.println("<html><head></head><body>");
81              Class clazz = object.getClass();
82              writer.printf("<h1>%s</h1>", clazz.getName());
83              writer.printf("<h2>Fields</h2>");
84  
85              Class fieldLoopclazz = object.getClass();
86  
87              while (fieldLoopclazz != null) {
88                  writer.println("<h3>" + fieldLoopclazz.getName() + "</h3>");
89                  for (Field field : fieldLoopclazz.getDeclaredFields()) {
90                      field.setAccessible(true);
91                      Object fieldValue = field.get(object);
92                      if (field.getName().equals("objectToString")) {
93                          continue;
94                      }
95                      writer.print("<font color='Grey'> "
96                              + Modifier.toString(field.getModifiers())
97                              + "</font><font color='DarkBlue'> "
98                              + field.getType().getName()
99                              + "</font> "
100                             + field.getName() + ": ");
101                     dumpLinkedObject(field.getType(), writer, fieldValue);
102                     writer.println("<br/>");
103                 }
104 
105                 fieldLoopclazz = fieldLoopclazz.getSuperclass();
106             }
107             writer.println("</body></html>");
108         }
109 
110 
111         private void dumpLinkedObject(Class clazz, PrintWriter writer, Object object) {
112             if (object == null) {
113                 writer.print("null");
114                 return;
115             }
116             if (clazz.isPrimitive() || clazz.equals(String.class) || clazz.equals(Date.class)) {
117                 writer.println(object.toString());
118             } else if (clazz.isAssignableFrom(Map.class)) {
119                 writer.println("<table border='1'>");
120                 Map map = (Map) object;
121                 for (Object o : map.entrySet()) {
122                     Map.Entry entry = (Map.Entry) o;
123                     Object key = entry.getKey();
124                     Object value = entry.getValue();
125                     writer.print("<tr><td>");
126                     if (key != null) {
127                         dumpLinkedObject(key.getClass(), writer, key);
128                     } else {
129                         writer.print("null");
130                     }
131 
132                     writer.print("</td><td>");
133                     if (value != null) {
134                         dumpLinkedObject(value.getClass(), writer, value);
135                     } else {
136                         writer.print("null");
137                     }
138                     writer.println("</td>");
139                 }
140                 writer.println("</table>");
141             } else if (clazz.isArray()) {
142                 writer.println("<table border='1'>");
143                 Object[] objectArray = (Object[]) object;
144                 for (Object o : objectArray) {
145                     writer.print("<td>");
146                     if (o == null) {
147                         writer.print("null");
148                     } else {
149                         dumpLinkedObject(o.getClass(), writer, o);
150                     }
151                     writer.print("</td>");
152                 }
153                 writer.println("</table>");
154             } else {
155                 String objectId = putObject(object);
156                 writer.print("<a href='/Inspect?object=" + objectId + "'>" + object + "</a>");
157             }
158         }
159 
160         public synchronized Object getObject(String objectId) {
161             if (objectId == null) {
162                 return Inspector.app;
163             } else {
164                 return stringToObject.get(objectId);
165             }
166         }
167 
168         private synchronized String putObject(Object object) {
169             String key = objectToString.get(object);
170             if (key == null) {
171                 key = "obj" + nextObjectId++;
172                 stringToObject.put(key, object);
173                 objectToString.put(object, key);
174             }
175 
176             return key;
177         }
178     }
179 
180 
181 }