/* * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package wicket.contrib.woogle.components; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.nutch.parse.ParseData; import org.apache.nutch.searcher.Hit; import org.apache.nutch.searcher.HitDetails; import org.apache.nutch.searcher.Hits; import org.apache.nutch.searcher.NutchBean; import org.apache.nutch.searcher.Query; import wicket.PageParameters; import wicket.behavior.SimpleAttributeModifier; import wicket.contrib.woogle.WoogleApplication; import wicket.contrib.woogle.domain.Site; import wicket.contrib.woogle.pages.SearchPage; import wicket.extensions.markup.html.repeater.RepeatingView; import wicket.markup.html.WebComponent; import wicket.markup.html.WebMarkupContainer; import wicket.markup.html.basic.Label; import wicket.markup.html.link.BookmarkablePageLink; import wicket.markup.html.link.ExternalLink; import wicket.markup.html.link.Link; import wicket.markup.html.list.Loop; import wicket.markup.html.panel.Panel; public class SearchResult extends Panel { private static final long serialVersionUID = 1L; /** Logging */ private static final Log log = LogFactory.getLog(SearchResult.class); private final int entriesPerPage = 10; private Hits hits; private Query query; private int calcPage; private int offset; private NutchBean nutch; private int page; private String searchString; public SearchResult(String id, String searchString) { this(id, searchString, 0); } public SearchResult(String id, String searchString, int page) { super(id); nutch = WoogleApplication.get().getNutch(); try { query = Query.parse(searchString); hits = nutch.search(query, 10000000); } catch (Exception e) { log.debug("Failed to search", e); } // Trackback if (hits.getLength() == 0) { add(new WebComponent("trackback").setVisible(false)); } else { PageParameters parameters = new PageParameters(); parameters.add("search", searchString); add(new BookmarkablePageLink("trackback", SearchPage.class, parameters)); } // Calculate offset if (page > 0) { page--; } int offset = page * entriesPerPage; if (offset >= hits.getLength()) { offset = hits.getLength() - entriesPerPage; page = offset / entriesPerPage; } if (offset < 0) { offset = 0; page = 0; } this.offset = offset; this.page = page; this.searchString = searchString; // Stats String stats; if (hits.getLength() == 0) { stats = "No results found."; } else { stats = "Showing "+(offset+1)+"-"+(offset+entriesPerPage)+" of "+hits.getLength(); } add(new Label("stats", stats)); // Result if (hits.getLength() == 0) { add(new WebComponent("hits").setVisible(false)); add(new WebComponent("pages").setVisible(false)); } else { showResult(); } } private void showResult() { RepeatingView hitsView = new RepeatingView("hits"); add(hitsView); // Preload the sites List<Site> sites = WoogleApplication.get().getSiteDAO().listActive(); for (Site site : sites) { Pattern pat = Pattern.compile(site.getMatchPattern()); site.setPattern(pat); } for (int i = offset; offset + entriesPerPage > i && i < hits.getLength(); i++) { Hit hit = hits.getHit(i); try { final HitDetails details = nutch.getDetails(hit); ParseData data = nutch.getParseData(details); String summary = nutch.getSummary(details, query); final String url = details.getValue("url"); // Container final WebMarkupContainer hitContainer = new WebMarkupContainer("" + i); hitsView.add(hitContainer); ExternalLink item = new ExternalLink("hitLink", url); hitContainer.add(item); String cssClass = ""; // Type of link for (Site site : sites) { Matcher mat = site.getPattern().matcher(url); if (mat.matches()) { cssClass += site.getCssClass(); break; } } // Css class item.add(new SimpleAttributeModifier("class", cssClass)); // Title item.add(new Label("title", data.getTitle())); // Summary item.add(new Label("summary", summary) .setEscapeModelStrings(false)); // Link item.add(new Label("linkLabel", url)); } catch (Exception e) { e.printStackTrace(); } } // Paging int numOfPages = hits.getLength() / entriesPerPage; int numLoopPages = numOfPages > 9 ? 9 : numOfPages; calcPage = 0; if (page > 4) { calcPage = page - 4; } add(new Loop("pages", numLoopPages) { private static final long serialVersionUID = 1L; @Override protected void populateItem(final LoopItem item) { int displayPage = calcPage + 1; PageParameters parameters = new PageParameters(); parameters.add("search", searchString); parameters.add("page", ""+displayPage); Link link = new BookmarkablePageLink("pageLink", SearchPage.class, parameters); item.add(link); link.add(new Label("pageLabel", ""+displayPage)); calcPage++; } }); } }