Ignore:
Timestamp:
08/17/12 16:15:24 (12 years ago)
Author:
pharms
Message:
  • adaptations for ensuring, that GUI event targets can be created as singletons during parsing.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/GUIModel.java

    r545 r576  
    88 
    99import java.util.ArrayList; 
    10 import java.util.Collection; 
    11 import java.util.HashMap; 
    1210import java.util.List; 
    13 import java.util.Map; 
    1411 
    1512/** 
    16  * TODO comment 
     13 * <p> 
     14 * The goal of a GUI model is to correctly l 
     15 * </p> 
    1716 *  
    1817 * @version $Revision: $ $Date: 14.08.2012$ 
    1918 * @author 2012, last modified by $Author: pharms$ 
    2019 */ 
    21 public class GUIModel<T extends IGUIElement> { 
     20public class GUIModel { 
    2221     
    2322    /** 
    2423     *  
    2524     */ 
    26     private Collection<T> guiElements = new ArrayList<T>(); 
    27  
     25    private TreeNode root = new TreeNode(); 
     26     
    2827    /** 
    2928     *  
    3029     */ 
    31     private Map<T, List<T>> childRelations = new HashMap<T, List<T>>(); 
     30    private List<TreeNode> allNodes = new ArrayList<TreeNode>(); 
    3231 
    3332    /** 
     
    3837     * @throws GUIModelException  
    3938     */ 
    40     public T checkAndIntegratePath(List<T> guiElementPath) throws GUIModelException { 
    41         T existingGuiElement = check(guiElementPath); 
    42          
    43         if (existingGuiElement == null) { 
    44             T terminalGuiElement = null; 
    45             T child = null; 
    46             boolean doBreak = false; 
    47             for (int i = guiElementPath.size() - 1; ((i >= 0) && (!doBreak)); i--) { 
    48                 T newElement = guiElementPath.get(i); 
    49                 existingGuiElement = null; 
     39    public IGUIElement integratePath(List<? extends IGUIElementSpec> guiElementPath, 
     40                                     IGUIElementFactory              guiElementFactory) 
     41        throws GUIModelException 
     42    { 
     43        List<IGUIElementSpec> remainingPath = new ArrayList<IGUIElementSpec>(); 
     44         
     45        for (IGUIElementSpec spec : guiElementPath) 
     46        { 
     47            remainingPath.add(spec); 
     48        } 
     49         
     50        return integratePath(root, remainingPath, guiElementFactory); 
     51    } 
     52 
     53    /** 
     54     * TODO: comment 
     55     * 
     56     * @param root 
     57     * @return 
     58     */ 
     59    public List<IGUIElement> getChildren(IGUIElement guiElement) { 
     60        for (TreeNode node : allNodes) { 
     61            if (node.guiElement.equals(guiElement)) { 
     62                List<IGUIElement> result = new ArrayList<IGUIElement>(); 
    5063                 
    51                 for (T candidate : guiElements) { 
    52                     if (candidate.equals(newElement)) { 
    53                         existingGuiElement = candidate; 
    54                         break; 
     64                if (node.children != null) { 
     65                    for (TreeNode child : node.children) { 
     66                      result.add(child.guiElement); 
    5567                    } 
    5668                } 
    5769                 
    58                 // element not yet contained in model. Add it. 
    59                 if (existingGuiElement == null) 
    60                 { 
    61                     guiElements.add(newElement); 
    62                     existingGuiElement = newElement; 
    63                 } 
    64                 else 
    65                 { 
    66                     doBreak = true; 
    67                 } 
     70                return result; 
     71            } 
     72        } 
     73         
     74        return null; 
     75    } 
     76 
     77    /** 
     78     * TODO: comment 
     79     * 
     80     * @return 
     81     */ 
     82    public List<IGUIElement> getRootElements() { 
     83        List<IGUIElement> roots = new ArrayList<IGUIElement>(); 
     84        for (TreeNode rootChild : root.children) { 
     85            roots.add(rootChild.guiElement); 
     86        } 
     87        return roots; 
     88    } 
     89 
     90    /** 
     91     * <p> 
     92     * TODO: comment 
     93     * </p> 
     94     * 
     95     * @param root2 
     96     * @param guiElementPath 
     97     * @param guiElementFactory 
     98     * @return 
     99     * @throws GUIModelException  
     100     */ 
     101    private IGUIElement integratePath(TreeNode                        parentNode, 
     102                                      List<? extends IGUIElementSpec> remainingPath, 
     103                                      IGUIElementFactory              guiElementFactory) 
     104        throws GUIModelException 
     105    { 
     106        IGUIElementSpec specToIntegrateElementFor = remainingPath.remove(0); 
     107         
     108        List<TreeNode> matchingChildren = new ArrayList<TreeNode>(); 
     109        int maximumSimilarity = 0; 
     110         
     111        if (parentNode.children != null) { 
     112            for (TreeNode child : parentNode.children) { 
     113                int similarityLevel = getSimilarityLevel 
     114                    (specToIntegrateElementFor, child.guiElement.getSpecification()); 
    68115                 
    69                 if (terminalGuiElement == null) { 
    70                     terminalGuiElement = existingGuiElement; 
    71                 } 
    72                  
    73                 if (child != null) { 
    74                     List<T> children = childRelations.get(existingGuiElement); 
    75                     if (children == null) { 
    76                         children = new ArrayList<T>(); 
    77                         childRelations.put(existingGuiElement, children); 
    78                     } 
    79                     children.add(child); 
    80                 } 
    81                 child = existingGuiElement; 
    82             } 
    83              
    84             existingGuiElement = terminalGuiElement; 
    85         } 
    86          
    87         return existingGuiElement; 
    88     } 
    89  
    90     /** 
    91      * TODO: comment 
    92      * 
    93      * @param root 
    94      * @return 
    95      */ 
    96     public List<T> getChildren(T guiElement) { 
    97         return childRelations.get(guiElement); 
    98     } 
    99  
    100     /** 
    101      * TODO: comment 
    102      * 
    103      * @return 
    104      */ 
    105     public List<T> getRootElements() { 
    106         List<T> roots = new ArrayList<T>(); 
    107         for (T guiElement : guiElements) { 
    108             if (guiElement.getParent() == null) { 
    109                 roots.add(guiElement); 
    110             } 
    111         } 
    112         return roots; 
    113     } 
    114  
    115     /** 
    116      * TODO: comment 
    117      * 
    118      * @param guiElementPath 
    119      * @throws GUIModelException  
    120      */ 
    121     private T check(List<T> guiElementPath) throws GUIModelException { 
    122         T guiElementInModel = null; 
    123          
    124         for (int i = 0; i < guiElementPath.size(); i++) { 
    125             guiElementInModel = null; 
    126              
    127             T newElement = guiElementPath.get(i); 
    128             T newParent = (i > 0 ? guiElementPath.get(i - 1) : null); 
    129              
    130             if ((newElement.getParent() != null) && 
    131                 (!newElement.getParent().equals(newParent))) 
    132             { 
    133                 throw new GUIModelException 
    134                     ("new GUI element " + newElement + " denotes a parent element (" + 
    135                      newElement.getParent() + ") which is not identical to the parent element " + 
    136                      "denoted by the element path (" + newParent + ")"); 
    137             } 
    138              
    139             for (T existingElement : guiElements) { 
    140                 if (existingElement.equals(newElement)) { 
    141                     if (guiElementInModel != null) { 
     116                if (similarityLevel >= maximumSimilarity) { 
     117                    if (maximumSimilarity == 100) { 
    142118                        throw new GUIModelException 
    143                             ("several GUI elements already existing in the model pretend to " + 
    144                              "match the new element " + newElement); 
     119                          ("several children of gui element " + parentNode.guiElement + 
     120                           " pretend to fully match specification " + specToIntegrateElementFor); 
    145121                    } 
    146122                     
    147                     if ((existingElement.getParent() != newParent) && 
    148                         ((existingElement.getParent() != null) && 
    149                          (!existingElement.getParent().equals(newParent)))) 
    150                     { 
    151                         throw new GUIModelException 
    152                             ("the new path denotes the GUI element " + newElement + 
    153                              " with parent " + newElement.getParent() + " that already exists in " + 
    154                              "the model with a distinct parent element (" + 
    155                              existingElement.getParent() + ")"); 
     123                    if (maximumSimilarity != similarityLevel) { 
     124                        matchingChildren.clear(); 
     125                        maximumSimilarity = similarityLevel; 
    156126                    } 
    157127                     
    158                     guiElementInModel = existingElement; 
     128                    matchingChildren.add(child); 
    159129                } 
    160130            } 
    161131        } 
    162132         
    163         return guiElementInModel; 
    164     } 
    165  
     133        // we do not see something as matching if the similarity level is below 80% 
     134        if (maximumSimilarity < 80) { 
     135            matchingChildren.clear(); 
     136        } 
     137         
     138        // if we get here, the corresponding path does not exist yet. So create it 
     139        if (matchingChildren.size() == 0) { 
     140            matchingChildren.add 
     141                (parentNode.addChild 
     142                     (guiElementFactory.instantiateGUIElement(specToIntegrateElementFor))); 
     143        } 
     144        else if (matchingChildren.size() > 1) { 
     145            throw new GUIModelException 
     146              ("several children of gui element " + parentNode.guiElement + 
     147               " match the specification " + specToIntegrateElementFor + " at the same level. " + 
     148               "Can not decide which is the right one."); 
     149        } 
     150         
     151        if (remainingPath.size() > 0) { 
     152            return integratePath(matchingChildren.get(0), remainingPath, guiElementFactory); 
     153        } 
     154        else { 
     155            return matchingChildren.get(0).guiElement; 
     156        } 
     157    } 
     158 
     159    /** 
     160     * <p> 
     161     * TODO: comment 
     162     * </p> 
     163     * 
     164     * @param spec1 
     165     * @param spec2 
     166     * @return 
     167     * @throws GUIModelException  
     168     */ 
     169    private int getSimilarityLevel(IGUIElementSpec spec1, IGUIElementSpec spec2) 
     170        throws GUIModelException 
     171    { 
     172        if (spec1 == spec2) { 
     173            return 100; 
     174        } 
     175        else if (spec1 != null) { 
     176            int level = spec1.getSimilarity(spec2); 
     177             
     178            if ((level < 0) || (100 < level)) { 
     179               throw new GUIModelException("invalid tree node similarity provided (" + level + 
     180                                           "). Must be between 0 and 100.");  
     181            } 
     182             
     183            return level; 
     184        } 
     185        else { 
     186            return 0; 
     187        } 
     188    } 
     189 
     190    /** 
     191     * <p> 
     192     * TODO comment 
     193     * </p> 
     194     *  
     195     * @version $Revision: $ $Date: 17.08.2012$ 
     196     * @author 2012, last modified by $Author: pharms$ 
     197     */ 
     198    private class TreeNode 
     199    { 
     200        /** */ 
     201        private IGUIElement guiElement; 
     202         
     203        /** */ 
     204        private List<TreeNode> children; 
     205         
     206        /** */ 
     207        //private TreeNode parent; 
     208         
     209        /** 
     210         * <p> 
     211         * TODO: comment 
     212         * </p> 
     213         * 
     214         * @param guiElement 
     215         * @return 
     216         */ 
     217        private TreeNode addChild(IGUIElement guiElement) 
     218        { 
     219            if (children == null) 
     220            { 
     221                children = new ArrayList<TreeNode>(); 
     222            } 
     223             
     224            TreeNode child = new TreeNode(); 
     225            child.guiElement = guiElement; 
     226            //child.parent = this; 
     227            children.add(child); 
     228             
     229            allNodes.add(child); 
     230             
     231            return child; 
     232        } 
     233    } 
    166234} 
Note: See TracChangeset for help on using the changeset viewer.