Changeset 1334
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-plugin-html-test/src/test/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDcondenseHTMLGUIModelTest.java
r1286 r1334 168 168 169 169 String[] assertionSpec = 170 { "/server/doc1/html/body/ div",170 { "/server/doc1/html/body/group_common/div", 171 171 "/server/doc1/html/body/group_doc1/div_1", 172 172 "/server/doc1/html/body/group_doc2/div_2" }; … … 207 207 208 208 String[] assertionSpec = 209 { "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/ div_1",210 "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/ div_2",209 { "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_common/div_1", 210 "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_common/div_2", 211 211 "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_doc1/div_3", 212 212 "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_doc1/div_5", 213 213 "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_doc2/div_7", 214 214 "/server/doc1/html/body/div/group_doc1doc2doc3/group_doc1doc2/group_doc2/div_8", 215 "/server/doc1/html/body/div/group_doc1doc2doc3/ div_6",215 "/server/doc1/html/body/div/group_doc1doc2doc3/group_common/div_6", 216 216 "/server/doc1/html/body/div/group_doc1doc5/div_4", 217 "/server/doc1/html/body/div/group_doc3doc5/ div_11",217 "/server/doc1/html/body/div/group_doc3doc5/group_common/div_11", 218 218 "/server/doc1/html/body/div/group_doc3doc5/group_doc3/div_9", 219 219 "/server/doc1/html/body/div/group_doc3doc5/group_doc3/div_10", … … 221 221 "/server/doc1/html/body/div/group_doc4/div_13" }; 222 222 223 assertGUIModel(guiModel, assertionSpec); 224 } 225 226 /** 227 * <p> 228 * TODO: comment 229 * </p> 223 guiModel.dump(System.out, "UTF-8"); 224 assertGUIModel(guiModel, assertionSpec); 225 } 226 227 /** 230 228 * 231 * @param guiSpec232 * @return233 * @throws GUIModelException234 * @throws IllegalArgumentException235 229 */ 236 230 private GUIModel generateGUIModel(String[] guiSpec) … … 301 295 302 296 /** 303 * <p> 304 * TODO: comment 305 * </p> 306 * 297 * 307 298 */ 308 299 private void executeCommand() { … … 316 307 317 308 /** 318 * <p>319 * TODO: comment320 * </p>321 309 * 322 * @param guiModel323 * @param assertionSpec324 310 */ 325 311 private void assertGUIModel(GUIModel guiModel, String[] assertionSpec) { … … 338 324 339 325 /** 340 * <p>341 * TODO: comment342 * </p>343 326 * 344 * @param traverser345 * @param paths346 327 */ 347 328 private void assertPaths(Traverser traverser, String path, List<String> paths) { … … 363 344 364 345 /** 365 * <p>366 * TODO: comment367 * </p>368 346 * 369 * @param childElement370 * @return371 347 */ 372 348 private String getPathElement(IGUIElement childElement) { -
trunk/autoquest-plugin-html/src/main/java/de/ugoe/cs/autoquest/plugin/html/commands/CMDcondenseHTMLGUIModel.java
r1286 r1334 15 15 package de.ugoe.cs.autoquest.plugin.html.commands; 16 16 17 import java.io.PrintStream; 17 18 import java.util.Arrays; 18 19 import java.util.Comparator; … … 73 74 * \-- html 74 75 * \-- body 75 * |-- div (id = menu) 76 * | \-- ... 76 * |-- group (common) 77 * | |-- div (id = menu) 78 * | | \-- ... 79 * | \-- div (id = footer) 80 * | \-- ... 77 81 * |-- group (document1) 78 82 * | \-- div (id = textcontent) … … 81 85 * | \-- div (id = imagecontent) 82 86 * | \-- ... 83 * \-- div (id = footer)84 * \-- ...85 87 * </pre> 86 88 * This now allows the menu and the footer to be treated as identical over several pages. … … 146 148 GUIElementsCluster rootCluster = getSimilarElementClusterHierarchy(server, model); 147 149 148 //rootCluster.dump(System.out, "");149 150 Console.traceln(Level.FINE, " merging GUI elements in same clusters and creating groups");151 mergeGUIElementsAccordingToClusters(rootCluster, model, "");150 rootCluster.dump(System.out, ""); 151 152 Console.traceln(Level.FINE, "grouping GUI elements according to clusters"); 153 groupGUIElementsAccordingToClusters(rootCluster, model, ""); 152 154 153 155 //model.dump(System.out, "UTF-8"); … … 157 159 /** 158 160 * <p> 159 * determines clusters of similar GUI elements being children of the provided parent. For this,160 * the method creates a cluster containing all children of the provided parentas similar161 * GUI elements. Usually, these are all documents on the s ame server. It then initiates162 * creatingthe cluster hierarchy by calling the recursive method161 * determines clusters of similar GUI elements being children of the provided server. For this, 162 * the method creates a cluster containing all children of the provided server as similar 163 * GUI elements. Usually, these are all documents on the server. It then initiates creating 164 * the cluster hierarchy by calling the recursive method 163 165 * {@link #addChildClusters(GUIElementsCluster, GUIModel, String)}. 164 166 * </p> 165 167 * 166 * @param parent the parent GUI element for which the clusters of similar children shall be 167 * determined (usually an HTML server) 168 * @param server the server for which the clusters of similar children shall be determined 168 169 * @param model the GUI model required for identifying children and sub children 169 170 * 170 * @return a list of GUI element clusters of the children.171 */ 172 private GUIElementsCluster getSimilarElementClusterHierarchy( IGUIElement parent, GUIModel model)171 * @return a GUI element cluster representing the server. 172 */ 173 private GUIElementsCluster getSimilarElementClusterHierarchy(HTMLServer server, GUIModel model) 173 174 { 174 175 GUIElementsCluster cluster = new GUIElementsCluster(); 175 176 176 List<IGUIElement> children = model.getChildren( parent);177 List<IGUIElement> children = model.getChildren(server); 177 178 178 179 SimilarGUIElements similarGuiElements = new SimilarGUIElements(); 179 180 180 181 for (IGUIElement child : children) { 181 // when starting with the root, the cluster parent is the child itself 182 // when starting with the root, the cluster parent is the child itself, i.e. the 183 // document. We expect all documents to be similar. 182 184 similarGuiElements.add(new SimilarGUIElement(child, child)); 183 185 } 184 186 185 187 cluster.addSimilarGUIElements(similarGuiElements); 188 189 // create the cluster structure 186 190 addChildClusters(cluster, model, ""); 187 191 … … 209 213 } 210 214 211 createClusterHierachies(cluster .childClusters);215 createClusterHierachies(cluster); 212 216 } 213 217 … … 216 220 * for a set of similar GUI elements, it identifies similar children and clusters them. For 217 221 * each identified cluster, it adds a new child cluster to the provided parent cluster. GUI 218 * elements having no further children are added to a default cluster.222 * elements having no further children are ignored. 219 223 * </p> 220 224 * … … 235 239 for (IGUIElement child : children) { 236 240 addToClusterOfSimilarElements 237 (child, similarGuiElement.mainClusterParent, parentCluster .childClusters,241 (child, similarGuiElement.mainClusterParent, parentCluster, 238 242 similarGuiElements, model); 239 243 } 240 244 } 241 else { 242 // search for a default cluster to add all elements to, which have no children 243 GUIElementsCluster defaultCluster = null; 244 245 for (GUIElementsCluster candidate : parentCluster.childClusters) { 246 if (candidate.similarChildrenGUIElements.size() == 0) { 247 defaultCluster = candidate; 248 break; 249 } 250 } 251 252 if (defaultCluster == null) { 253 defaultCluster = new GUIElementsCluster(); 254 parentCluster.addChildCluster(defaultCluster); 255 } 256 257 defaultCluster.clusteredGUIElements.add(similarGuiElement); 258 } 259 } 260 } 261 262 /** 263 * <p> 264 * for a given GUI element, searches the list of known clusters and adds the GUI element to 265 * the cluster, if the cluster already contains a similar GUI element. If not, a new cluster is 266 * created and added to the list of known clusters. 245 } 246 } 247 248 /** 249 * <p> 250 * for a given GUI element, searches the list of child clusters of the parent cluster and adds 251 * the GUI element to the cluster, if the cluster already contains a similar GUI element. If 252 * not, a new cluster is created and added to the list of known clusters. 267 253 * </p> 268 254 * 269 * @param child the child for which the cluster is to be determined 270 * @param clusterParent the GUI element for 271 * @param parents 272 * @param model 273 */ 274 private void addToClusterOfSimilarElements(IGUIElement child, 275 IGUIElement clusterParent, 276 List<GUIElementsCluster> knownClusters, 277 SimilarGUIElements similarGuiElements, 278 GUIModel model) 255 * @param child the child for which the cluster is to be determined 256 * @param clusterParent the root GUI element of the parent cluster 257 * @param parentCluster the parent cluster whose child clusters shall be filled 258 * @param similarGuiElements the similar GUI elements currently matched to each other 259 * @param model the GUI model required to determine children of GUI elements 260 */ 261 private void addToClusterOfSimilarElements(IGUIElement child, 262 IGUIElement clusterParent, 263 GUIElementsCluster parentCluster, 264 SimilarGUIElements similarGuiElements, 265 GUIModel model) 279 266 { 280 267 SimilarGUIElements matchingParents = new SimilarGUIElements(); … … 294 281 GUIElementsCluster cluster = null; 295 282 296 for (GUIElementsCluster clusterCandidate : knownClusters) {283 for (GUIElementsCluster clusterCandidate : parentCluster.childClusters) { 297 284 if (clusterCandidate.isClusterOf(matchingParents)) { 298 285 cluster = clusterCandidate; … … 303 290 if (cluster == null) { 304 291 cluster = new GUIElementsCluster(); 305 knownClusters.add(cluster);292 parentCluster.addChildCluster(cluster); 306 293 cluster.setClusteredGUIElements(matchingParents); 307 294 } … … 315 302 * each other. This is, e.g., the case if one cluster contains all elements being part of 316 303 * document1 and document2 and a further cluster contains all elements of document 1 only. In 317 * this case, the cluster of document1 is added as a child to the other cluster. 304 * this case, the cluster of document1 is added as a child to the other cluster. In this case 305 * it is furthermore required, that a common cluster as child of the document1/document2 cluster 306 * is created carrying the common GUI elements for both clusters. 318 307 * </p> 319 308 * 320 * @param clusters the clusters, for which the child hierarchies shall be created321 * (in-out parameter, as it is changed)322 */ 323 private void createClusterHierachies( List<GUIElementsCluster> clusters) {324 GUIElementsCluster[] clustersCopy = 325 clusters.toArray(new GUIElementsCluster[clusters.size()]);309 * @param parentCluster the parent cluster for whose children the child hierarchies shall be 310 * created (in-out parameter, as it is changed) 311 */ 312 private void createClusterHierachies(GUIElementsCluster parentCluster) { 313 GUIElementsCluster[] clustersCopy = parentCluster.childClusters.toArray 314 (new GUIElementsCluster[parentCluster.childClusters.size()]); 326 315 327 316 // sort the array starting with the shortest cluster and ending with the longest … … 333 322 }); 334 323 335 List<GUIElementsCluster> subClustersToHandle = new LinkedList<GUIElementsCluster>();324 Set<GUIElementsCluster> subClustersToHandle = new HashSet<GUIElementsCluster>(); 336 325 337 326 // now add smaller clusters to larger ones, if they are parents … … 346 335 subClustersToHandle.add(clustersCopy[j]); 347 336 348 for (int k = 0; k < clusters.size(); k++) {349 if ( clusters.get(k) == potentialChild) {350 clusters.remove(k);337 for (int k = 0; k < parentCluster.childClusters.size(); k++) { 338 if (parentCluster.childClusters.get(k) == potentialChild) { 339 parentCluster.childClusters.remove(k); 351 340 break; 352 341 } … … 358 347 } 359 348 360 // finally, for all subclusters that were changed, ensure the creation of their internal 361 // hierarchy as well 362 for (GUIElementsCluster subClusterToHandle : subClustersToHandle) { 363 createClusterHierachies(subClusterToHandle.childClusters); 364 } 365 } 366 367 /** 368 * <p> 369 * called for each cluster to merge similar GUI elements depending on the clusters and to 370 * create GUI element groups if required. Calls itself recursively to be also applied on 371 * child clusters. 372 * </p> 373 * 374 * @param cluster the cluster of which the similar children shall be merged 375 * @param model the model to be adapted through the merge 376 */ 377 private void mergeGUIElementsAccordingToClusters(GUIElementsCluster cluster, 378 GUIModel model, 379 String indent) 380 { 381 //System.out.println(indent + "handling " + cluster); 382 383 for (SimilarGUIElements similarGUIElements : cluster.similarChildrenGUIElements) { 384 mergeGUIElements(similarGUIElements, model, indent + " "); 385 } 386 387 if (cluster.childClusters.size() > 0) { 388 //System.out.println(indent + " handling child clusters"); 389 390 for (GUIElementsCluster childCluster : cluster.childClusters) { 391 if (cluster.isDefault() || cluster.clusterParentsMatch(childCluster)) { 392 // for default cluster or children not creating subgroups, just traverse the 393 // cluster hierarchy 394 mergeGUIElementsAccordingToClusters(childCluster, model, indent + " "); 395 } 396 else { 397 createClusterGroup(childCluster, model, indent + " "); 398 } 349 if (subClustersToHandle.size() > 0) { 350 // finally, for all subclusters that were changed, ensure the creation of their internal 351 // hierarchy as well 352 for (GUIElementsCluster subClusterToHandle : subClustersToHandle) { 353 // we need a dedicated common cluster --> add it 354 createClusterHierachies(subClusterToHandle); 355 356 GUIElementsCluster commonCluster = new GUIElementsCluster(); 357 //commonCluster.setClusteredGUIElements(subClusterToHandle.clusteredGUIElements); 358 commonCluster.similarChildrenGUIElements.addAll 359 (subClusterToHandle.similarChildrenGUIElements); 360 361 subClusterToHandle.similarChildrenGUIElements.clear(); 362 subClusterToHandle.childClusters.add(0, commonCluster); 399 363 } 400 364 } … … 416 380 417 381 while (similarGUIElements.size() > 1) { 418 //System.out.println(indent + "merging " + mergeResult + " and " +419 //similarGUIElements.get(1).similarGUIElement);382 System.out.println(indent + "merging " + mergeResult + " and " + 383 similarGUIElements.get(1).similarGUIElement); 420 384 mergeResult = model.mergeGUIElements 421 385 (mergeResult, similarGUIElements.remove(1).similarGUIElement, false); … … 432 396 * @param model the model to be used for creating the groups 433 397 */ 434 private void createClusterGroup(GUIElementsCluster cluster, GUIModel model, String indent) { 435 //System.out.println(indent + "creating group for " + cluster); 436 398 private void groupGUIElementsAccordingToClusters(GUIElementsCluster cluster, 399 GUIModel model, 400 String indent) 401 { 402 System.out.println(indent + "handling " + cluster); 403 437 404 List<IGUIElement> guiElementsToGroup = new LinkedList<IGUIElement>(); 438 405 … … 442 409 } 443 410 444 //System.out.println(indent + " iterating child clusters of " + cluster); 411 List<IGUIElement> subgroups = new LinkedList<IGUIElement>(); 412 413 414 System.out.println(indent + "iterating child clusters of " + cluster); 445 415 for (GUIElementsCluster childCluster : cluster.childClusters) { 446 if (cluster.isDefault() || cluster.clusterParentsMatch(childCluster)) { 447 // for default cluster or children not creating subgroups, just traverse the 448 // cluster hierarchy 449 mergeGUIElementsAccordingToClusters(childCluster, model, indent + " "); 450 } 451 else { 452 createClusterGroup(childCluster, model, indent + " "); 453 } 454 455 if (childCluster.getGroup() != null) { 456 if (cluster.isSubCluster(childCluster)) { 457 guiElementsToGroup.add(childCluster.getGroup()); 458 } 459 else { 460 guiElementsToGroup.add(childCluster.getGroup().getParent()); 461 } 462 } 463 } 464 465 //System.out.println(indent + "grouping: " + guiElementsToGroup); 466 IGUIElement group = model.groupGUIElements(guiElementsToGroup, getGroupName(cluster)); 467 //System.out.println(indent + " created group for " + cluster + ": " + group); 468 469 cluster.setGroup(group); 416 groupGUIElementsAccordingToClusters(childCluster, model, indent + " "); 417 418 if (cluster.childClusters.size() > 1) { 419 List<IGUIElement> childGuiElemsToGroup = new LinkedList<IGUIElement>(); 420 421 for (SimilarGUIElements similarGUIElems : childCluster.similarChildrenGUIElements) { 422 childGuiElemsToGroup.addAll(similarGUIElems.toGUIElementList()); 423 } 424 425 for (GUIElementsCluster subsubcluster : childCluster.childClusters) { 426 if (subsubcluster.getGroup() != null) { 427 childGuiElemsToGroup.add(subsubcluster.getGroup()); 428 } 429 } 430 431 if (childGuiElemsToGroup.size() > 0) { 432 System.out.println(indent + " grouping: " + childGuiElemsToGroup); 433 IGUIElement group = model.groupGUIElements 434 (childGuiElemsToGroup, getGroupName(childCluster)); 435 System.out.println 436 (indent + " created group for " + childCluster + ": " + group); 437 438 if (group != null) { 439 childCluster.setGroup(group); 440 if (cluster.isSubCluster(childCluster)) { 441 subgroups.add(childCluster.getGroup()); 442 } 443 else { 444 subgroups.add(childCluster.getGroup().getParent()); 445 } 446 } 447 } 448 } 449 450 System.out.println(); 451 } 452 470 453 } 471 454 … … 484 467 name.append("group_"); 485 468 486 for (SimilarGUIElement guiElement : cluster.clusteredGUIElements) { 487 if (guiElement.mainClusterParent instanceof HTMLDocument) { 488 name.append(((HTMLDocument) guiElement.mainClusterParent).getPath()); 489 } 490 else { 491 name.append(guiElement.mainClusterParent.getStringIdentifier()); 492 } 469 if (cluster.clusteredGUIElements.size() > 0) { 470 for (SimilarGUIElement guiElement : cluster.clusteredGUIElements) { 471 if (guiElement.mainClusterParent instanceof HTMLDocument) { 472 name.append(((HTMLDocument) guiElement.mainClusterParent).getPath()); 473 } 474 else { 475 name.append(guiElement.mainClusterParent.getStringIdentifier()); 476 } 477 } 478 } 479 else { 480 name.append("common"); 493 481 } 494 482 … … 557 545 /** 558 546 * <p> 559 * checks, if the main cluster parents, i.e., the documents of this and the provided cluster560 * match561 * </p>562 *563 * @param other the other cluster of which the main cluster parents shall be compared to564 * this565 *566 * @return true if they match, false else567 */568 private boolean clusterParentsMatch(GUIElementsCluster other) {569 // cluster parent may already be merged and therefore equals --> use system identity570 // hash code for uniqueness571 Set<Integer> mainClusterParents1 = new HashSet<Integer>();572 for (SimilarGUIElement clusteredElem1 : clusteredGUIElements) {573 mainClusterParents1.add(System.identityHashCode(clusteredElem1.mainClusterParent));574 }575 576 Set<Integer> mainClusterParents2 = new HashSet<Integer>();577 for (SimilarGUIElement clusteredElem2 : other.clusteredGUIElements) {578 mainClusterParents2.add(System.identityHashCode(clusteredElem2.mainClusterParent));579 }580 581 return mainClusterParents1.equals(mainClusterParents2);582 }583 584 /**585 * <p>586 * returns true, if this cluster is a default cluster587 * </p>588 *589 * @return590 */591 public boolean isDefault() {592 return clusteredGUIElements.size() <= 0;593 }594 595 /**596 * <p>597 547 * sets the GUI element group created for this cluster 598 548 * </p> … … 710 660 711 661 if (clusteredGUIElements.size() > 0) { 662 ret.append(clusteredGUIElements.get(0).similarGUIElement); 663 ret.append(" ["); 664 665 int length = ret.length(); 712 666 for (SimilarGUIElement similarGUIElement : clusteredGUIElements) { 713 if (ret.length() > "cluster(".length()) {667 if (ret.length() > length) { 714 668 ret.append(", "); 715 669 } 716 670 717 ret.append(similarGUIElement); 718 } 671 ret.append(similarGUIElement.mainClusterParent); 672 } 673 674 ret.append(']'); 719 675 } 720 676 else { … … 732 688 * </p> 733 689 */ 734 // private void dump(PrintStream out, String indent) { 735 // out.print(indent); 736 // out.print(getName()); 737 // out.print(" { "); 738 // 739 // if (similarChildrenGUIElements.size() > 0) { 740 // out.println(); 741 // out.print(indent); 742 // out.println(" similar children {"); 743 // 744 // for (SimilarGUIElements similarGuiElements : similarChildrenGUIElements) { 745 // similarGuiElements.dump(out, indent + " "); 746 // } 747 // 748 // out.print(indent); 749 // out.println(" }"); 750 // 751 // if (childClusters.size() > 0) { 752 // out.print(indent); 753 // out.println(" child clusters {"); 754 // 755 // for (GUIElementsCluster childCluster : childClusters) { 756 // childCluster.dump(out, indent + " "); 757 // } 758 // 759 // out.print(indent); 760 // out.println(" }"); 761 // } 762 // 763 // out.print(indent); 764 // } 765 // else if (clusteredGUIElements.size() > 0) { 766 // out.println(); 767 // out.print(indent); 768 // out.println(" clustered GUIElements {"); 769 // 770 // for (SimilarGUIElement clusteredGUIElement : clusteredGUIElements) { 771 // clusteredGUIElement.dump(out, indent + " "); 772 // } 773 // 774 // out.print(indent); 775 // out.println(" }"); 776 // out.print(indent); 777 // } 778 // 779 // out.println("}"); 780 // } 690 private void dump(PrintStream out, String indent) { 691 out.print(indent); 692 out.print(getName()); 693 out.println(" { "); 694 695 if (clusteredGUIElements.size() > 0) { 696 out.print(indent); 697 out.println(" clustered GUIElements {"); 698 699 for (SimilarGUIElement clusteredGUIElement : clusteredGUIElements) { 700 clusteredGUIElement.dump(out, indent + " "); 701 } 702 703 out.print(indent); 704 out.println(" }"); 705 } 706 707 if (similarChildrenGUIElements.size() > 0) { 708 out.print(indent); 709 out.println(" similar children {"); 710 711 for (SimilarGUIElements similarGuiElements : similarChildrenGUIElements) { 712 similarGuiElements.dump(out, indent + " "); 713 } 714 715 out.print(indent); 716 out.println(" }"); 717 } 718 719 if (childClusters.size() > 0) { 720 out.print(indent); 721 out.println(" child clusters {"); 722 723 for (GUIElementsCluster childCluster : childClusters) { 724 childCluster.dump(out, indent + " "); 725 } 726 727 out.print(indent); 728 out.println(" }"); 729 } 730 731 out.print(indent); 732 out.println("}"); 733 } 781 734 782 735 } … … 834 787 * </p> 835 788 */ 836 //private void dump(PrintStream out, String indent) {837 //out.print(indent);838 //out.print("{ ");839 //840 //for (int i = 0; i < super.size(); i++) {841 //if (i > 0) {842 //out.print(", ");843 //}844 //out.print(super.get(i));845 //}846 //847 //out.println(" }");848 //}789 private void dump(PrintStream out, String indent) { 790 out.print(indent); 791 out.print("{ "); 792 793 for (int i = 0; i < super.size(); i++) { 794 if (i > 0) { 795 out.print(", "); 796 } 797 out.print(super.get(i)); 798 } 799 800 out.println(" }"); 801 } 849 802 } 850 803 … … 886 839 * </p> 887 840 */ 888 //private void dump(PrintStream out, String indent) {889 //out.print(indent);890 //out.println(this);891 //}841 private void dump(PrintStream out, String indent) { 842 out.print(indent); 843 out.println(this); 844 } 892 845 893 846 /* (non-Javadoc)
Note: See TracChangeset
for help on using the changeset viewer.