blob: 39d31a1ae1151b314de0f9eff40065255b6deb04 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and Others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Daisuke SATO - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.fennec.impl;
import java.util.ArrayList;
import org.eclipse.actf.ai.fennec.treemanager.ITreeItem;
import org.eclipse.actf.model.dom.dombycom.INodeEx;
import org.eclipse.actf.util.vocab.DelegationTerms;
import org.eclipse.actf.util.vocab.IEvalTarget;
import org.eclipse.actf.util.vocab.Vocabulary;
import org.eclipse.swt.graphics.Rectangle;
import org.w3c.dom.Node;
public class TreeItemTerms extends DelegationTerms {
public TreeItemTerms(IEvalTarget delegationTarget) {
super(delegationTarget);
}
private boolean isSymbol(char c) {
int type = Character.getType(c);
if (type == Character.OTHER_SYMBOL || type == Character.MODIFIER_SYMBOL || type == Character.MATH_SYMBOL)
return true;
return false;
}
private boolean isSeparator(char c) {
switch (Character.getType(c)) {
case Character.SPACE_SEPARATOR:
case Character.LINE_SEPARATOR:
case Character.PARAGRAPH_SEPARATOR:
case Character.FORMAT:
case Character.CONTROL:
return true;
}
return false;
}
private boolean isPunctuation(char c) {
int type = Character.getType(c);
if (type == Character.CONNECTOR_PUNCTUATION || type == Character.DASH_PUNCTUATION
|| type == Character.START_PUNCTUATION || type == Character.END_PUNCTUATION
|| type == Character.INITIAL_QUOTE_PUNCTUATION || type == Character.FINAL_QUOTE_PUNCTUATION
|| type == Character.OTHER_PUNCTUATION)
return true;
return false;
}
private enum ContentCheckResult {
TRUE, FALSE, UNKNOWN
}
private ContentCheckResult contentCommonCheck(ITreeItem item) {
Object baseNode = item.getBaseNode();
if (baseNode instanceof IEvalTarget) {
if (Vocabulary.hasContent().eval((IEvalTarget) baseNode)) {
return ContentCheckResult.TRUE;
}
}
if (!isVisibleNode(item))
return ContentCheckResult.FALSE;
if (Vocabulary.isSelectOption().eval(item))
return ContentCheckResult.FALSE;
return ContentCheckResult.UNKNOWN;
}
@Override
public boolean hasContent(IEvalTarget target) {
if (!(target instanceof ITreeItem))
return false;
ITreeItem item = (ITreeItem) target;
switch (contentCommonCheck(item)) {
case TRUE:
return true;
case FALSE:
return false;
}
String str = item.getUIString();
if (str.length() == 0)
return false;
return true;
}
@Override
public boolean hasReadingContent(IEvalTarget target) {
if (!(target instanceof ITreeItem))
return false;
ITreeItem item = (ITreeItem) target;
switch (contentCommonCheck(item)) {
case TRUE:
return true;
case FALSE:
return false;
}
String str = item.getUIString();
// remove only punctuation
if (str.length() == 0) return false;
if (Vocabulary.isLink().eval(item))
return true;
for (int i = 0; i < str.length(); i++) {
if (isSeparator(str.charAt(i)) || isPunctuation(str.charAt(i)) //
|| isSymbol(str.charAt(i)))
continue;
return true;
}
return false;
}
@Override
public boolean isVisibleNode(IEvalTarget target) {
return true;
}
@Override
public boolean isBlockJumpPointF(IEvalTarget node) {
return isBlockJumpPoint(false, node);
}
@Override
public boolean isBlockJumpPointB(IEvalTarget node) {
return isBlockJumpPoint(true, node);
}
public boolean isBlockJumpPoint(boolean back, IEvalTarget node) {
if (!(node instanceof TreeItemFennec))
return false;
TreeItemFennec item = (TreeItemFennec) node;
TreeItemFennec prev;
if (!back) {
if (item.getNth() > 0) {
prev = (TreeItemFennec) item.getParent().getChildItems()[item.getNth() - 1];
while (prev.hasChild()) {
ITreeItem[] items = prev.getChildItems();
prev = (TreeItemFennec) items[items.length - 1];
}
} else {
prev = (TreeItemFennec) item.getParent();
}
} else {
if (item.getNth() == item.getParent().getChildItems().length - 1) {
ITreeItem parent = item.getParent();
if (parent == null)
return false;
while (parent.getNth() == parent.getParent().getChildItems().length - 1) {
parent = parent.getParent();
if (parent == null)
return false;
}
prev = (TreeItemFennec) parent.getParent().getChildItems()[parent.getNth() + 1];
} else {
if (item.hasChild()) {
prev = (TreeItemFennec) item.getChildItems()[0];
} else {
prev = (TreeItemFennec) item.getParent().getChildItems()[item.getNth() + 1];
}
}
}
if (prev == null)
return false;
item.distance = prev.distance + 1;
prev.distance = 0;
if (!(item.getBaseNode() instanceof INodeEx))
return false;
if (!(prev.getBaseNode() instanceof INodeEx))
return false;
INodeEx nex = (INodeEx) item.getBaseNode();
INodeEx nex2 = (INodeEx) prev.getBaseNode();
if (nex == null || nex2 == null)
return false;
Rectangle r = nex.getLocation();
Rectangle r2 = nex2.getLocation();
if (r == null || r2 == null)
return false;
int dist = distance(r, r2);
item.distance += dist;
if (r.width < 20)
return false;
if (!Vocabulary.hasContent().eval(node))
return false;
if (!Vocabulary.hasReadingContent().eval(node))
return false;
if (Vocabulary.isClickable().eval(node))
return false;
if (item.getNth() > 2 && Vocabulary.isConnectable().eval(node))
return false;
if (item.distance > 800) {
item.distance = 0;
return true;
}
if (!back && !super.isBlockJumpPointF(node))
return false;
if (back && !super.isBlockJumpPointB(node))
return false;
if (item.distance > 200) {
item.distance = 0;
return true;
}
return false;
}
private int distance(Rectangle r, Rectangle r2) {
return (int) Math.sqrt(Math.abs(r.x - r2.x) * Math.abs(r.y - r2.y)) //
+ Math.abs(r.x - r2.x) + Math.abs(r.y - r2.y);
}
@Override
public boolean isHeading(int level, IEvalTarget node) {
if (!(node instanceof ITreeItem))
return false;
ITreeItem item = (ITreeItem) node;
if (level == 0)
return (item.getHeadingLevel() > 0);
else
return item.getHeadingLevel() == level;
}
@Override
public boolean isHeadingJumpPoint(IEvalTarget node) {
if (!(node instanceof ITreeItem))
return false;
ITreeItem item = (ITreeItem) node;
ITreeItem current = item;
short r = 0;
do {
if (current == null)
return super.isHeadingJumpPoint(node);
FennecMetadata meta = ((TreeItemFennec) current).getMetadata();
if (meta instanceof FennecGeneratedMetadata) {
r = ((FennecGeneratedMetadata) meta).getHeadingLevelByMetadata(item);
if (r > 0)
return true;
else if (r == -1)
return false;
current = current.getParent();
} else
break;
} while (r == 0);
if (((TreeItemFennec) item).getMetadata() == null)
return false;
return ((TreeItemFennec) item).getMetadata().getHeadingLevel(item) > 0;
}
@Override
public boolean isConnectable(IEvalTarget node) {
if (!(node instanceof TreeItemFennec))
return false;
TreeItemFennec item = (TreeItemFennec) node;
if (item.hasChild())
return false;
int nth = item.getNth();
int nextNth = nth + 1;
ITreeItem parent = ((TreeItemFennec) node).getParent();
if (parent == null)
return false;
ITreeItem[] items = parent.getChildItems();
if (nextNth >= items.length)
return false;
Object o = items[nextNth].getBaseNode();
if (o == null || !(o instanceof Node))
return false;
Node n = (Node) o;
return Vocabulary.isReachable(n).eval(node);
}
@Override
public boolean find(String str, boolean exact, IEvalTarget node) {
if (!(node instanceof ITreeItem))
return false;
ITreeItem item = (ITreeItem) node;
String uiString = item.getUIString();
if (!exact) {
uiString = uiString.toLowerCase();
str = str.toLowerCase();
}
if (uiString.indexOf(str) != -1)
return true;
/*
for (int len = str.length() - 1; len > 0; len--) {
if (uiString.lastIndexOf(str.substring(0, len)) == uiString.length() - len) {
if (hasChild()) {
if(Vocabulary.startsWith(str.substring(len), exact).eval(getChildItems()[0])){
return true;
}
continue;
}
int nth = item.getNth();
ITreeItem parent = item.getParent();
while (parent != null) {
ITreeItem[] items = parent.getChildItems();
if (nth + 1 < items.length) {
if(Vocabulary.startsWith(str.substring(len), exact).eval(items[nth + 1])){
return true;
}
break;
}
nth = parent.getNth();
parent = parent.getParent();
}
}
}*/
return false;
}
@Override
public boolean startsWith(String str, boolean exact, IEvalTarget node) {
if (!(node instanceof TreeItemFennec))
return false;
TreeItemFennec item = (TreeItemFennec) node;
String uiString = item.getUIString();
if (!exact) {
uiString = uiString.toLowerCase();
str = str.toLowerCase();
}
if (uiString.length() < str.length()) {
if (str.startsWith(uiString)) {
int len = uiString.length();
if (item.hasChild()) {
return Vocabulary.startsWith(str.substring(len), exact).eval(item.getChildItems()[0]);
}
int nth = item.getNth();
ITreeItem parent = item.getParent();
while (parent != null) {
ITreeItem[] items = parent.getChildItems();
if (nth + 1 < items.length) {
return Vocabulary.startsWith(str.substring(len), exact).eval(items[nth + 1]);
}
nth = parent.getNth();
parent = parent.getParent();
}
}
}
return uiString.startsWith(str);
}
@Override
public boolean nodeLocation(Node refNode, boolean backward, IEvalTarget node) {
if (!Vocabulary.hasContent().eval(node))
return false;
if (!(node instanceof TreeItemFennec))
return false;
TreeItemFennec item = (TreeItemFennec) node;
Node targetNode = item.getNearestNode();
if (targetNode == null) return false;
ArrayList<Node> refAncestors = getAncestors(refNode);
ArrayList<Node> ancestors = getAncestors(targetNode);
int i = refAncestors.size() - 1;
int j = ancestors.size() - 1;
while ((i >= 0) && (j >= 0)) {
Node refAncestor = refAncestors.get(i);
Node ancestor = ancestors.get(j);
if (!(ancestor.isSameNode(refAncestor))) {
if (!((ancestor instanceof INodeEx)) && (refAncestor instanceof INodeEx))
return false;
int ancestorNth = ((INodeEx) ancestor).getNth();
int refAncestorNth = ((INodeEx) refAncestor).getNth();
if (ancestorNth == refAncestorNth)
return true;
if (backward) {
return (ancestorNth < refAncestorNth);
} else {
return (ancestorNth > refAncestorNth);
}
}
i--;
j--;
}
return true;
}
private ArrayList<Node> getAncestors(Node n) {
ArrayList<Node> list = new ArrayList<Node>();
while (n != null) {
list.add(n);
n = n.getParentNode();
}
return list;
}
}