Changeset 1019 for trunk/autoquest-htmlmonitor/src
- Timestamp:
- 12/14/12 15:10:12 (12 years ago)
- Location:
- trunk/autoquest-htmlmonitor/src/main
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-htmlmonitor/src/main/assembly/bin.xml
r936 r1019 34 34 </includes> 35 35 </fileSet> 36 <fileSet> 37 <directory>data</directory> 38 <outputDirectory>data</outputDirectory> 39 <fileMode>664</fileMode> 40 <includes> 41 <include>**/*</include> 42 </includes> 43 </fileSet> 36 44 </fileSets> 37 45 </assembly> -
trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlClientInfos.java
r927 r1019 57 57 * @param title title of the web site shown by the browser of the client 58 58 */ 59 publicHtmlClientInfos(String clientId, String userAgent, URL url, String title) {59 HtmlClientInfos(String clientId, String userAgent, URL url, String title) { 60 60 this.clientId = clientId; 61 61 this.userAgent = userAgent; -
trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorLogManager.java
r927 r1019 115 115 */ 116 116 @Override 117 public void handleMessage(HtmlClientInfos clientInfos, HtmlEvent[] events) { 117 public void handleMessage(HtmlClientInfos clientInfos, 118 HtmlPageElement guiStructure, 119 HtmlEvent[] events) 120 { 118 121 HtmlMonitorOutputWriter writer = writers.get(clientInfos.getClientId()); 119 122 … … 132 135 } 133 136 134 writer.handleMessage(clientInfos, events);137 writer.handleMessage(clientInfos, guiStructure, events); 135 138 } 136 139 catch (Exception e) { … … 144 147 if (writer != null) { 145 148 try { 146 writer.handleMessage(clientInfos, events);149 writer.handleMessage(clientInfos, guiStructure, events); 147 150 } 148 151 catch (Exception e1) { -
trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorMessageListener.java
r927 r1019 32 32 * 33 33 * @param clientInfos infos about the client that send the events 34 * @param TODO comment 34 35 * @param events the received events 35 36 */ 36 void handleMessage(HtmlClientInfos clientInfos, HtmlEvent[] events); 37 void handleMessage(HtmlClientInfos clientInfos, 38 HtmlPageElement guiStructure, 39 HtmlEvent[] events); 37 40 38 41 } -
trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorOutputWriter.java
r997 r1019 22 22 import java.text.DecimalFormat; 23 23 24 import de.ugoe.cs.util.StringTools; 24 25 import de.ugoe.cs.util.console.Console; 25 26 … … 177 178 */ 178 179 @Override 179 public void handleMessage(HtmlClientInfos clientInfos, HtmlEvent[] events) { 180 public void handleMessage(HtmlClientInfos clientInfos, 181 HtmlPageElement guiStructure, 182 HtmlEvent[] events) 183 { 180 184 if (outputWriter == null) { 181 185 throw new IllegalStateException("not initialized. Call init() first"); 182 186 } 183 187 188 if (guiStructure != null) { 189 dumpGuiStructure(guiStructure); 190 } 191 184 192 for (HtmlEvent event : events) { 185 193 dumpEvent(event); … … 200 208 /** 201 209 * <p> 210 * TODO: comment 211 * </p> 212 * 213 * @param guiStructure 214 */ 215 private void dumpGuiStructure(HtmlPageElement guiStructure) { 216 outputWriter.print("<component path=\""); 217 outputWriter.print(guiStructure.getPath()); 218 outputWriter.println("\">"); 219 220 dumpParam("class", guiStructure.getTagName()); 221 dumpParam("htmlId", guiStructure.getId()); 222 dumpParam("title", guiStructure.getTitle()); 223 dumpParam("index", guiStructure.getIndex()); 224 dumpParam("parent", guiStructure.getParentPath()); 225 226 outputWriter.println("</component>"); 227 228 if (guiStructure.getChildren() != null) { 229 for (HtmlPageElement child : guiStructure.getChildren()) { 230 dumpGuiStructure(child); 231 } 232 } 233 } 234 235 /** 236 * <p> 202 237 * formats a received event and writes it to the log file. One event results in one line 203 238 * in the log file containing all infos of the event. … … 207 242 */ 208 243 private void dumpEvent(HtmlEvent event) { 209 dumpString(event.getClientInfos().getClientId()); 210 outputWriter.print(' '); 211 dumpString(event.getTime().toString()); 212 outputWriter.print(' '); 213 dumpString(event.getClientInfos().getTitle()); 214 outputWriter.print(' '); 215 dumpString(event.getClientInfos().getUrl().toString()); 216 outputWriter.print(' '); 217 dumpString(event.getClientInfos().getUserAgent()); 218 outputWriter.print(' '); 219 dumpString(event.getEventType()); 220 outputWriter.print(' '); 221 dumpString(event.getPath()); 222 244 outputWriter.print("<event type=\""); 245 outputWriter.print(event.getEventType()); 246 outputWriter.println("\">"); 247 223 248 if (event.getCoordinates() != null) { 224 outputWriter.print(' '); 225 226 StringBuffer value = new StringBuffer(); 227 for (int i = 0; i < event.getCoordinates().length; i++) { 228 if (i > 0) { 229 value.append(','); 230 } 231 value.append(event.getCoordinates()[i]); 232 } 233 234 dumpString(value.toString()); 235 } 236 237 if (event.getKey() != null) { 238 outputWriter.print(' '); 239 dumpString(event.getKey().toString()); 240 } 249 dumpParam("X", event.getCoordinates()[0]); 250 dumpParam("Y", event.getCoordinates()[1]); 251 } 252 253 dumpParam("key", event.getKey()); 241 254 242 255 if (event.getScrollPosition() != null) { 243 outputWriter.print(' ');244 245 StringBuffer value = new StringBuffer();246 for (int i = 0; i < event.getScrollPosition().length; i++) { 247 if (i > 0) {248 value.append(',');249 }250 value.append(event.getScrollPosition()[i]);251 }252 253 dumpString(value.toString()); 254 }255 256 if (event.getSelectedValue() != null) {257 outputWriter.print(' ');258 dumpString(event.getSelectedValue());259 }260 261 outputWriter.println();262 }263 264 /**265 * <p>266 * convenience method to dump a string with trailing and leading " as well as replaced267 * backslashes, ", and newlines268 * </p>269 *270 * @param clientId2271 */272 private void dumpString(String str){273 String value = str;274 value = value.replaceAll("\\\\", "\\\\\\\\");275 value = value.replaceAll("\\\"", "\\\\\\\"");276 value = value.replaceAll("\n", "\\\\n");277 278 outputWriter.print( '"');279 outputWriter.print( value);280 outputWriter.print ('"');256 dumpParam("scrollX", event.getScrollPosition()[0]); 257 dumpParam("scrollY", event.getScrollPosition()[1]); 258 } 259 260 dumpParam("selectedValue", event.getSelectedValue()); 261 dumpParam("target", event.getPath()); 262 dumpParam("timestamp", event.getTime()); 263 264 outputWriter.println("</event>"); 265 } 266 267 /** 268 * <p> 269 * TODO: comment 270 * </p> 271 * 272 * @param string 273 * @param integer 274 */ 275 private void dumpParam(String name, Object value) { 276 if (value == null) { 277 return; 278 } 279 280 String val; 281 282 if (value instanceof String) { 283 val = (String) value; 284 } 285 else { 286 val = value.toString(); 287 } 288 289 outputWriter.print(" <param name=\""); 290 outputWriter.print(name); 291 outputWriter.print("\" value=\""); 292 outputWriter.print(StringTools.xmlEntityReplacement(val)); 293 outputWriter.println("\"/>"); 281 294 } 282 295 … … 332 345 FileOutputStream fis = new FileOutputStream(logFile); 333 346 outputWriter = new PrintWriter(new OutputStreamWriter(fis, "UTF-8")); 347 outputWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); 348 outputWriter.println("<session>"); 334 349 } 335 350 … … 341 356 private void closeLogWriter() { 342 357 if (outputWriter != null) { 358 outputWriter.println("</session>"); 343 359 outputWriter.flush(); 344 360 outputWriter.close(); -
trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorServlet.java
r998 r1019 16 16 17 17 import java.io.BufferedReader; 18 import java.io.FileNotFoundException; 18 19 import java.io.IOException; 19 20 import java.io.InputStream; … … 37 38 import org.mortbay.jetty.servlet.DefaultServlet; 38 39 40 import de.ugoe.cs.util.FileTools; 39 41 import de.ugoe.cs.util.console.Console; 40 42 … … 59 61 60 62 /** 63 * <p> 64 * Name and path of the robot filter. 65 * </p> 66 */ 67 private static final String ROBOTFILTERFILE = "data/robots/robotfilter.txt"; 68 69 /** 70 * <p> 71 * Field that contains a regular expression that matches all robots 72 * contained in {@link #ROBOTFILTERFILE}. 73 * </p> 74 */ 75 private String robotRegex = null; 76 77 /** 61 78 * the message listener to forward received messages to. 62 79 */ … … 72 89 HtmlMonitorServlet(HtmlMonitorMessageListener messageListener) { 73 90 this.messageListener = messageListener; 91 try { 92 loadRobotRegex(); 93 } 94 catch (Exception e) { 95 Console.println 96 ("robot filtering disabled: could not parse robot filter file " + ROBOTFILTERFILE); 97 } 74 98 } 75 99 … … 89 113 InputStream script = this.getClass().getClassLoader().getResourceAsStream 90 114 ("autoquest-htmlmonitor.js"); 91 115 92 116 if (script == null) { 93 117 Console.printerrln("could not read autoquest-htmlmonitor.js from classpath"); … … 126 150 Object value = null; 127 151 try { 152 //InputStream requestInputStream = dumpStreamContent(request.getInputStream()); 128 153 InputStream requestInputStream = request.getInputStream(); 129 154 130 155 value = JSONValue.parseWithException 131 156 (new InputStreamReader(requestInputStream, "UTF-8")); … … 169 194 ("incoming message does not contain valid client infos --> discarding it"); 170 195 } 171 else { 196 else if (isRobot(clientInfos.getUserAgent())) { 197 Console.printerrln 198 ("ignoring robot " + clientInfos.getUserAgent()); 199 } 200 else { 201 HtmlPageElement guiStructure = extractHtmlPageElements(message, clientInfos); 172 202 HtmlEvent[] events = extractHtmlEvents(message, clientInfos); 203 173 204 if (events == null) { 174 205 Console.printerrln … … 176 207 } 177 208 else { 178 messageListener.handleMessage(clientInfos, events);209 messageListener.handleMessage(clientInfos, guiStructure, events); 179 210 } 180 211 } … … 244 275 events = new ArrayList<HtmlEvent>(); 245 276 277 HtmlPageElement server = getServerElement(clientInfos); 278 HtmlPageElement page = getPageElementRepresentingWebPage(clientInfos, server); 279 246 280 for (int i = 0; i < eventArray.size(); i++) { 247 281 Object eventObj = eventArray.get(i); … … 277 311 (eventType, coordinates, key, scrollPosition, selectedValue)) 278 312 { 279 events.add(new HtmlEvent(clientInfos, time, path, eventType, coordinates, 280 key, scrollPosition, selectedValue)); 313 path = page.getPath() + path; 314 events.add(new HtmlEvent(clientInfos, time, path, eventType, 315 coordinates, key, scrollPosition, selectedValue)); 281 316 } 282 317 else { … … 294 329 return null; 295 330 } 331 } 332 333 /** 334 * <p> 335 * TODO: comment 336 * </p> 337 * 338 * @param message 339 * @param clientInfos 340 * @return 341 */ 342 private HtmlPageElement extractHtmlPageElements(JSONObject object, 343 HtmlClientInfos clientInfos) 344 { 345 HtmlPageElement server = getServerElement(clientInfos); 346 HtmlPageElement page = getPageElementRepresentingWebPage(clientInfos, server); 347 348 JSONObject jsonPageElement = assertValue(object, "guiModel", JSONObject.class); 349 page.addChild(convert(jsonPageElement, page.getPath())); 350 351 return server; 352 } 353 354 /** 355 * <p> 356 * TODO: comment 357 * </p> 358 * 359 * @param clientInfos 360 * @return 361 */ 362 private HtmlPageElement getServerElement(HtmlClientInfos clientInfos) { 363 String id = clientInfos.getUrl().getHost(); 364 if (clientInfos.getUrl().getPort() > -1) { 365 id += ":" + clientInfos.getUrl().getPort(); 366 } 367 368 return new HtmlPageElement(null, "server", id, 0); 369 } 370 371 /** 372 * <p> 373 * TODO: comment 374 * </p> 375 * 376 * @param clientInfos 377 */ 378 private HtmlPageElement getPageElementRepresentingWebPage(HtmlClientInfos clientInfos, 379 HtmlPageElement server) 380 { 381 String id = clientInfos.getUrl().getPath(); 382 383 if (clientInfos.getUrl().getQuery() != null) { 384 id += "?" + clientInfos.getUrl().getQuery(); 385 } 386 387 HtmlPageElement page = 388 new HtmlPageElement(server.getPath(), "document", id, clientInfos.getTitle(), 0); 389 390 server.addChild(page); 391 392 return page; 393 } 394 395 /** 396 * <p> 397 * TODO: comment 398 * </p> 399 * 400 * @param jsonPageElement 401 * @return 402 */ 403 private HtmlPageElement convert(JSONObject jsonPageElement, String parentPath) { 404 HtmlPageElement result = null; 405 406 if (jsonPageElement != null) { 407 String tagName = assertValue(jsonPageElement, "tagName", String.class); 408 String id = assertValue(jsonPageElement, "id", String.class); 409 Integer index = assertValue(jsonPageElement, "index", Integer.class); 410 411 result = new HtmlPageElement(parentPath, tagName, id, index); 412 413 JSONArray childElements = assertValue(jsonPageElement, "children", JSONArray.class); 414 415 if (childElements != null) { 416 Object jsonChild; 417 418 for (int i = 0; i < childElements.size(); i++) { 419 jsonChild = childElements.get(i); 420 if (!(jsonChild instanceof JSONObject)) { 421 Console.printerrln("child " + (i + 1) + " of HTML page element " + tagName + 422 " is no valid HTML page element"); 423 } 424 else { 425 result.addChild(convert((JSONObject) jsonChild, result.getPath())); 426 } 427 } 428 } 429 430 } 431 432 return result; 296 433 } 297 434 … … 495 632 /** 496 633 * <p> 634 * Checks whether an agent is a robot. 635 * </p> 636 * 637 * @param agent 638 * agent that is checked 639 * @return true, if the agent is a robot; false otherwise 640 */ 641 private boolean isRobot(String agent) { 642 return agent.matches(robotRegex); 643 } 644 645 /** 646 * <p> 647 * Reads {@link #ROBOTFILTERFILE} and creates a regular expression that 648 * matches all the robots defined in the file. The regular expression is 649 * stored in the field {@link #robotRegex}. 650 * </p> 651 * 652 * @throws IOException 653 * thrown if there is a problem reading the robot filter 654 * @throws FileNotFoundException 655 * thrown if the robot filter is not found 656 */ 657 private void loadRobotRegex() throws IOException, FileNotFoundException { 658 String[] lines = FileTools.getLinesFromFile(ROBOTFILTERFILE); 659 StringBuilder regex = new StringBuilder(); 660 for (int i = 0; i < lines.length; i++) { 661 regex.append("(.*" + lines[i] + ".*)"); 662 if (i != lines.length - 1) { 663 regex.append('|'); 664 } 665 } 666 robotRegex = regex.toString(); 667 } 668 669 /** 670 * <p> 497 671 * convenience method for dumping the content of a stream and returning a new stream 498 672 * containing the same data. … … 504 678 * @throws IOException if the stream can not be read 505 679 */ 506 /*private InputStream dumpStreamContent(ServletInputStream inputStream) throws IOException {680 /* private InputStream dumpStreamContent(ServletInputStream inputStream) throws IOException { 507 681 List<Byte> bytes = new ArrayList<Byte>(); 508 682 int buf;
Note: See TracChangeset
for help on using the changeset viewer.