提交 872b71fc 编写于 作者: K kohsuke

importing code from experiments. this is still not live yet.


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@4056 71c3de6d-444a-0410-be80-ed276b4c234a
上级 e337c69c
package hudson.search;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* Set of {@link SearchItem}s that are statically known upfront.
*
* @author Kohsuke Kawaguchi
*/
public class FixedSet implements SearchIndex {
private final Collection<? extends SearchItem> items;
public FixedSet(Collection<? extends SearchItem> items) {
this.items = items;
}
public FixedSet(SearchItem... items) {
this(Arrays.asList(items));
}
public void find(String token, List<SearchItem> result) {
for (SearchItem i : items)
if(token.equals(i.getSearchName()))
result.add(i);
}
public void suggest(String token, List<SearchItem> result) {
for (SearchItem i : items)
if(i.getSearchName().contains(token))
result.add(i);
}
}
package hudson.search;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
/**
* @author Kohsuke Kawaguchi
*/
@Retention(RUNTIME)
@Target({METHOD, FIELD})
public @interface QuickSilver {
String[] value() default {};
}
package hudson.search;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Collections;
import hudson.util.EditDistance;
/**
* @author Kohsuke Kawaguchi
*/
public class Search {
//public static List<SearchItem> find(SearchIndex index, String tokenList) {
// List<SearchItem> result = new ArrayList<SearchItem>();
// StringTokenizer tokens = new StringTokenizer(tokenList);
//
// while(tokens.hasMoreTokens()) {
// String token = tokens.nextToken();
//
// result.clear();
// index.find(token,result);
//
// index = SearchIndex.EMPTY;
// for (SearchItem r : result)
// index = UnionSearchIndex.combine(index,r.getSearchIndex());
// }
//
// return result;
//}
private enum Mode {
FIND {
void find(SearchIndex index, String token, List<SearchItem> result) {
index.find(token, result);
}
},
SUGGEST {
void find(SearchIndex index, String token, List<SearchItem> result) {
index.suggest(token, result);
}
};
abstract void find(SearchIndex index, String token, List<SearchItem> result);
}
public static SuggestedItem find(SearchIndex index, String tokenList) {
List<SuggestedItem> r = find(Mode.FIND, index, tokenList);
if(r.isEmpty()) return null;
else return r.get(0);
}
public static List<SuggestedItem> suggest(SearchIndex index, final String tokenList) {
class Tag implements Comparable<Tag>{
SuggestedItem item;
int distance;
Tag(SuggestedItem i) {
this.item = i;
distance = EditDistance.editDistance(i.getPath(),tokenList);
}
public int compareTo(Tag that) {
return this.distance-that.distance;
}
}
List<Tag> buf = new ArrayList<Tag>();
List<SuggestedItem> items = find(Mode.SUGGEST, index, tokenList);
// sort them
for( SuggestedItem i : items)
buf.add(new Tag(i));
Collections.sort(buf);
items.clear();
for (Tag t : buf)
items.add(t.item);
return items;
}
private static List<SuggestedItem> find(Mode m, SearchIndex index, String tokenList) {
List<SuggestedItem> front = new ArrayList<SuggestedItem>();
List<SuggestedItem> back = new ArrayList<SuggestedItem>();
List<SearchItem> items = new ArrayList<SearchItem>(); // items found in 1 step
StringTokenizer tokens = new StringTokenizer(tokenList);
if(!tokens.hasMoreTokens()) return front; // no tokens given
// first token
m.find(index,tokens.nextToken(),items);
for (SearchItem i : items)
front.add(new SuggestedItem(i));
// successive tokens
while(tokens.hasMoreTokens()) {
String token = tokens.nextToken();
back.clear();
for (SuggestedItem r : front) {
items.clear();
m.find(r.item.getSearchIndex(),token,items);
for (SearchItem i : items)
back.add(new SuggestedItem(r,i));
}
{// swap front and back
List<SuggestedItem> t = front;
front = back;
back = t;
}
}
return front;
}
}
package hudson.search;
import java.util.List;
/**
* @author Kohsuke Kawaguchi
*/
public interface SearchIndex {
void find(String token, List<SearchItem> result);
/**
*
* This method returns the superset of {@link #find(String, List)}.
*/
void suggest(String token, List<SearchItem> result);
/**
* Empty set.
*/
static final SearchIndex EMPTY = new SearchIndex() {
public void find(String token, List<SearchItem> result) {
// no item to contribute
}
public void suggest(String token, List<SearchItem> result) {
// nothing to suggest
}
};
}
package hudson.search;
import java.util.ArrayList;
import java.util.List;
/**
* @author Kohsuke Kawaguchi
*/
public final class SearchIndexBuilder {
private final List<SearchItem> items = new ArrayList<SearchItem>();
private final List<SearchIndex> indices = new ArrayList<SearchIndex>();
public SearchIndexBuilder add(String url, String name) {
items.add(SearchItems.create(name,url));
return this;
}
public SearchIndexBuilder add(String url, String... names) {
for (String name : names)
add(url,name);
return this;
}
public SearchIndexBuilder add(String url, SearchableModelObject searchable, String name) {
items.add(SearchItems.create(name,url,searchable));
return this;
}
public SearchIndexBuilder add(String url, SearchableModelObject searchable, String... names) {
for (String name : names)
add(url,searchable,name);
return this;
}
public SearchIndexBuilder add(SearchIndex index) {
this.indices.add(index);
return this;
}
public SearchIndex make() {
SearchIndex r = new FixedSet(items);
for (SearchIndex index : indices)
r = new UnionSearchIndex(r,index);
return r;
}
}
package hudson.search;
/**
* @author Kohsuke Kawaguchi
*/
public interface SearchItem {
String getSearchName();
String getSearchUrlFragment();
SearchIndex getSearchIndex();
}
package hudson.search;
/**
* @author Kohsuke Kawaguchi
*/
public class SearchItems {
public static SearchItem create(String searchName, String url) {
return create(searchName,url, SearchIndex.EMPTY);
}
public static SearchItem create(final String searchName, final String url, final SearchIndex children) {
return new SearchItem() {
public String getSearchName() {
return searchName;
}
public String getSearchUrlFragment() {
return url;
}
public SearchIndex getSearchIndex() {
return children;
}
};
}
public static SearchItem create(final String searchName, final String url, final SearchableModelObject searchable) {
return new SearchItem() {
public String getSearchName() {
return searchName;
}
public String getSearchUrlFragment() {
return url;
}
public SearchIndex getSearchIndex() {
return searchable.getSearchIndex();
}
};
}
}
package hudson.search;
import hudson.model.ModelObject;
/**
* {@link ModelObject} that has {@link SearchIndex}.
*
* @author Kohsuke Kawaguchi
*/
public interface SearchableModelObject extends ModelObject {
SearchIndex getSearchIndex();
}
package hudson.search;
/**
* @author Kohsuke Kawaguchi
*/
public class SuggestedItem {
private final SuggestedItem parent;
public final SearchItem item;
public SuggestedItem(SearchItem top) {
this(null,top);
}
public SuggestedItem(SuggestedItem parent, SearchItem item) {
this.parent = parent;
this.item = item;
}
public String getPath() {
if(parent==null)
return item.getSearchName();
else {
StringBuilder buf = new StringBuilder();
getPath(buf);
return buf.toString();
}
}
private void getPath(StringBuilder buf) {
if(parent==null)
buf.append(item.getSearchName());
else {
parent.getPath(buf);
buf.append(' ').append(item.getSearchName());
}
}
public String getUrl() {
StringBuilder buf = new StringBuilder("$contextRoot");
getUrl(buf);
return buf.toString();
}
private void getUrl(StringBuilder buf) {
if(parent!=null) {
parent.getUrl(buf);
}
buf.append('/').append(item.getSearchUrlFragment());
}
}
package hudson.search;
import java.util.List;
/**
* Union of two sets.
*
* @author Kohsuke Kawaguchi
*/
public class UnionSearchIndex implements SearchIndex {
public static SearchIndex combine(SearchIndex... sets) {
SearchIndex p=EMPTY;
for (SearchIndex q : sets) {
// allow some of the inputs to be null,
// and also recognize EMPTY
if (q != null && q != EMPTY) {
if (p == EMPTY)
p = q;
else
p = new UnionSearchIndex(p,q);
}
}
return p;
}
private final SearchIndex lhs,rhs;
public UnionSearchIndex(SearchIndex lhs, SearchIndex rhs) {
this.lhs = lhs;
this.rhs = rhs;
}
public void find(String token, List<SearchItem> result) {
lhs.find(token,result);
rhs.find(token,result);
}
public void suggest(String token, List<SearchItem> result) {
lhs.suggest(token,result);
rhs.suggest(token,result);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册