Changeset 1893
- Timestamp:
- 03/05/15 11:50:56 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/HTMLLogParser.java
r1817 r1893 19 19 import java.io.FileNotFoundException; 20 20 import java.io.IOException; 21 import java.io.UnsupportedEncodingException; 22 import java.security.MessageDigest; 23 import java.security.NoSuchAlgorithmException; 21 24 import java.util.HashMap; 22 25 import java.util.LinkedList; 23 26 import java.util.List; 27 import java.util.ListIterator; 24 28 import java.util.Map; 25 29 import java.util.Properties; … … 27 31 import java.util.regex.Pattern; 28 32 33 import org.apache.commons.codec.binary.Base64; 29 34 import org.xml.sax.SAXException; 30 35 … … 69 74 /** 70 75 * <p> 76 * the mapping between ids and their replacements due to merging while parsing 77 * </p> 78 */ 79 private Map<String, String> idMapping = new HashMap<>(); 80 81 /** 82 * <p> 71 83 * file containing parameters to influence parsing 72 84 * </p> … … 99 111 throws SAXException 100 112 { 113 if (idMapping.containsKey(id)) { 114 // the element is already existing. Return, that it was processed 115 return true; 116 } 117 118 String parentId = parameters.get("parent"); 119 120 if (parentId != null) { 121 parentId = idMapping.get(parentId); 122 123 if (parentId == null) { 124 // parent not yet handled, return that this elements can not be handled yet 125 return false; 126 } 127 } 128 129 HTMLGUIElement parent = (HTMLGUIElement) super.getGUIElementTree().find(parentId); 130 101 131 ensureParsingParameters(); 102 132 103 133 HTMLGUIElementSpec specification = null; 104 105 String parentId = parameters.get("parent"); 106 HTMLGUIElement parent = (HTMLGUIElement) super.getGUIElementTree().find(parentId); 107 134 String replacementId = null; 135 108 136 if (parameters.containsKey("host")) { 109 137 // this is a server specification … … 115 143 } 116 144 117 specification = new HTMLServerSpec(parameters.get("host"), port); 145 String host = parameters.get("host"); 146 specification = new HTMLServerSpec(host, port); 147 replacementId = calculateId(host, portStr); 118 148 } 119 149 else if (parameters.containsKey("path")) { … … 126 156 } 127 157 158 String path = parameters.get("path"); 159 String query = parameters.get("query"); 160 String title = parameters.get("title"); 161 162 String replacement = getReplacementMapping(path, parent); 163 164 if (replacement != null) { 165 if (replacement.startsWith("CLEAR_QUERY,")) { 166 query = null; 167 replacement = replacement.substring("CLEAR_QUERY,".length()); 168 } 169 else if ("CLEAR_QUERY".equals(replacement)) { 170 query = null; 171 replacement = path; 172 } 173 174 if ("".equals(replacement)) { 175 path = null; 176 } 177 else { 178 path = replacement; 179 } 180 } 181 128 182 specification = new HTMLDocumentSpec 129 ((HTMLServerSpec) parent.getSpecification(), parameters.get("path"), 130 parameters.get("query"), parameters.get("title")); 183 ((HTMLServerSpec) parent.getSpecification(), path, query, title); 184 185 replacementId = calculateId(parentId, path, query, title); 131 186 } 132 187 else if (parentId == null) { … … 193 248 index = 0; 194 249 } 250 251 HTMLDocumentSpec documentSpec = (HTMLDocumentSpec) document.getSpecification(); 195 252 196 253 specification = new HTMLPageElementSpec 197 ((HTMLDocumentSpec) document.getSpecification(), 198 tagName.intern(), htmlId == null ? null : htmlId.intern(), index); 254 (documentSpec, tagName.intern(), htmlId == null ? null : htmlId.intern(), index); 255 256 replacementId = calculateId 257 (documentSpec.getPath(), documentSpec.getQuery(), documentSpec.getTitle(), 258 parentId, tagName, htmlId, (htmlId == null ? Integer.toString(index) : null)); 199 259 200 260 } … … 209 269 if (specification != null) { 210 270 try { 211 super.getGUIElementTree().add(id, parentId, specification); 271 idMapping.put(id, replacementId); 272 273 super.getGUIElementTree().add(replacementId, parentId, specification); 212 274 } 213 275 catch (GUIModelException e) { … … 222 284 } 223 285 286 /** 287 * <p> 288 * returns the replacement mapping for the document path specified by the parameter, if a 289 * mapping exists. 290 * </p> 291 * 292 * @param path the path of the document 293 * 294 * @return the replacement mapping, if any is configured; null else 295 */ 296 private String getReplacementMapping(String path, HTMLGUIElement parent) { 297 List<ReplacementSpecification> mappingCandidates = 298 replacementSpecifications.get(ReplacementSpecification.LAST_TAG_NAME_FOR_DOCUMENTS); 299 300 List<ReplacementSpecification> candidates = new LinkedList<>(); 301 302 if (mappingCandidates != null) { 303 for (ReplacementSpecification replacementSpec : mappingCandidates) { 304 if (replacementSpec.matches(ReplacementSpecification.LAST_TAG_NAME_FOR_DOCUMENTS, 305 -1, path, parent)) 306 { 307 candidates.add(replacementSpec); 308 } 309 } 310 } 311 312 prioritizeReplacementSpecs(candidates, "document " + path); 313 314 if (candidates.size() == 1) { 315 return candidates.get(0).getReplacement(); 316 } 317 else { 318 return null; 319 } 320 } 321 224 322 /** 225 323 * <p> … … 241 339 List<ReplacementSpecification> mappingCandidates = replacementSpecifications.get(tagName); 242 340 341 List<ReplacementSpecification> candidates = new LinkedList<>(); 342 243 343 if (mappingCandidates != null) { 244 344 for (ReplacementSpecification replacementSpec : mappingCandidates) { 245 345 if (replacementSpec.matches(tagName, index, htmlId, parent)) { 246 return replacementSpec.getReplacement(); 247 } 248 } 249 } 250 251 return null; 346 candidates.add(replacementSpec); 347 } 348 } 349 } 350 351 StringBuffer forWhat = new StringBuffer(); 352 forWhat.append("tag "); 353 toString(tagName, index, htmlId, parent, forWhat); 354 355 prioritizeReplacementSpecs(candidates, forWhat.toString()); 356 357 if (candidates.size() == 1) { 358 return candidates.get(0).getReplacement(); 359 } 360 else { 361 return null; 362 } 363 } 364 365 /** 366 * <p> 367 * decides, which replacement specification is to be preferred, if several match 368 * </p> 369 */ 370 private void prioritizeReplacementSpecs(List<ReplacementSpecification> candidates, 371 String forWhat) 372 { 373 boolean hasNonPattern = false; 374 375 for (ReplacementSpecification spec : candidates) { 376 if (!spec.isPattern()) { 377 hasNonPattern = true; 378 break; 379 } 380 } 381 382 if (hasNonPattern) { 383 ListIterator<ReplacementSpecification> it = candidates.listIterator(); 384 385 while (it.hasNext()) { 386 if (it.next().isPattern()) { 387 it.remove(); 388 } 389 } 390 } 391 392 if (candidates.size() > 1) { 393 StringBuffer message = new StringBuffer(); 394 message.append("parse parameter file is ambigious for "); 395 message.append(forWhat); 396 message.append(". Can be mapped using "); 397 398 int counter = 0; 399 for (ReplacementSpecification spec : candidates) { 400 message.append(spec); 401 counter++; 402 403 if (counter < (candidates.size() - 1)) { 404 message.append(", "); 405 } 406 else if (counter < candidates.size()) { 407 message.append(", and "); 408 } 409 } 410 411 throw new IllegalArgumentException(message.toString()); 412 } 413 } 414 415 /** 416 * 417 */ 418 private void toString(String tagName, 419 int index, 420 String htmlId, 421 HTMLGUIElement parent, 422 StringBuffer message) 423 { 424 LinkedList<HTMLGUIElementSpec> specs = new LinkedList<>(); 425 426 HTMLGUIElement currentParent = parent; 427 428 while (currentParent != null) { 429 specs.addFirst((HTMLGUIElementSpec) currentParent.getSpecification()); 430 currentParent = (HTMLGUIElement) currentParent.getParent(); 431 } 432 433 for (HTMLGUIElementSpec spec : specs) { 434 message.append(spec.toString()); 435 message.append("/"); 436 } 437 438 message.append(tagName); 439 440 if (htmlId != null) { 441 message.append("(htmlId="); 442 message.append(htmlId); 443 message.append(')'); 444 } 445 else { 446 message.append('['); 447 message.append(index); 448 message.append(']'); 449 } 252 450 } 253 451 … … 280 478 } 281 479 282 IGUIElement target = super.getGUIElementTree().find(targetId);283 284 if (target == null) {480 targetId = idMapping.get(targetId); 481 482 if (targetId == null) { 285 483 // event not processible yet 286 484 return false; 287 485 } 486 487 IGUIElement target = super.getGUIElementTree().find(targetId); 288 488 289 489 IEventType eventType = … … 483 683 484 684 /** 685 * <p> 686 * calculates a unique id for the given string fragments using SHA-512 and Base64 encoding. 687 * </p> 688 * 689 * @param fragments strings to be used for calculating a unique id 690 * 691 * @return a Base64 encoded unique id for the provided fragments 692 */ 693 private String calculateId(String... fragments) { 694 try { 695 MessageDigest md = MessageDigest.getInstance("SHA-512"); 696 697 for (String fragment : fragments) { 698 if (fragment != null) { 699 md.update(fragment.getBytes("UTF-8")); 700 } 701 } 702 703 return Base64.encodeBase64String(md.digest()); 704 } 705 catch (UnsupportedEncodingException e) { 706 throw new IllegalStateException("Java VM does not support this code"); 707 } 708 catch (NoSuchAlgorithmException e) { 709 throw new IllegalStateException("Java VM does not support this code"); 710 } 711 } 712 713 /** 485 714 * <p>specification for a replacement consisting of path of tag or document specifications 486 715 * and the appropriate replacement.</p> … … 489 718 490 719 /** 720 * 721 */ 722 private static final String LAST_TAG_NAME_FOR_DOCUMENTS = "LAST_TAG_NAME_FOR_DOCUMENTS"; 723 724 /** 491 725 * <p> 492 726 * the pattern used for parsing parsing parameters … … 494 728 */ 495 729 private Pattern htmlElementSpecPattern = Pattern.compile 496 ("(document\\(path=([\\w/ -]+)\\))|((\\w+)(\\[(\\d+)\\]|\\(htmlId=([\\w-_#]+)\\))?)");730 ("(document\\(path=([\\w/\\-#$&%]+)\\))|((\\w+)(\\[(\\d+)\\]|\\(htmlId=([\\w\\-_#]+)\\))?)"); 497 731 498 732 /** … … 525 759 * </p> 526 760 */ 527 p ublicReplacementSpecification(String tagSpec, String replacement) {761 private ReplacementSpecification(String tagSpec, String replacement) { 528 762 List<String> tagSpecs = split(tagSpec); 529 763 … … 558 792 } 559 793 560 this.lastTagName = ((TagSpec) this.specs.get(this.specs.size() - 1)).getTagName(); 794 if (this.specs.get(this.specs.size() - 1) instanceof TagSpec) { 795 this.lastTagName = ((TagSpec) this.specs.get(this.specs.size() - 1)).getTagName(); 796 } 797 else { 798 this.lastTagName = LAST_TAG_NAME_FOR_DOCUMENTS; 799 } 561 800 562 801 this.replacement = replacement; … … 601 840 /** 602 841 * <p> 842 * returns true, if the spec is a pattern, i.e. matches a group of similar elements 843 * </p> 844 */ 845 public boolean isPattern() { 846 for (Spec spec : specs) { 847 if (spec.isPattern()) { 848 return true; 849 } 850 } 851 852 return false; 853 } 854 855 /** 856 * <p> 603 857 * checks, if the tag identified by the parameters matches this specificaiton. 604 858 * </p> … … 608 862 int currentIndex = index; 609 863 String currentHtmlId = htmlId; 610 String currentPath = null;864 String currentPath = LAST_TAG_NAME_FOR_DOCUMENTS.equals(tagName) ? htmlId : null; 611 865 HTMLGUIElement currentParent = parent; 612 866 … … 634 888 currentPath = null; 635 889 currentParent = (HTMLGUIElement) currentParent.getParent(); 636 890 } 637 891 else if (currentParent instanceof HTMLDocument) { 638 892 currentTagName = null; … … 696 950 * </p> 697 951 */ 698 private static interface Spec { } 952 private static interface Spec { 953 954 /** 955 * <p> 956 * returns true if the spec is a pattern, i.e., matches a group of similar elements 957 * </p> 958 * 959 * @return 960 */ 961 boolean isPattern(); 962 963 } 699 964 700 965 /** … … 721 986 } 722 987 988 /* (non-Javadoc) 989 * @see de.ugoe.cs.autoquest.plugin.html.HTMLLogParser.Spec#isPattern() 990 */ 991 @Override 992 public boolean isPattern() { 993 return (pathPart != null) && (pathPart.indexOf('#') > -1); 994 } 995 723 996 /** 724 997 * <p> … … 727 1000 */ 728 1001 private boolean matches(String path) { 729 return path.contains(pathPart); 1002 if ((path != null) && (path.contains(pathPart))) { 1003 return true; 1004 } 1005 else if ((path != null) && (isPattern() || (pathPart.indexOf('$') > -1))) { 1006 // check if the path condition would match with ignoring specific characters 1007 1008 boolean mustMatchAtEnd = pathPart.charAt(pathPart.length() - 1) == '$'; 1009 1010 int indexInPath = 0; 1011 int indexInPathPart = 0; 1012 1013 while (indexInPath < path.length()) { 1014 if ((path.charAt(indexInPath) == pathPart.charAt(indexInPathPart)) || 1015 (pathPart.charAt(indexInPathPart) == '#')) 1016 { 1017 indexInPathPart++; 1018 1019 if ((indexInPathPart >= pathPart.length()) || 1020 (mustMatchAtEnd && (indexInPathPart == pathPart.length() - 1) && 1021 (indexInPath == path.length() - 1))) 1022 { 1023 // found a match 1024 return true; 1025 } 1026 } 1027 else { 1028 indexInPathPart = 0; 1029 } 1030 1031 indexInPath++; 1032 } 1033 1034 return false; 1035 } 1036 else { 1037 // no condition ignoring specific characters 1038 return false; 1039 } 730 1040 } 731 1041 … … 778 1088 } 779 1089 1090 /* (non-Javadoc) 1091 * @see de.ugoe.cs.autoquest.plugin.html.HTMLLogParser.Spec#isPattern() 1092 */ 1093 @Override 1094 public boolean isPattern() { 1095 return (idCondition != null) && (idCondition.indexOf('#') > -1); 1096 } 1097 780 1098 /** 781 1099 * <p> … … 793 1111 if (!idCondition.equals(htmlId)) { 794 1112 // check if the id condition would match with ignoring specific characters 795 if ((htmlId != null) && (idCondition.indexOf('#') > -1)) {1113 if ((htmlId != null) && isPattern()) { 796 1114 // first of all, the length must match 797 1115 if (idCondition.length() != htmlId.length()) {
Note: See TracChangeset
for help on using the changeset viewer.