1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jmonit.web;
17
18 import java.io.IOException;
19 import java.lang.reflect.Array;
20 import java.lang.reflect.Method;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.StringTokenizer;
27
28 import javax.servlet.ServletException;
29 import javax.servlet.http.HttpServlet;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.jmonit.Monitoring;
34 import org.jmonit.reporting.JSonRenderer;
35 import org.jmonit.reporting.Renderer;
36 import org.jmonit.spi.PluginManager;
37
38
39
40
41
42
43
44
45
46 public class RestServlet2
47 extends HttpServlet
48 {
49
50
51
52
53
54
55 protected void service( HttpServletRequest request, HttpServletResponse response )
56 throws ServletException, IOException
57 {
58 Object resource = Monitoring.getRepository();
59 try
60 {
61 resource = findResource( split( request.getPathInfo() ), resource );
62 }
63 catch ( Exception e )
64 {
65 response.sendError( HttpServletResponse.SC_NOT_FOUND );
66 }
67 if ( resource == null )
68 {
69 response.setStatus( HttpServletResponse.SC_NO_CONTENT );
70 return;
71 }
72
73 Renderer renderer = getRenderer( MimeUtils.getMimeTypes( request ), response );
74
75
76
77 }
78
79
80
81
82
83
84
85
86
87 protected Renderer getRenderer( List<String> mimeTypes, HttpServletResponse response )
88 throws IOException
89 {
90
91 response.setContentType( "application/json" );
92 return new JSonRenderer( response.getWriter() );
93 }
94
95 protected Object findResource( String path, Object root )
96 throws Exception
97 {
98 return findResource( split( path ), root );
99 }
100
101 private String createMethod( String element, String accessor )
102 {
103 return accessor + Character.toUpperCase( element.charAt( 0 ) ) + element.substring( 1 );
104 }
105
106 private List<String> split( String path )
107 {
108 if ( path.startsWith( "/" ) )
109 {
110 path = path.substring( 1 );
111 }
112 List<String> elements = new ArrayList<String>();
113
114 StringTokenizer tokenizer = new StringTokenizer( path, "/" );
115 while ( tokenizer.hasMoreTokens() )
116 {
117 elements.add( tokenizer.nextToken() );
118 }
119 return elements;
120 }
121
122 private Object findResource( List<String> path, Object root )
123 throws Exception
124 {
125 for ( Iterator<String> iterator = path.iterator(); iterator.hasNext(); )
126 {
127 String element = iterator.next();
128
129 if ( root.getClass().isArray() )
130 {
131 int index = Integer.parseInt( element );
132 root = Array.get( root, index );
133 continue;
134 }
135 if ( root instanceof List )
136 {
137 int index = Integer.parseInt( element );
138 root = ( (List) root ).get( index );
139 continue;
140 }
141 if ( root instanceof Map )
142 {
143 root = ( (Map) root ).get( element );
144 continue;
145 }
146
147 String get = createMethod( element, "get" );
148 try
149 {
150 root = invokeMethod( root, iterator, get );
151 }
152 catch ( NoSuchMethodException e )
153 {
154
155 root = invokeMethod( root, iterator, element );
156 }
157
158 if ( root == null && iterator.hasNext() )
159 {
160 throw new UnsupportedOperationException( "Unknown path" );
161 }
162 }
163 return root;
164 }
165
166 private Object invokeMethod( Object root, Iterator<String> next, String name )
167 throws Exception
168 {
169 Method method = findMethod( root, name );
170 Class[] types = method.getParameterTypes();
171 if ( types.length == 0 )
172 {
173 return method.invoke( root, null );
174 }
175 Object arg = convert( next.next(), types[0] );
176 return method.invoke( root, new Object[] { arg } );
177 }
178
179 private final List<Class[]> parameterTypes = new ArrayList<Class[]>();
180 {
181 parameterTypes.add( new Class[0] );
182 parameterTypes.add( new Class[] { String.class } );
183 parameterTypes.add( new Class[] { String[].class } );
184 parameterTypes.add( new Class[] { Class.class } );
185 parameterTypes.add( new Class[] { Class[].class } );
186 }
187
188 private Method findMethod( Object root, String name )
189 throws Exception
190 {
191 for ( Class[] parameterType : parameterTypes )
192 {
193 try
194 {
195 return root.getClass().getMethod( name, parameterType );
196 }
197 catch ( NoSuchMethodException e )
198 {
199 continue;
200 }
201 }
202 throw new NoSuchMethodException( "no " + name + " method on object " + root.getClass() );
203 }
204
205
206
207
208
209
210 private Object convert( String arg, Class type )
211 {
212 if ( type.equals( String.class ) )
213 {
214 return arg;
215 }
216 if ( type.equals( Class.class ) )
217 {
218 return Monitoring.getRepository().getFeatureManager().getFeature( arg );
219 }
220 if ( type.isArray() )
221 {
222 StringTokenizer tokenizer = new StringTokenizer( arg, "+" );
223 List args = new ArrayList();
224 while ( tokenizer.hasMoreTokens() )
225 {
226 args.add( convert( tokenizer.nextToken(), type.getComponentType() ) );
227 }
228 return args.toArray( (Object[]) Array
229 .newInstance( type.getComponentType(), args.size() ) );
230 }
231 return null;
232 }
233
234 private Collection<Class> parseFeatures( String element )
235 {
236 PluginManager manager = Monitoring.getRepository().getFeatureManager();
237 Collection<Class> features = new ArrayList<Class>();
238 StringTokenizer tokenizer = new StringTokenizer( element, "+" );
239 while ( tokenizer.hasMoreTokens() )
240 {
241 Class feature = manager.getFeature( tokenizer.nextToken() );
242 if ( feature != null )
243 {
244 features.add( feature );
245 }
246 }
247 return features;
248 }
249 }