/* * This software is Copyright 2005,2006,2007,2008 Langdale Consultants. * Langdale Consultants can be contacted at: http://www.langdale.com.au */ package au.com.langdale.kena; import java.util.AbstractCollection; import java.util.Collection; import java.util.Iterator; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; /** * An index of all local names found in one or more models. */ public abstract class SearchIndex { private SortedSet words = new TreeSet(); /** * Add a single word to this index. */ public void addWord(String word) { words.add(reverse(word)); } /** * Find all words in the index matching a prefix * @param prefix: a string prefixing the last dotted substring of each match * @return a collection of <code>String</code>s */ public Collection match(String prefix, int limit) { return new Result(prefix, limit); } /** * Add all words occurring in the model to this index. */ public abstract void scan(OntModel model); /** * Find the resources in the model corresponding to this word. */ public abstract Set locate(String name, OntModel model); private static String reverse(String path) { StringBuffer result = new StringBuffer(); int ix = path.length(); while(ix > 0) { int iy = path.lastIndexOf('.', ix - 1) + 1; result.append(path, iy, ix); if( iy > 0 ) result.append('.'); ix = iy - 1; } return result.toString(); } /** * A collection of matches. */ private class Result extends AbstractCollection { private Collection matches; private String prefix; private int limit; public Result(String prefix, int limit) { this.prefix = prefix; this.matches = words.tailSet(prefix); this.limit = limit; } @Override public Iterator iterator() { return new Iterator() { Iterator inner = matches.iterator(); int count; Object lookahead = step(); private Object step() { if( count >= limit || ! inner.hasNext()) return null; String cand = (String) inner.next(); if( ! cand.startsWith(prefix)) return null; return reverse(cand); } public boolean hasNext() { return lookahead != null; } public Object next() { count++; Object value = lookahead; lookahead = step(); return value; } public void remove() { } }; } @Override public int size() { Iterator inner = matches.iterator(); int count = 0; while( count < limit ) { if( ! inner.hasNext()) break; String cand = (String) inner.next(); if( ! cand.startsWith(prefix)) break; count++; } return count; } } }