Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Side by Side Diff: pkg/analysis_server/lib/src/get_handler.dart

Issue 685863003: Make table entries on analysis server's '/status' page clickable. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library get.handler; 5 library get.handler;
6 6
7 import 'dart:convert'; 7 import 'dart:convert';
8 import 'dart:io'; 8 import 'dart:io';
9 9
10 import 'package:analysis_server/src/socket_server.dart'; 10 import 'package:analysis_server/src/socket_server.dart';
11 import 'package:analyzer/file_system/file_system.dart'; 11 import 'package:analyzer/file_system/file_system.dart';
12 import 'package:analyzer/src/generated/source.dart';
12 import 'package:analyzer/src/generated/engine.dart'; 13 import 'package:analyzer/src/generated/engine.dart';
13 import 'package:analyzer/src/generated/java_engine.dart'; 14 import 'package:analyzer/src/generated/java_engine.dart';
15 import 'analysis_server.dart';
14 16
15 /** 17 /**
16 * Instances of the class [GetHandler] handle GET requests. 18 * Instances of the class [GetHandler] handle GET requests.
17 */ 19 */
18 class GetHandler { 20 class GetHandler {
19 /** 21 /**
22 * States displayed in each state table.
23 */
24 static const List<CacheState> STATES = AnalysisContextStatistics_CacheRow.STAT ES;
25
26 /**
20 * The path used to request the status of the analysis server as a whole. 27 * The path used to request the status of the analysis server as a whole.
21 */ 28 */
22 static const String STATUS_PATH = '/status'; 29 static const String STATUS_PATH = '/status';
23 30
24 /** 31 /**
32 * The path used to request the list of source files in a certain cache
33 * state.
34 */
35 static const String CACHE_STATE_PATH = '/cache_state';
36
37 /**
38 * Query parameter used to represent the cache state to search for, when
39 * accessing [CACHE_STATE_PATH].
40 */
41 static const String STATE_QUERY_PARAM = 'state';
42
43 /**
44 * Query parameter used to represent the context to search for, when
45 * accessing [CACHE_STATE_PATH].
46 */
47 static const String CONTEXT_QUERY_PARAM = 'context';
48
49 /**
50 * Query parameter used to represent the descriptor to search for, when
51 * accessing [CACHE_STATE_PATH].
52 */
53 static const String DESCRIPTOR_QUERY_PARAM = 'descriptor';
54
55 /**
25 * The socket server whose status is to be reported on. 56 * The socket server whose status is to be reported on.
26 */ 57 */
27 SocketServer _server; 58 SocketServer _server;
28 59
29 /** 60 /**
30 * Initialize a newly created handler for GET requests. 61 * Initialize a newly created handler for GET requests.
31 */ 62 */
32 GetHandler(SocketServer this._server); 63 GetHandler(SocketServer this._server);
33 64
34 /** 65 /**
35 * Handle a GET request received by the HTTP server. 66 * Handle a GET request received by the HTTP server.
36 */ 67 */
37 void handleGetRequest(HttpRequest request) { 68 void handleGetRequest(HttpRequest request) {
38 String path = request.uri.path; 69 String path = request.uri.path;
39 if (path == STATUS_PATH) { 70 if (path == STATUS_PATH) {
40 _returnServerStatus(request); 71 _returnServerStatus(request);
72 } else if (path == CACHE_STATE_PATH) {
73 _returnCacheState(request);
41 } else { 74 } else {
42 _returnUnknownRequest(request); 75 _returnUnknownRequest(request);
43 } 76 }
44 } 77 }
45 78
46 /** 79 /**
80 * Create a link to [path] with query parameters [params], with inner HTML
81 * [innerHtml].
82 */
83 String _makeLink(String path, Map<String, String> params, String innerHtml) {
84 Uri uri = new Uri(path: path, queryParameters: params);
85 return '<a href="${HTML_ESCAPE.convert(uri.toString())}">$innerHtml</a>';
86 }
87
88 /**
89 * Return a response indicating the set of source files in a certain cache
90 * state.
91 */
92 void _returnCacheState(HttpRequest request) {
93 // Figure out what CacheState is being searched for.
94 String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM];
95 if (stateQueryParam == null) {
96 return _returnFailure(request,
97 'Query parameter $STATE_QUERY_PARAM required');
98 }
99 CacheState stateFilter = null;
100 for (CacheState value in CacheState.values) {
101 if (value.toString() == stateQueryParam) {
102 stateFilter = value;
103 }
104 }
105 if (stateFilter == null) {
106 return _returnFailure(request,
107 'Query parameter $STATE_QUERY_PARAM is invalid');
108 }
109
110 // Figure out which context is being searched for.
111 String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
112 if (contextFilter == null) {
113 return _returnFailure(request,
114 'Query parameter $CONTEXT_QUERY_PARAM required');
115 }
116
117 // Figure out which descriptor is being searched for.
118 String descriptorFilter =
119 request.uri.queryParameters[DESCRIPTOR_QUERY_PARAM];
120 if (descriptorFilter == null) {
121 return _returnFailure(request,
122 'Query parameter $DESCRIPTOR_QUERY_PARAM required');
123 }
124
125 AnalysisServer analysisServer = _server.analysisServer;
126 if (analysisServer == null) {
127 return _returnFailure(request, 'Analysis server not running');
128 }
129 HttpResponse response = request.response;
130 response.statusCode = HttpStatus.OK;
131 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html");
132 response.write('<html>');
133 response.write('<head>');
134 response.write('<title>Dart Analysis Server - Search result</title>');
135 response.write('</head>');
136 response.write('<body>');
137 response.write('<h1>');
138 response.write('Files with state ${HTML_ESCAPE.convert(stateQueryParam)}');
139 response.write(' for descriptor ${HTML_ESCAPE.convert(descriptorFilter)}');
140 response.write(' in context ${HTML_ESCAPE.convert(contextFilter)}');
141 response.write('</h1>');
142 response.write('<ul>');
143 int count = 0;
144 analysisServer.folderMap.forEach((Folder folder,
145 AnalysisContextImpl context) {
146 if (folder.path != contextFilter) {
147 return;
148 }
149 context.visitCacheItems((Source source, SourceEntry dartEntry,
150 DataDescriptor rowDesc, CacheState state) {
151 if (state != stateFilter || rowDesc.toString() != descriptorFilter) {
152 return;
153 }
154 response.write('<li>${HTML_ESCAPE.convert(source.fullName)}</li>');
155 count++;
156 });
157 });
158 response.write('<p>$count files found</p>');
Brian Wilkerson 2014/10/29 13:51:02 Need to terminate the <ul> tag.
Paul Berry 2014/10/29 18:39:11 Done.
159 response.write('</body>');
160 response.write('</html>');
161 response.close();
162 }
163
164 /**
47 * Return a response indicating the status of the analysis server. 165 * Return a response indicating the status of the analysis server.
48 */ 166 */
49 void _returnServerStatus(HttpRequest request) { 167 void _returnServerStatus(HttpRequest request) {
50 HttpResponse response = request.response; 168 HttpResponse response = request.response;
51 response.statusCode = HttpStatus.OK; 169 response.statusCode = HttpStatus.OK;
52 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html"); 170 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html");
53 response.write('<html>'); 171 response.write('<html>');
54 response.write('<head>'); 172 response.write('<head>');
55 response.write('<title>Dart Analysis Server - Status</title>'); 173 response.write('<title>Dart Analysis Server - Status</title>');
56 response.write('</head>'); 174 response.write('</head>');
57 response.write('<body>'); 175 response.write('<body>');
58 response.write('<h1>Analysis Server</h1>'); 176 response.write('<h1>Analysis Server</h1>');
59 if (_server.analysisServer == null) { 177 if (_server.analysisServer == null) {
60 response.write('<p>Not running</p>'); 178 response.write('<p>Not running</p>');
61 } else { 179 } else {
62 response.write('<p>Running</p>'); 180 response.write('<p>Running</p>');
63 response.write('<h1>Analysis Contexts</h1>'); 181 response.write('<h1>Analysis Contexts</h1>');
64 response.write('<h2>Summary</h2>'); 182 response.write('<h2>Summary</h2>');
65 response.write('<table>'); 183 response.write('<table>');
66 _writeRow( 184 List headerRowText = ['Context'];
67 response, 185 headerRowText.addAll(STATES);
68 ['Context', 'ERROR', 'FLUSHED', 'IN_PROCESS', 'INVALID', 'VALID'], 186 _writeRow(response, headerRowText, true);
69 true);
70 _server.analysisServer.folderMap.forEach((Folder folder, AnalysisContextIm pl context) { 187 _server.analysisServer.folderMap.forEach((Folder folder, AnalysisContextIm pl context) {
71 String key = folder.shortName; 188 String key = folder.shortName;
72 AnalysisContextStatistics statistics = context.statistics; 189 AnalysisContextStatistics statistics = context.statistics;
73 int errorCount = 0; 190 Map<CacheState, int> totals = <CacheState, int>{};
74 int flushedCount = 0; 191 for (CacheState state in STATES) {
75 int inProcessCount = 0; 192 totals[state] = 0;
76 int invalidCount = 0; 193 }
77 int validCount = 0;
78 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) { 194 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
79 errorCount += row.errorCount; 195 for (CacheState state in STATES) {
80 flushedCount += row.flushedCount; 196 totals[state] += row.getCount(state);
81 inProcessCount += row.inProcessCount; 197 }
82 invalidCount += row.invalidCount;
83 validCount += row.validCount;
84 }); 198 });
85 _writeRow(response, [ 199 List rowText = ['<a href="#context_${HTML_ESCAPE.convert(key)}">$key</a> '];
86 '<a href="#context_${HTML_ESCAPE.convert(key)}">$key</a>', 200 for (CacheState state in STATES) {
87 errorCount, 201 rowText.add(totals[state]);
88 flushedCount, 202 }
89 inProcessCount, 203 _writeRow(response, rowText);
90 invalidCount,
91 validCount]);
92 }); 204 });
93 response.write('</table>'); 205 response.write('</table>');
94 _server.analysisServer.folderMap.forEach((Folder folder, AnalysisContextIm pl context) { 206 _server.analysisServer.folderMap.forEach((Folder folder, AnalysisContextIm pl context) {
95 String key = folder.shortName; 207 String key = folder.shortName;
96 response.write('<h2><a name="context_${HTML_ESCAPE.convert(key)}">Analys is Context: $key</a></h2>'); 208 response.write('<h2><a name="context_${HTML_ESCAPE.convert(key)}">Analys is Context: $key</a></h2>');
97 AnalysisContextStatistics statistics = context.statistics; 209 AnalysisContextStatistics statistics = context.statistics;
98 response.write('<table>'); 210 response.write('<table>');
99 _writeRow( 211 _writeRow(response, headerRowText, true);
100 response,
101 ['Item', 'ERROR', 'FLUSHED', 'IN_PROCESS', 'INVALID', 'VALID'],
102 true);
103 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) { 212 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
104 _writeRow( 213 List rowText = [row.name];
105 response, 214 for (CacheState state in STATES) {
106 [row.name, 215 String text = row.getCount(state).toString();
107 row.errorCount, 216 Map<String, String> params = <String, String>{
108 row.flushedCount, 217 STATE_QUERY_PARAM: state.toString(),
109 row.inProcessCount, 218 CONTEXT_QUERY_PARAM: folder.path,
110 row.invalidCount, 219 DESCRIPTOR_QUERY_PARAM: row.name
111 row.validCount]); 220 };
221 rowText.add(_makeLink(CACHE_STATE_PATH, params, text));
222 }
223 _writeRow(response, rowText);
112 }); 224 });
113 response.write('</table>'); 225 response.write('</table>');
114 List<CaughtException> exceptions = statistics.exceptions; 226 List<CaughtException> exceptions = statistics.exceptions;
115 if (!exceptions.isEmpty) { 227 if (!exceptions.isEmpty) {
116 response.write('<h2>Exceptions</h2>'); 228 response.write('<h2>Exceptions</h2>');
117 exceptions.forEach((CaughtException exception) { 229 exceptions.forEach((CaughtException exception) {
118 response.write('<p>${exception.exception}</p>'); 230 response.write('<p>${exception.exception}</p>');
119 }); 231 });
120 } 232 }
121 }); 233 });
122 } 234 }
123 response.write('</body>'); 235 response.write('</body>');
124 response.write('</html>'); 236 response.write('</html>');
125 response.close(); 237 response.close();
126 } 238 }
127 239
128 /** 240 /**
129 * Return an error in response to an unrecognized request received by the HTTP 241 * Return an error in response to an unrecognized request received by the HTTP
130 * server. 242 * server.
131 */ 243 */
132 void _returnUnknownRequest(HttpRequest request) { 244 void _returnUnknownRequest(HttpRequest request) {
133 HttpResponse response = request.response; 245 HttpResponse response = request.response;
134 response.statusCode = HttpStatus.NOT_FOUND; 246 response.statusCode = HttpStatus.NOT_FOUND;
135 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); 247 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");
136 response.write('Not found'); 248 response.write('Not found');
137 response.close(); 249 response.close();
138 } 250 }
139 251
252 void _returnFailure(HttpRequest request, String message) {
253 HttpResponse response = request.response;
254 response.statusCode = HttpStatus.OK;
255 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html");
256 response.write('<html>');
257 response.write('<head>');
258 response.write('<title>Dart Analysis Server - Failure</title>');
259 response.write('</head>');
260 response.write('<body>');
261 response.write(HTML_ESCAPE.convert(message));
262 response.write('</body>');
263 response.write('</html>');
264 response.close();
265 }
266
140 /** 267 /**
141 * Write a single row within a table to the given [response] object. The row 268 * Write a single row within a table to the given [response] object. The row
142 * will have one cell for each of the [columns], and will be a header row if 269 * will have one cell for each of the [columns], and will be a header row if
143 * [header] is `true`. 270 * [header] is `true`.
144 */ 271 */
145 void _writeRow(HttpResponse response, List<Object> columns, [bool header = fal se]) { 272 void _writeRow(HttpResponse response, List<Object> columns, [bool header = fal se]) {
146 response.write('<tr>'); 273 response.write('<tr>');
147 columns.forEach((Object value) { 274 columns.forEach((Object value) {
148 if (header) { 275 if (header) {
149 response.write('<th>'); 276 response.write('<th>');
150 } else { 277 } else {
151 response.write('<td>'); 278 response.write('<td>');
152 } 279 }
153 response.write(value); 280 response.write(value);
154 if (header) { 281 if (header) {
155 response.write('</th>'); 282 response.write('</th>');
156 } else { 283 } else {
157 response.write('</td>'); 284 response.write('</td>');
158 } 285 }
159 }); 286 });
160 response.write('</tr>'); 287 response.write('</tr>');
161 } 288 }
162 } 289 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/engine.dart » ('j') | pkg/analyzer/lib/src/generated/engine.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698