// Module : $RCSfile: GUIModel.java,v $
// Version : $Revision: 0.0 $ $Author: pharms $ $Date: 14.08.2012 $
// Project : quest-core-events
// Creation : 2012 by pharms
// Copyright : Patrick Harms, 2012
package de.ugoe.cs.quest.eventcore.guimodel;
import java.util.ArrayList;
import java.util.List;
/**
*
* The goal of a GUI model is to correctly l
*
*
* @version $Revision: $ $Date: 14.08.2012$
* @author 2012, last modified by $Author: pharms$
*/
public class GUIModel {
/**
*
*/
private TreeNode root = new TreeNode();
/**
*
*/
private List allNodes = new ArrayList();
/**
* TODO: comment
*
* @param currentGUIElementPath
* @return
* @throws GUIModelException
*/
public IGUIElement integratePath(List extends IGUIElementSpec> guiElementPath,
IGUIElementFactory guiElementFactory)
throws GUIModelException
{
List remainingPath = new ArrayList();
for (IGUIElementSpec spec : guiElementPath)
{
remainingPath.add(spec);
}
return integratePath(root, remainingPath, guiElementFactory);
}
/**
* TODO: comment
*
* @param root
* @return
*/
public List getChildren(IGUIElement guiElement) {
for (TreeNode node : allNodes) {
if (node.guiElement.equals(guiElement)) {
List result = new ArrayList();
if (node.children != null) {
for (TreeNode child : node.children) {
result.add(child.guiElement);
}
}
return result;
}
}
return null;
}
/**
* TODO: comment
*
* @return
*/
public List getRootElements() {
List roots = new ArrayList();
for (TreeNode rootChild : root.children) {
roots.add(rootChild.guiElement);
}
return roots;
}
/**
*
* TODO: comment
*
*
* @param root2
* @param guiElementPath
* @param guiElementFactory
* @return
* @throws GUIModelException
*/
private IGUIElement integratePath(TreeNode parentNode,
List extends IGUIElementSpec> remainingPath,
IGUIElementFactory guiElementFactory)
throws GUIModelException
{
IGUIElementSpec specToIntegrateElementFor = remainingPath.remove(0);
List matchingChildren = new ArrayList();
int maximumSimilarity = 0;
if (parentNode.children != null) {
for (TreeNode child : parentNode.children) {
int similarityLevel = getSimilarityLevel
(specToIntegrateElementFor, child.guiElement.getSpecification());
if (similarityLevel >= maximumSimilarity) {
if (maximumSimilarity == 100) {
throw new GUIModelException
("several children of gui element " + parentNode.guiElement +
" pretend to fully match specification " + specToIntegrateElementFor);
}
if (maximumSimilarity != similarityLevel) {
matchingChildren.clear();
maximumSimilarity = similarityLevel;
}
matchingChildren.add(child);
}
}
}
// we do not see something as matching if the similarity level is below 80%
if (maximumSimilarity < 80) {
matchingChildren.clear();
}
// if we get here, the corresponding path does not exist yet. So create it
if (matchingChildren.size() == 0) {
matchingChildren.add
(parentNode.addChild
(guiElementFactory.instantiateGUIElement(specToIntegrateElementFor)));
}
else if (matchingChildren.size() > 1) {
throw new GUIModelException
("several children of gui element " + parentNode.guiElement +
" match the specification " + specToIntegrateElementFor + " at the same level. " +
"Can not decide which is the right one.");
}
if (remainingPath.size() > 0) {
return integratePath(matchingChildren.get(0), remainingPath, guiElementFactory);
}
else {
return matchingChildren.get(0).guiElement;
}
}
/**
*
* TODO: comment
*
*
* @param spec1
* @param spec2
* @return
* @throws GUIModelException
*/
private int getSimilarityLevel(IGUIElementSpec spec1, IGUIElementSpec spec2)
throws GUIModelException
{
if (spec1 == spec2) {
return 100;
}
else if (spec1 != null) {
int level = spec1.getSimilarity(spec2);
if ((level < 0) || (100 < level)) {
throw new GUIModelException("invalid tree node similarity provided (" + level +
"). Must be between 0 and 100.");
}
return level;
}
else {
return 0;
}
}
/**
*
* TODO comment
*
*
* @version $Revision: $ $Date: 17.08.2012$
* @author 2012, last modified by $Author: pharms$
*/
private class TreeNode
{
/** */
private IGUIElement guiElement;
/** */
private List children;
/** */
//private TreeNode parent;
/**
*
* TODO: comment
*
*
* @param guiElement
* @return
*/
private TreeNode addChild(IGUIElement guiElement)
{
if (children == null)
{
children = new ArrayList();
}
TreeNode child = new TreeNode();
child.guiElement = guiElement;
//child.parent = this;
children.add(child);
allNodes.add(child);
return child;
}
}
}