package esl.cuenet.source; import com.hp.hpl.jena.ontology.EnumeratedClass; import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.util.iterator.ExtendedIterator; import esl.cuenet.query.QueryOperator; import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; public class TreeMapper implements IMapper { private TreeMapperNode root = new TreeMapperNode(); private Logger logger = Logger.getLogger(TreeMapper.class); private OntModel model = null; private HashMap<String, String> namespaceMap; public TreeMapper(HashMap<String, String> namespaceMap) { root.name = "//"; root.adornment = null; root.attribute = null; root.operator = null; if (namespaceMap == null) this.namespaceMap = new HashMap<String, String>(); else this.namespaceMap = namespaceMap; } @Override public void map(String pathExpression, Adornment adornment, QueryOperator operator, Attribute attribute) { if (pathExpression == null) throw new NullPointerException("Null Path Expression"); if (containsPattern(pathExpression)) logger.debug("Path already in tree: " + pathExpression); else { TreeMapperNode node = completeExpression(pathExpression); node.adornment = adornment; node.operator = operator; node.attribute = attribute; if (node.resourcePath == null) node.resourcePath = nsEval(pathExpression); } } @Override public void map(String pathExpression, Adornment adornment) { TreeMapperNode node; if (containsPattern(pathExpression)) { logger.debug("[map-adornment] Path already in tree: " + pathExpression); TreeMapperNode[] exp = findSubExpressionNode(pathExpression); node = exp[exp.length - 1]; } else { node = completeExpression(pathExpression); } node.adornment = adornment; if (node.resourcePath == null) node.resourcePath = nsEval(pathExpression); } @Override public void map(String pathExpression, QueryOperator operator) { TreeMapperNode node; if (containsPattern(pathExpression)) { logger.debug("[map-operator] Path already in tree: " + pathExpression); TreeMapperNode[] exp = findSubExpressionNode(pathExpression); node = exp[exp.length - 1]; } else { node = completeExpression(pathExpression); } node.operator = operator; if (node.resourcePath == null) node.resourcePath = nsEval(pathExpression); } @Override public void map(String pathExpression, Attribute attribute) { TreeMapperNode node; if (containsPattern(pathExpression)) { logger.debug("[map-attribute] Path already in tree: " + pathExpression); TreeMapperNode[] exp = findSubExpressionNode(pathExpression); node = exp[exp.length - 1]; } else { node = completeExpression(pathExpression); } node.attribute = attribute; if (node.resourcePath == null) node.resourcePath = nsEval(pathExpression); } private Resource[] nsEval(String pathExpression) { if (namespaceMap.size() == 0) return new Resource[0]; String[] classnames = pathExpression.split("\\."); Resource[] resourcePath = new Resource[classnames.length]; String uri; for (int i = 0; i < classnames.length - 1; i++) { uri = namespaceMap.get("this") + classnames[i]; resourcePath[i] = model.getOntClass(uri); // if (resourcePath[i] == null) logger.error("Class not found: " + uri + " " + pathExpression); } int last = classnames.length - 1; uri = namespaceMap.get("this") + classnames[last]; if (model.getOntClass(uri) != null) resourcePath[last] = model.getOntClass(uri); else if (model.getDatatypeProperty(uri) != null) resourcePath[last] = model.getDatatypeProperty(uri); // else // logger.error("Class not found: " + uri + " " + pathExpression); return resourcePath; } @Override public boolean containsPattern(String pathExpression) { String exp = buildExpression(findSubExpressionNode(pathExpression)); return exp.compareTo(pathExpression) == 0; } @Override public Attribute getAttribute(String pathExpression) { if (!containsPattern(pathExpression)) throw new NullPointerException("Path Expression not found: " + pathExpression); TreeMapperNode[] nodes = findSubExpressionNode(pathExpression); return nodes[nodes.length - 1].attribute; } @Override public Adornment getAdornment(String pathExpression) { if (!containsPattern(pathExpression)) throw new NullPointerException("Path Expression not found: " + pathExpression); TreeMapperNode[] nodes = findSubExpressionNode(pathExpression); return nodes[nodes.length - 1].adornment; } @Override public void setOntologyModel(OntModel model) { this.model = model; } @Override public OntModel getOntologyModel() { return this.model; } private TreeMapperNode completeExpression(String pathExpression) { TreeMapperNode[] partialExpressionNodes = findSubExpressionNode(pathExpression); TreeMapperNode start = root; String[] names = pathExpression.split("\\."); int ix = 0; if (partialExpressionNodes[0] != null) { for (; ix < partialExpressionNodes.length; ix++) if (partialExpressionNodes[ix] == null) { start = partialExpressionNodes[ix - 1]; break; } } for (int i = ix; i < names.length; i++) { TreeMapperNode node = new TreeMapperNode(); node.name = names[i]; start.children.add(node); start = node; } return start; } private String buildExpression(TreeMapperNode[] nodes) { if (nodes == null) return ""; StringBuilder builder = new StringBuilder(); for (TreeMapperNode node : nodes) if (node != null) builder.append(node.name).append('.'); int eix = builder.lastIndexOf("."); if (eix == -1) return ""; return builder.substring(0, eix); } private TreeMapperNode[] findSubExpressionNode(String pathExpression) { String[] names = pathExpression.split("\\."); TreeMapperNode current = root; TreeMapperNode[] resultList = new TreeMapperNode[names.length]; for (TreeMapperNode n : resultList) n = null; int ix = 0; while (true) { List<TreeMapperNode> children = current.children; for (TreeMapperNode node : children) if (node.name.compareTo(names[ix]) == 0) resultList[ix] = node; if (resultList[ix] == null) break; else current = resultList[ix]; ix++; if (ix == names.length) break; } return resultList; } private class TreeMapperNode { public String name; public Adornment adornment; public QueryOperator operator; public Attribute attribute; public Resource[] resourcePath = null; public List<TreeMapperNode> children = new ArrayList<TreeMapperNode>(); public String toString() { StringBuilder builder = new StringBuilder(); builder.append('(').append(name).append(" -> "); for (TreeMapperNode c : children) builder.append(c.toString()).append(" "); builder.append(')'); return builder.substring(0); } } }