source: trunk/autoquest-core-usability/src/main/java/de/ugoe/cs/autoquest/usability/RuleUtils.java @ 1918

Last change on this file since 1918 was 1918, checked in by pharms, 9 years ago
  • extension with further smell detections
  • may not fully work. But Hudson is more happy because compile errors should be gone
File size: 9.7 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.usability;
16
17import java.util.Collection;
18import java.util.HashMap;
19import java.util.Iterator;
20import java.util.LinkedList;
21import java.util.List;
22import java.util.ListIterator;
23import java.util.Map;
24
25import de.ugoe.cs.autoquest.eventcore.guimodel.GUIElementGroup;
26import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
27
28/**
29 * <p>
30 * TODO comment
31 * </p>
32 *
33 * @author Patrick Harms
34 */
35class RuleUtils {
36
37    /**
38     *
39     */
40    static Map<IGUIElement, List<IGUIElement>> getGroups(Collection<IGUIElement> guiElements,
41                                                         int                     maxDistToCommonParent)
42    {
43        Map<IGUIElement, List<IGUIElement>> groups = new HashMap<>();
44        List<IGUIElement> guiElementsToGroup = new LinkedList<>(guiElements);
45        IGUIElement parentToGroup;
46       
47        do {
48            List<LinkedList<IGUIElement>> sortedPaths = new LinkedList<>();
49            List<IGUIElement> commonParents = new LinkedList<>();
50           
51            createSortedPaths
52                (guiElementsToGroup, sortedPaths, commonParents, maxDistToCommonParent);
53
54            // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TEST IMPLEMENTATION
55            // Iterator<LinkedList<IGUIElement>> sortedPathsIt1 = sortedPaths.iterator();
56            // Iterator<IGUIElement> commonParentIt1 = commonParents.iterator();
57            // 
58            // while (commonParentIt1.hasNext()) {
59            //     IGUIElement currentParent = commonParentIt1.next();
60            //     IGUIElement sortedPath = sortedPathsIt1.next().getLast();
61            //     
62            //     System.out.println(toPathString(sortedPath));
63            //     System.out.println(toPathString(currentParent) + "###########");
64            // }
65            // 
66            // System.out.println();
67            // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TEST IMPLEMENTATION
68           
69            parentToGroup = getParentToGroup(commonParents);
70       
71            if (parentToGroup != null) {
72                Iterator<LinkedList<IGUIElement>> sortedPathsIt = sortedPaths.iterator();
73                ListIterator<IGUIElement> commonParentIt = commonParents.listIterator();
74       
75                while (commonParentIt.hasNext()) {
76                    if (!parentToGroup.equals(commonParentIt.next())) {
77                        sortedPathsIt.next();
78                    }
79                    else {
80                        break;
81                    }
82                }
83               
84                List<IGUIElement> groupedGUIElements = new LinkedList<>();
85               
86                // go one backward to ensure, that next will return the first occurrence
87                // of the parent to create the group for.
88                commonParentIt.previous();
89               
90                do {
91                    IGUIElement guiElementToGroup = sortedPathsIt.next().getLast();
92                    groupedGUIElements.add(guiElementToGroup);
93                    guiElementsToGroup.remove(guiElementToGroup);
94                   
95                }
96                while (parentToGroup.equals(commonParentIt.next()));
97               
98                groups.put(parentToGroup, groupedGUIElements);
99               
100                // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> TEST IMPLEMENTATION
101                // System.out.println("group for");
102                // System.out.println(toPathString(parentToGroup));
103                // 
104                // for (IGUIElement element : groupedGUIElements) {
105                //     System.out.println(toPathString(element));
106                // }
107                // 
108                // System.out.println();
109                // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TEST IMPLEMENTATION
110            }
111        }
112        while (parentToGroup != null);
113       
114        return groups;
115    }
116
117    /**
118     *
119     */
120    static String toPathString(IGUIElement element) {
121        IGUIElement parent = element;
122        String result = "";
123       
124        while (parent != null) {
125            if (!(parent instanceof GUIElementGroup)) {
126                result = parent.toString() + "/" + result;
127            }
128            else {
129                result = parent.toString().hashCode() + "/" + result;
130            }
131           
132            parent = parent.getParent();
133        }
134       
135        return result.toString();
136    }
137
138    /**
139     *
140     */
141    private static void createSortedPaths(List<IGUIElement>             guiElements,
142                                          List<LinkedList<IGUIElement>> sortedPaths,
143                                          List<IGUIElement>             commonParents,
144                                          int                           maxDistToCommonParent)
145    {
146        for (IGUIElement guiElement : guiElements) {
147            // create the path
148            LinkedList<IGUIElement> path = new LinkedList<>();
149            IGUIElement parent = guiElement;
150            while (parent != null) {
151                if (!(parent instanceof GUIElementGroup)) {
152                    path.addFirst(parent);
153                }
154               
155                parent = parent.getParent();
156            }
157           
158            // sort it into the list of paths
159            int maxEquality = 0;
160            int maxEqualityPos = 0;
161            int pos = 0;
162           
163            for (List<IGUIElement> candidate : sortedPaths) {
164                int equality = 0;
165                while ((equality < candidate.size()) && (equality < path.size()) &&
166                       (candidate.get(equality).equals(path.get(equality))))
167                {
168                    equality++;
169                }
170               
171                if (equality > maxEquality) {
172                    maxEquality = equality;
173                    maxEqualityPos = pos;
174                }
175               
176                pos++;
177            }
178           
179            sortedPaths.add(maxEqualityPos, path);
180           
181            if ((maxEquality > 0) && ((path.size() - maxEquality) < maxDistToCommonParent)) {
182                commonParents.add(maxEqualityPos, path.get(maxEquality - 1));
183            }
184            else {
185                commonParents.add(maxEqualityPos, null);
186            }
187        }
188    }
189
190    /**
191     *
192     */
193    private static IGUIElement getParentToGroup(List<IGUIElement> commonParents) {
194        Map<IGUIElement, Integer> occurrenceCounts = new HashMap<>();
195        Map<IGUIElement, Integer> depths = new HashMap<>();
196       
197        // get the required information about path lengths and occurrence counts
198        for (IGUIElement commonParent : commonParents) {
199            Integer occurrenceCount = occurrenceCounts.get(commonParent);
200           
201            if (occurrenceCount != null) {
202                occurrenceCounts.put(commonParent, occurrenceCount + 1);
203            }
204            else {
205                occurrenceCounts.put(commonParent, 1);
206            }
207           
208            if (!depths.containsKey(commonParent)) {
209                int depth = 0;
210                IGUIElement parent = commonParent;
211               
212                while (parent != null) {
213                    depth++;
214                    parent = parent.getParent();
215                }
216               
217                depths.put(commonParent, depth);
218            }
219        }
220       
221        IGUIElement elementToGroup = null;
222       
223        // get the GUI element being the parent most often
224        for (IGUIElement commonParent : commonParents) {
225            if (elementToGroup == null) {
226                elementToGroup = commonParent;
227            }
228            else if ((commonParent != null) &&
229                     (!elementToGroup.equals(commonParent)))
230            {
231                int occurrenceCountCandidate = occurrenceCounts.get(commonParent);
232                int depthCandidate = depths.get(commonParent);
233           
234                int occurrenceCountElement = occurrenceCounts.get(elementToGroup);
235                int depthElement = depths.get(elementToGroup);
236               
237                if ((depthCandidate > depthElement) ||
238                    ((depthCandidate == depthElement) &&
239                     (occurrenceCountCandidate > occurrenceCountElement)))
240                {
241                    elementToGroup = commonParent;
242                }
243                else if ((occurrenceCountCandidate == occurrenceCountElement) &&
244                         (depthCandidate == depthElement))
245                {
246                    // in this situation, the order is irrelevant. The GUI elements for which
247                    // both paths were identified as parents are completely different.
248                    // Otherwise, they would have the same parent. But as they are that
249                    // different, they will not occur subsequently in the ordered list
250                    // of GUI elements to group. Hence, we just reuse the one the is currently
251                    // identified as the one to group next.
252                }
253            }
254        }
255       
256        return elementToGroup;
257    }
258
259    /**
260     *
261     */
262    private RuleUtils() {
263        // prevent instantiation
264    }
265}
Note: See TracBrowser for help on using the repository browser.