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

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: Changes based on code review 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
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/engine.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /**
20 * The path used to request the status of the analysis server as a whole. 22 * The path used to request the status of the analysis server as a whole.
21 */ 23 */
22 static const String STATUS_PATH = '/status'; 24 static const String STATUS_PATH = '/status';
23 25
24 /** 26 /**
27 * The path used to request the list of source files in a certain cache
28 * state.
29 */
30 static const String CACHE_STATE_PATH = '/cache_state';
31
32 /**
33 * Query parameter used to represent the cache state to search for, when
34 * accessing [CACHE_STATE_PATH].
35 */
36 static const String STATE_QUERY_PARAM = 'state';
37
38 /**
39 * Query parameter used to represent the context to search for, when
40 * accessing [CACHE_STATE_PATH].
41 */
42 static const String CONTEXT_QUERY_PARAM = 'context';
43
44 /**
45 * Query parameter used to represent the descriptor to search for, when
46 * accessing [CACHE_STATE_PATH].
47 */
48 static const String DESCRIPTOR_QUERY_PARAM = 'descriptor';
49
50 /**
25 * The socket server whose status is to be reported on. 51 * The socket server whose status is to be reported on.
26 */ 52 */
27 SocketServer _server; 53 SocketServer _server;
28 54
29 /** 55 /**
30 * Buffer containing strings printed by the analysis server. 56 * Buffer containing strings printed by the analysis server.
31 */ 57 */
32 List<String> _printBuffer; 58 List<String> _printBuffer;
33 59
34 /** 60 /**
35 * Initialize a newly created handler for GET requests. 61 * Initialize a newly created handler for GET requests.
36 */ 62 */
37 GetHandler(this._server, this._printBuffer); 63 GetHandler(this._server, this._printBuffer);
38 64
39 /** 65 /**
40 * Handle a GET request received by the HTTP server. 66 * Handle a GET request received by the HTTP server.
41 */ 67 */
42 void handleGetRequest(HttpRequest request) { 68 void handleGetRequest(HttpRequest request) {
43 String path = request.uri.path; 69 String path = request.uri.path;
44 if (path == STATUS_PATH) { 70 if (path == STATUS_PATH) {
45 _returnServerStatus(request); 71 _returnServerStatus(request);
72 } else if (path == CACHE_STATE_PATH) {
73 _returnCacheState(request);
46 } else { 74 } else {
47 _returnUnknownRequest(request); 75 _returnUnknownRequest(request);
48 } 76 }
49 } 77 }
50 78
51 /** 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('</ul>');
159 response.write('<p>$count files found</p>');
160 response.write('</body>');
161 response.write('</html>');
162 response.close();
163 }
164
165 /**
52 * Return a response indicating the status of the analysis server. 166 * Return a response indicating the status of the analysis server.
53 */ 167 */
54 void _returnServerStatus(HttpRequest request) { 168 void _returnServerStatus(HttpRequest request) {
55 HttpResponse response = request.response; 169 HttpResponse response = request.response;
56 response.statusCode = HttpStatus.OK; 170 response.statusCode = HttpStatus.OK;
57 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html"); 171 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html");
58 response.write('<html>'); 172 response.write('<html>');
59 response.write('<head>'); 173 response.write('<head>');
60 response.write('<title>Dart Analysis Server - Status</title>'); 174 response.write('<title>Dart Analysis Server - Status</title>');
61 response.write('</head>'); 175 response.write('</head>');
62 response.write('<body>'); 176 response.write('<body>');
63 response.write('<h1>Analysis Server</h1>'); 177 response.write('<h1>Analysis Server</h1>');
64 if (_server.analysisServer == null) { 178 if (_server.analysisServer == null) {
65 response.write('<p>Not running</p>'); 179 response.write('<p>Not running</p>');
66 } else { 180 } else {
67 response.write('<p>Running</p>'); 181 response.write('<p>Running</p>');
68 response.write('<h1>Analysis Contexts</h1>'); 182 response.write('<h1>Analysis Contexts</h1>');
69 response.write('<h2>Summary</h2>'); 183 response.write('<h2>Summary</h2>');
70 response.write('<table>'); 184 response.write('<table>');
71 _writeRow( 185 List headerRowText = ['Context'];
72 response, 186 headerRowText.addAll(CacheState.values);
73 ['Context', 'ERROR', 'FLUSHED', 'IN_PROCESS', 'INVALID', 'VALID'], 187 _writeRow(response, headerRowText, true);
74 true);
75 _server.analysisServer.folderMap.forEach((Folder folder, AnalysisContextIm pl context) { 188 _server.analysisServer.folderMap.forEach((Folder folder, AnalysisContextIm pl context) {
76 String key = folder.shortName; 189 String key = folder.shortName;
77 AnalysisContextStatistics statistics = context.statistics; 190 AnalysisContextStatistics statistics = context.statistics;
78 int errorCount = 0; 191 Map<CacheState, int> totals = <CacheState, int>{};
79 int flushedCount = 0; 192 for (CacheState state in CacheState.values) {
80 int inProcessCount = 0; 193 totals[state] = 0;
81 int invalidCount = 0; 194 }
82 int validCount = 0;
83 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) { 195 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
84 errorCount += row.errorCount; 196 for (CacheState state in CacheState.values) {
85 flushedCount += row.flushedCount; 197 totals[state] += row.getCount(state);
86 inProcessCount += row.inProcessCount; 198 }
87 invalidCount += row.invalidCount;
88 validCount += row.validCount;
89 }); 199 });
90 _writeRow(response, [ 200 List rowText = ['<a href="#context_${HTML_ESCAPE.convert(key)}">$key</a> '];
91 '<a href="#context_${HTML_ESCAPE.convert(key)}">$key</a>', 201 for (CacheState state in CacheState.values) {
92 errorCount, 202 rowText.add(totals[state]);
93 flushedCount, 203 }
94 inProcessCount, 204 _writeRow(response, rowText);
95 invalidCount,
96 validCount]);
97 }); 205 });
98 response.write('</table>'); 206 response.write('</table>');
99 _server.analysisServer.folderMap.forEach((Folder folder, AnalysisContextIm pl context) { 207 _server.analysisServer.folderMap.forEach((Folder folder, AnalysisContextIm pl context) {
100 String key = folder.shortName; 208 String key = folder.shortName;
101 response.write('<h2><a name="context_${HTML_ESCAPE.convert(key)}">Analys is Context: $key</a></h2>'); 209 response.write('<h2><a name="context_${HTML_ESCAPE.convert(key)}">Analys is Context: $key</a></h2>');
102 AnalysisContextStatistics statistics = context.statistics; 210 AnalysisContextStatistics statistics = context.statistics;
103 response.write('<table>'); 211 response.write('<table>');
104 _writeRow( 212 _writeRow(response, headerRowText, true);
105 response,
106 ['Item', 'ERROR', 'FLUSHED', 'IN_PROCESS', 'INVALID', 'VALID'],
107 true);
108 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) { 213 statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
109 _writeRow( 214 List rowText = [row.name];
110 response, 215 for (CacheState state in CacheState.values) {
111 [row.name, 216 String text = row.getCount(state).toString();
112 row.errorCount, 217 Map<String, String> params = <String, String>{
113 row.flushedCount, 218 STATE_QUERY_PARAM: state.toString(),
114 row.inProcessCount, 219 CONTEXT_QUERY_PARAM: folder.path,
115 row.invalidCount, 220 DESCRIPTOR_QUERY_PARAM: row.name
116 row.validCount]); 221 };
222 rowText.add(_makeLink(CACHE_STATE_PATH, params, text));
223 }
224 _writeRow(response, rowText);
117 }); 225 });
118 response.write('</table>'); 226 response.write('</table>');
119 List<CaughtException> exceptions = statistics.exceptions; 227 List<CaughtException> exceptions = statistics.exceptions;
120 if (!exceptions.isEmpty) { 228 if (!exceptions.isEmpty) {
121 response.write('<h2>Exceptions</h2>'); 229 response.write('<h2>Exceptions</h2>');
122 exceptions.forEach((CaughtException exception) { 230 exceptions.forEach((CaughtException exception) {
123 response.write('<p>${exception.exception}</p>'); 231 response.write('<p>${exception.exception}</p>');
124 }); 232 });
125 } 233 }
126 }); 234 });
(...skipping 12 matching lines...) Expand all
139 * server. 247 * server.
140 */ 248 */
141 void _returnUnknownRequest(HttpRequest request) { 249 void _returnUnknownRequest(HttpRequest request) {
142 HttpResponse response = request.response; 250 HttpResponse response = request.response;
143 response.statusCode = HttpStatus.NOT_FOUND; 251 response.statusCode = HttpStatus.NOT_FOUND;
144 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain"); 252 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");
145 response.write('Not found'); 253 response.write('Not found');
146 response.close(); 254 response.close();
147 } 255 }
148 256
257 void _returnFailure(HttpRequest request, String message) {
258 HttpResponse response = request.response;
259 response.statusCode = HttpStatus.OK;
260 response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html");
261 response.write('<html>');
262 response.write('<head>');
263 response.write('<title>Dart Analysis Server - Failure</title>');
264 response.write('</head>');
265 response.write('<body>');
266 response.write(HTML_ESCAPE.convert(message));
267 response.write('</body>');
268 response.write('</html>');
269 response.close();
270 }
271
149 /** 272 /**
150 * Write a single row within a table to the given [response] object. The row 273 * Write a single row within a table to the given [response] object. The row
151 * will have one cell for each of the [columns], and will be a header row if 274 * will have one cell for each of the [columns], and will be a header row if
152 * [header] is `true`. 275 * [header] is `true`.
153 */ 276 */
154 void _writeRow(HttpResponse response, List<Object> columns, [bool header = fal se]) { 277 void _writeRow(HttpResponse response, List<Object> columns, [bool header = fal se]) {
155 response.write('<tr>'); 278 response.write('<tr>');
156 columns.forEach((Object value) { 279 columns.forEach((Object value) {
157 if (header) { 280 if (header) {
158 response.write('<th>'); 281 response.write('<th>');
159 } else { 282 } else {
160 response.write('<td>'); 283 response.write('<td>');
161 } 284 }
162 response.write(value); 285 response.write(value);
163 if (header) { 286 if (header) {
164 response.write('</th>'); 287 response.write('</th>');
165 } else { 288 } else {
166 response.write('</td>'); 289 response.write('</td>');
167 } 290 }
168 }); 291 });
169 response.write('</tr>'); 292 response.write('</tr>');
170 } 293 }
171 } 294 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698