java/code/src/com/redhat/rhn/frontend/action/channel/PackageSearchAction.java | 115 ++++++++-- java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml | 2 java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml | 14 + java/code/webapp/WEB-INF/pages/channel/packagesearch.jsp | 46 ++-- java/code/webapp/WEB-INF/struts-config.xml | 1 5 files changed, 145 insertions(+), 33 deletions(-)
New commits: commit 4e7014913d566209226486b643e4f30b4bce2119 Author: Jason Dobies jason.dobies@redhat.com Date: Fri May 29 16:58:06 2009 -0400
457316 - Added search for packages in a particular channel.
Restructured the page to be a radio-button based selection of which criteria to use (relevant channel, specific channel, specific architecture).
diff --git a/java/code/src/com/redhat/rhn/frontend/action/channel/PackageSearchAction.java b/java/code/src/com/redhat/rhn/frontend/action/channel/PackageSearchAction.java index 419a18a..cccb13e 100644 --- a/java/code/src/com/redhat/rhn/frontend/action/channel/PackageSearchAction.java +++ b/java/code/src/com/redhat/rhn/frontend/action/channel/PackageSearchAction.java @@ -18,7 +18,10 @@ package com.redhat.rhn.frontend.action.channel; import com.redhat.rhn.common.localization.LocalizationService; import com.redhat.rhn.common.validator.ValidatorException; import com.redhat.rhn.domain.channel.ChannelArch; +import com.redhat.rhn.domain.channel.Channel; +import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.dto.PackageOverview; +import com.redhat.rhn.frontend.dto.PackageDto; import com.redhat.rhn.frontend.struts.RequestContext; import com.redhat.rhn.frontend.struts.RhnAction; import com.redhat.rhn.frontend.taglibs.list.ListTagHelper; @@ -158,16 +161,36 @@ public class PackageSearchAction extends RhnAction { RequestContext ctx = new RequestContext(request); String searchString = form.getString("search_string"); String viewmode = form.getString("view_mode"); - String relevant = StringUtils.defaultString( - request.getParameter("relevant")); - String[] selectedArches = form.getStrings("channel_arch"); - - if (selectedArches.length < 1) { - relevant = "yes"; + String searchCriteria = request.getParameter("whereCriteria"); + String[] selectedArches = null; + Long filterChannelId = null; + boolean relevantFlag = false; + + // Default to relevant channels if no search criteria was specified + if (searchCriteria == null || searchCriteria.equals("")) { + searchCriteria = "relevant"; } - + + // Handle the radio button selection for channel filtering + if (searchCriteria.equals("relevant")) { + relevantFlag = true; + } + if (searchCriteria.equals("architecture")) { + /* The search call will function as being scoped to architectures if the arch + list isn't null. In order to actually get radio-button-like functionality + we can't rely on the arch list coming in from the form to be null; the + user may have selected an arch but *not* the radio button for arch. If we + push off retrieving the arches until we know we want to use them, we can + get the desired functionality described by the UI. + */ + selectedArches = form.getStrings("channel_arch"); + } + else if (searchCriteria.equals("channel")) { + String sChannelId = form.getString("channel_filter"); + filterChannelId = Long.parseLong(sChannelId); + } + if (viewmode.equals("")) { //first time viewing page - relevant = "yes"; viewmode = PackageSearchHelper.OPT_NAME_AND_SUMMARY; }
@@ -201,21 +224,36 @@ public class PackageSearchAction extends RhnAction { !archLabels.contains(arch.getLabel())); } } - + + // Load list of available channels to select as filter + List allChannels = + ChannelManager.allChannelsTree(ctx.getLoggedInUser()); + request.setAttribute("search_string", searchString); request.setAttribute("view_mode", viewmode); - request.setAttribute("relevant", relevant); request.setAttribute("searchOptions", searchOptions); request.setAttribute("channelArches", channelArches); request.setAttribute("channel_arch", selectedArches); + request.setAttribute("allChannels", allChannels); + + // Default where to search criteria + request.setAttribute("whereCriteria", searchCriteria);
if (!StringUtils.isBlank(searchString)) { List<PackageOverview> results = PackageSearchHelper.performSearch(ctx.getWebSession().getId(), searchString, viewmode, - selectedArches); + selectedArches, relevantFlag); + + // Perform any post-search logic that wasn't done by the search server results = removeDuplicateNames(results); + + if (filterChannelId != null) { + User user = ctx.getLoggedInUser(); + results = filterByChannel(user, filterChannelId, results); + } + log.warn("GET search: " + results); request.setAttribute("pageList", results != null ? results : Collections.EMPTY_LIST); @@ -224,12 +262,18 @@ public class PackageSearchAction extends RhnAction { request.setAttribute("pageList", Collections.EMPTY_LIST); } } - + + /** + * Package Search returns a list of all matching packages, this will likely + * include multiple packages with the same name but different version, release, + * epoch. WebUI only wants a list of unique package names, so we need + * to strip the duplicate names while preserving order. + * + * @param pkgs packages returned from search that should be cleaned + * @return new list object with duplicates removed; does not change the list in place + */ private List<PackageOverview> removeDuplicateNames(List<PackageOverview> pkgs) { - // Package Search returns a list of all matching packages, this will likely - // include multiple packages with the same name but different version, release, - // epoch. WebUI only wants a list of unique package names, so we need - // to strip the duplicate names while preserving order. + List<PackageOverview> result = new ArrayList<PackageOverview>(); for (PackageOverview pkgOver : pkgs) { boolean addPkg = true; @@ -246,6 +290,45 @@ public class PackageSearchAction extends RhnAction { return result; }
+ /** + * Since the search server does not carry channel information, we do any channel + * filtering in the Java stack. This method will return a new list of packages that + * containing packages that are present in the given channel; others returned from + * the search will be removed. + * + * @param user user making the request + * @param channelId channel against which the filter should be run + * @param pkgs list of packages returned from the search query that should be + * filtered + * @return new list object with duplicates removed; does not change the list in place + */ + private List<PackageOverview> filterByChannel(User user, Long channelId, + List<PackageOverview> pkgs) { + + Channel channel = ChannelManager.lookupByIdAndUser(channelId, user); + List<PackageDto> allPackagesList = ChannelManager.listAllPackages(channel); + + // Convert the package list into a map for quicker lookup + Map<String, String> packageNamesMap = + new HashMap<String, String>(allPackagesList.size()); + + for (PackageDto dto : allPackagesList) { + String name = dto.getName(); + packageNamesMap.put(name, name); + } + + // Iterate results and remove if not in the channel + List<PackageOverview> newResult = new ArrayList<PackageOverview>(); + for (PackageOverview pkg : pkgs) { + String packageName = pkg.getPackageName(); + if (packageNamesMap.get(packageName) != null) { + newResult.add(pkg); + } + } + + return newResult; + } + private void addOption(List options, String key, String value) { addOption(options, key, value, false); } diff --git a/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml b/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml index 4f6af70..eefc958 100644 --- a/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml +++ b/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml @@ -2668,7 +2668,7 @@ available for this kickstart profile to function properly. </context-group> </trans-unit> <trans-unit id="searchserver.index_out_of_sync_with_db"> - <source>SearchServer index and database entries appear to be out of sync. Please run '/sbin/service rhn-search cleanindex; /sbin/service rhn-search start'</source> + <source>SearchServer index and database entries appear to be out of sync. Please run '/sbin/service rhn-search cleanindex'</source> <context-group name="ctx"> <context context-type="sourcefile">/rhn/channels/Search</context> </context-group> diff --git a/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml b/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml index 30ebc1d..2470475 100644 --- a/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml +++ b/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml @@ -5162,7 +5162,19 @@ value for this entitlement.</source> </context-group> </trans-unit> <trans-unit id="packagesearch.jsp.relevant"> -<source>Channels relevant to your systems</source> +<source>Only channels relevant to your systems</source> + <context-group name="ctx"> + <context context-type="sourcefile">/rhn/channels/software/Search</context> + </context-group> + </trans-unit> + <trans-unit id="packagesearch.jsp.specificchannel"> +<source>Specific channel you have access to</source> + <context-group name="ctx"> + <context context-type="sourcefile">/rhn/channels/software/Search</context> + </context-group> + </trans-unit> + <trans-unit id="packagesearch.jsp.specificarch"> +<source>Packages of a specific architecture in any channel you have access to</source> <context-group name="ctx"> <context context-type="sourcefile">/rhn/channels/software/Search</context> </context-group> diff --git a/java/code/webapp/WEB-INF/pages/channel/packagesearch.jsp b/java/code/webapp/WEB-INF/pages/channel/packagesearch.jsp index bc1a13f..ed50a22 100644 --- a/java/code/webapp/WEB-INF/pages/channel/packagesearch.jsp +++ b/java/code/webapp/WEB-INF/pages/channel/packagesearch.jsp @@ -53,20 +53,34 @@ </tr> <tr><th><bean:message key="packagesearch.jsp.wheresearch"/></th> <td rowspan="2"> - <div style="text-align: center"> - <input type="checkbox" name="relevant" value="yes" onclick="javascript:highlander(this);" - <c:if test="${not empty relevant}">checked="checked"</c:if> /> - <bean:message key="packagesearch.jsp.relevant"/></div> - <div style="font-weight: bold; text-align: center">-or-</div> - <div style="text-align: center"> - <html:select property="channel_arch" multiple="multiple" size="5" onclick="javascript:highlander(this);"> - <html:options collection="channelArches" - property="value" - labelProperty="display" /> - </html:select><br/> - - </div> - <div style="text-align: center"><bean:message key="packagesearch.jsp.searchwherelegend"/></div> + + <div style="text-align: left;"> + <input type="radio" name="whereCriteria" value="relevant" <c:if test="${whereCriteria eq 'relevant'}">checked</c:if> /><bean:message key="packagesearch.jsp.relevant"/> + </div> + <div style="text-align: left;"> + <input type="radio" name="whereCriteria" value="channel" <c:if test="${whereCriteria eq 'channel'}">checked</c:if> /><bean:message key="packagesearch.jsp.specificchannel"/><br/> + <div style="margin-left: 30px; margin-top: 5px;"> + <html:select property="channel_filter"> + <html:options collection="allChannels" + property="id" + labelProperty="name" /> + </html:select><br/> + </div> + </div> + <div style="text-align: left;"> + <input type="radio" name="whereCriteria" value="architecture" <c:if test="${whereCriteria eq 'architecture'}">checked</c:if> /><bean:message key="packagesearch.jsp.specificarch"/><br/> + <div style="margin-left: 30px; margin-top: 5px;"> + <html:select property="channel_arch" multiple="multiple" + size="5" onclick="javascript:highlander(this);"> + <html:options collection="channelArches" + property="value" + labelProperty="display" /> + </html:select><br/> + + <bean:message key="packagesearch.jsp.searchwherelegend"/> + </div> + </div> + </td> </tr> </table> @@ -118,7 +132,9 @@ <input type="hidden" name="submitted" value="true" /> <input type="hidden" name="search_string" value="${search_string}" /> <input type="hidden" name="view_mode" value="${view_mode}" /> - <input type="hidden" name="relevant" value="${relevant}" /> + <input type="hidden" name="whereCriteria" value="${whereCriteria}" /> + <input type="hidden" name="channel_filter" value="${channel_filter}" /> + <c:forEach items="${requestScope.channel_arch}" var="item"> <input type="hidden" name="channel_arch" value="${item}" /> </c:forEach> diff --git a/java/code/webapp/WEB-INF/struts-config.xml b/java/code/webapp/WEB-INF/struts-config.xml index 4b2160a..31c416e 100644 --- a/java/code/webapp/WEB-INF/struts-config.xml +++ b/java/code/webapp/WEB-INF/struts-config.xml @@ -255,6 +255,7 @@ <form-property name="search_string" type="java.lang.String"/> <form-property name="view_mode" type="java.lang.String"/> <form-property name="channel_arch" type="java.lang.String[]"/> + <form-property name="channel_filter" type="java.lang.String"/> <form-property name="filter_value" type="java.lang.String"/> <form-property name="prev_filter_value" type="java.lang.String"/> <form-property name="relevant" type="java.lang.String" />
spacewalk-commits@lists.fedorahosted.org