diff --git a/core/src/main/java/hudson/search/Search.java b/core/src/main/java/hudson/search/Search.java index c6899a7cdf6ef0a19af8695cc26c74e3fc090151..402aad6ae0c8e48f0f3d9be1eee1c357999c7d7b 100644 --- a/core/src/main/java/hudson/search/Search.java +++ b/core/src/main/java/hudson/search/Search.java @@ -25,9 +25,9 @@ package hudson.search; import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; - import hudson.Util; import hudson.util.EditDistance; + import java.io.IOException; import java.util.AbstractList; import java.util.ArrayList; @@ -39,6 +39,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; + import org.kohsuke.stapler.Ancestor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; @@ -340,7 +341,7 @@ public class Search { items.clear(); m.find(index,token,items); for (SearchItem si : items) { - paths[w].add(new SuggestedItem(si)); + paths[w].add(SuggestedItem.build(si)); LOGGER.log(Level.FINE, "found search item: {0}", si.getSearchName()); } w++; diff --git a/core/src/main/java/hudson/search/SuggestedItem.java b/core/src/main/java/hudson/search/SuggestedItem.java index e242471063b9f461a1eb106014c8612a1932acff..6a40c2b9889520ec6e3d98321157de48c42c649a 100644 --- a/core/src/main/java/hudson/search/SuggestedItem.java +++ b/core/src/main/java/hudson/search/SuggestedItem.java @@ -23,6 +23,9 @@ */ package hudson.search; +import hudson.model.Item; +import hudson.model.ItemGroup; + /** * One item of a search result. * @@ -75,6 +78,29 @@ public class SuggestedItem { getUrl(buf); return buf.toString(); } + + private static SuggestedItem build(Item top) { + ItemGroup parent = top.getParent(); + if (parent instanceof Item) { + Item parentItem = (Item)parent; + return new SuggestedItem(build(parentItem), top); + } + return new SuggestedItem(top); + } + + /** + * Given a SearchItem, builds a SuggestedItem hierarchy by looking up parent items (if applicable). + * This allows search results for items not contained within the same ItemGroup to be distinguished. + * @param si + * @return + * @since XXX + */ + public static SuggestedItem build(SearchItem si) { + if (si instanceof Item) { + return build((Item)si); + } + return new SuggestedItem(si); + } private void getUrl(StringBuilder buf) { if(parent!=null) { diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index 6e7c388cec70bdcd5afeb0aef95341e65ccc6185..ff25f816c6f160527befa5f590929ad184f84c03 100755 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -1821,8 +1821,8 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro .add("manage") .add("log") .add(new CollectionSearchIndex() { - protected SearchItem get(String key) { return getItem(key); } - protected Collection all() { return getItems(); } + protected SearchItem get(String key) { return getItemByFullName(key, TopLevelItem.class); } + protected Collection all() { return getAllItems(TopLevelItem.class); } }) .add(getPrimaryView().makeSearchIndex()) .add(new CollectionSearchIndex() {// for computers diff --git a/test/src/test/java/hudson/search/SearchTest.java b/test/src/test/java/hudson/search/SearchTest.java index e213813ec33fe80250c7da708a87b03dd449ceff..f524685b95db28e08ff3ddcf0fcf465aeab1a1c7 100644 --- a/test/src/test/java/hudson/search/SearchTest.java +++ b/test/src/test/java/hudson/search/SearchTest.java @@ -43,6 +43,7 @@ import org.junit.Test; import org.jvnet.hudson.test.Bug; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.JenkinsRule.WebClient; +import org.jvnet.hudson.test.MockFolder; import com.gargoylesoftware.htmlunit.AlertHandler; import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; @@ -256,6 +257,17 @@ public class SearchTest { assertTrue(suggest(j.jenkins.getSearchIndex(),"foo").contains(p)); } + + @Test + public void testSearchWithinFolders() throws Exception { + MockFolder folder1 = j.createFolder("folder1"); + FreeStyleProject p1 = folder1.createProject(FreeStyleProject.class, "myjob"); + MockFolder folder2 = j.createFolder("folder2"); + FreeStyleProject p2 = folder2.createProject(FreeStyleProject.class, "myjob"); + List suggest = suggest(j.jenkins.getSearchIndex(), "myjob"); + assertTrue(suggest.contains(p1)); + assertTrue(suggest.contains(p2)); + } private List suggest(SearchIndex index, String term) { List result = new ArrayList();