📄 searchservlet.java
字号:
sb.append( ""+this.searchable ); sb.append( "," ); sb.append( ""+this.speller ); sb.append( "," ); if (this.quickLinks==null) sb.append("null"); else sb.append( "has quicklinks" ); sb.append( ")" ); return sb.toString(); } } // Search Menu is sorted by internal ID. protected SortedMap searchMenu = new TreeMap(); /** * Define Search Menu Items. * To configure this Servlet for your installation, * override the given sample code with your own implementation. * * Each instance of <code>SearchMenuItem</code> * defines a choice in a drop-down * select box as to what to search. The displayable name is the text * in the drop-down box, but the choices are sorted * alphabetically by id. * * A Searchable here doesn't have to be a SearchCollection. It could * be any Searchable. For example, you can designate virtual * collections with CompositeSearchable or SubsetSearchable. * @throws IOException if unable to completely initialize menu due to communication problems * @throws ServletException if other fatal problem occurs **/ protected void initSearchMenu() throws ServletException, IOException { SortedMap newMenu = new TreeMap(); IOException exception = null; /* Define a menu item for each Ultraseek search collection */ boolean needDefault = false; try { Collection collections = ultraseek.getSearchCollections(); Iterator i = collections.iterator(); while (i.hasNext()) { UltraseekCollection collection = (UltraseekCollection) i.next(); if (collection.getDefaultSearch() && !collection.getDefaultShow()) needDefault = true; if (!collection.getDefaultShow()) continue; SearchMenuItem sm = new SearchMenuItem(collection.getID()); sm.displayName = collection.getName(); sm.server = ultraseek; sm.searchable = collection; sm.speller = ultraseek.getSpeller(collection); sm.quickLinks = ultraseek.getQuickLinksSearchable(collection); newMenu.put(sm.ID,sm); } } catch (IOException e) { needDefault = true; log( "Problem in initSearchMenu", e ); exception = e; } /* Define a menu item to search the default-searchable collections * This also ensures the menu is never empty. * We need this master item when the user could pick from more * than 1 search collection, or when there are hidden collections * that are only searched as part of a default search. */ if (needDefault || newMenu.size() != 1) { SearchMenuItem sm = new SearchMenuItem(""); // Pseudo ID sm.displayName = "Default Collections"; sm.server = ultraseek; sm.searchable = ultraseek; sm.speller = ultraseek.getSpeller(); sm.quickLinks = ultraseek.getQuickLinksSearchable(); newMenu.put(sm.ID,sm); } if (exception==null || searchMenu.size() < 1) searchMenu = newMenu; if (exception!=null) throw new XPAIOException("",exception); } /** * Re-initialize search menus, etc., after a configuration change * was detected on the Ultraseek server. * @throws IOException if initialization could not complete due to communication problems. * @throws ServletException if initialization was incorrect */ public void reinitialize() throws IOException, ServletException { // REMIND: really should change all 3 configuration values // at the same time - to prevent wrong menus being used with an Ultraseek // server. initUltraseek(); if (ultraseek==null) throw new ServletException("Ultraseek server not set by initUltraseek()"); initSearchMenu(); if (searchMenu == null || searchMenu.size() < 1) throw new ServletException("searchMenu not set up by initSearchMenu()" ); initServerStyleSettings(); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException { try { SearchRequest sr = makeSearchRequest(req,resp); sr.handle(); } catch (ServletException e) { DEBUG(resp,e); throw e; } catch (Exception e) { DEBUG(resp,e); throw new ServletException(e.getLocalizedMessage(),e); } } /** * Make a new SearchRequest instance. * Override this method if you need to specialize the * SearchServlet's SearchRequest class. */ protected SearchRequest makeSearchRequest(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { return new SearchRequest(req,resp); } // Results sorting criteria protected static final int RF_RELEVANCE = 0; // Sort by relevance protected static final int RF_RELEVANCE_WITH_DATE = 1; // Sort by recent relevance protected static final int RF_INTERLEAVE_SITES = 2; // Not supported protected static final int RF_TITLE_SORT = 3; // Sort by title protected static final int RF_DATE_SORT = 4; // Sort by date // Summary display criteria protected static final int LK_WITH_SUMMARIES = 1; // default protected static final int LK_NO_SUMMARIES = 2; // Type of search request // Used for both qm and rq parameters // qm == Mode of NEXT query (new search / search these results) // rq == Mode of THIS query (new search / search results of prior query) protected static final int QM_NEW_SEARCH = 0; // default protected static final int QM_SEARCH_THESE_RESULTS = 1; protected static final int QM_SEARCH_INTERNET = 2; // Not supported in SearchServlet protected static final int QM_SEARCH_THIS_TOPIC = 3; // Site Clustering protected static final int SC_NO_GROUPING = 0; // default protected static final int SC_GROUP_BY_LOCATION = 1; protected static final int SC_GROUP_BY_TOPIC = 2; // "group_results_by_topic" /** * Default menu for where-to-search in Advanced Query form menu. * Each style setting has its own defintion of this list. * <p> * For Ultraseek version 5.1.1 and beyond this map is * only used if the SearchServlet initializes before the Ultraseek * server is available. */ protected List advanced_query_fields = new ArrayList(); { advanced_query_fields.add( Arrays.asList( new String[] {"","in the body"} )); advanced_query_fields.add( Arrays.asList( new String[] {"title:","in the title"})); advanced_query_fields.add( Arrays.asList( new String[] {"url:","in the URL"})); advanced_query_fields.add( Arrays.asList( new String[] {"site:","in the site name"})); advanced_query_fields.add( Arrays.asList( new String[] {"link:","in a link"})); advanced_query_fields.add( Arrays.asList( new String[] {"imagelink:","in an image link"})); advanced_query_fields.add( Arrays.asList( new String[] {"alt:","in image alt text"})); advanced_query_fields.add( Arrays.asList( new String[] {"description:","in the description"})); advanced_query_fields.add( Arrays.asList( new String[] {"keywords:","in the keywords"})); advanced_query_fields.add( Arrays.asList( new String[] {"anchor:","in remote anchor text"})); } /** * Default style settings. * Used when style settings are unavailable from the Ultraseek server * (eg: if the server is less than version 5.1.1). * <p> * This map is also used when the SearchServlet supports style settings * that are not supported by the remote Ultraseek server version. * For instance, the version 5.2 <code>"default_qs"</code> style setting is * defined by this <code>Map</code> when the remote Ultraseek server * is less than version 5.2. */ protected Map defaultStyleSettings = new HashMap(); { /** Default values from Ultraseek. ** Used when no style settings available. */ defaultStyleSettings.put("default_sc", "" + SC_NO_GROUPING ); defaultStyleSettings.put("show_word_scores", "0" ); defaultStyleSettings.put("search_internet", "1" ); // not supported defaultStyleSettings.put("default_qm", "" + QM_NEW_SEARCH ); defaultStyleSettings.put("default_ql", "" ); defaultStyleSettings.put("default_nh", "10" ); defaultStyleSettings.put("default_lk", new Integer(LK_WITH_SUMMARIES) ); defaultStyleSettings.put("default_pw", "100%" ); defaultStyleSettings.put("query_form_above", "1" ); defaultStyleSettings.put("query_form_below", "0" ); defaultStyleSettings.put("advanced_query_fields", advanced_query_fields ); defaultStyleSettings.put("default_rf", "" + RF_RELEVANCE ); defaultStyleSettings.put("default_qp", "" ); defaultStyleSettings.put("language", "en" ); // ignored - browser setting used defaultStyleSettings.put("header_html", "" ); defaultStyleSettings.put("footer_html", "" ); // #topics defaultStyleSettings.put("default_ht", "0" ); defaultStyleSettings.put("index_form_above", "1" ); defaultStyleSettings.put("index_form_below", "0" ); defaultStyleSettings.put("browse_form_above", "1" ); defaultStyleSettings.put("browse_form_below", "0" ); defaultStyleSettings.put("related_topics_above", "1" ); defaultStyleSettings.put("related_topics_below", "0" ); defaultStyleSettings.put("related_topics_child_indent", "1" ); defaultStyleSettings.put("inline_topics_fullpath", "0" ); defaultStyleSettings.put("group_results_by_topic", "0" ); defaultStyleSettings.put("related_topics_childcount", "0" ); defaultStyleSettings.put("related_topics_columns", "1" ); defaultStyleSettings.put("related_topics_count", "6" ); defaultStyleSettings.put("related_topics_fullpath", "1" ); defaultStyleSettings.put("subtopics_above", "1" ); defaultStyleSettings.put("subtopics_below", "0" ); defaultStyleSettings.put("subtopics_columns", "3" ); defaultStyleSettings.put("subtopics_child_indent", "1" ); defaultStyleSettings.put("subtopics_childcount", "3" ); defaultStyleSettings.put("topics_child_indent", "1" ); defaultStyleSettings.put("topics_childcount", "3" ); defaultStyleSettings.put("topics_columns", "3" ); defaultStyleSettings.put("show_all_topics", "0" ); /* Ultraseek 5.2 style settings */ defaultStyleSettings.put("default_qs", ""); defaultStyleSettings.put("enable_spell", "1"); defaultStyleSettings.put("enable_passages", "1"); // Not supported (always enabled) defaultStyleSettings.put("lowercase_query", "0"); } /** * Ultraseek Server display settings that are not style specific * For Ultraseek version 5.1.1 or greater, this map is filled * with values fetched from the Ultraseek server. * The default settings are only used for Ultraseek server * less than version 5.1.1. */ protected Map serverStyleSettings = new HashMap(); { serverStyleSettings.put("default_sc_subhits", new Integer(3) ); serverStyleSettings.put("average_group_size", new Integer(5) ); serverStyleSettings.put("group_score_threshold", new Integer(10) ); serverStyleSettings.put("filter_nhits", new Integer(100) ); } /** * Pick up values for server-wide display style options from the Ultraseek * server. * @throws IOException if unable to read all style settings */ protected void initServerStyleSettings() throws IOException { try { if (!ultraseek.versionAtLeast(5,1,1)) return; Iterator it = serverStyleSettings.keySet().iterator(); while (it.hasNext()) { String key = (String) it.next(); Object val = ultraseek.getValue(key); serverStyleSettings.put(key, val); } } catch (IOException e) { log( "Problem fetching serverStyleSettings", e ); throw e; } } /** Used in advanced menu for "should contain" / "must contain" / "must not contain" menu */ protected List operatorOptions = new ArrayList(); { operatorOptions.add( Arrays.asList( new String[] {"", "should contain"} )); operatorOptions.add( Arrays.asList( new String[] {"+", "must contain"} )); operatorOptions.add( Arrays.asList( new String[] {"-", "must not contain"} )); } /** Used in advanced menu for "the words" / "the phrase" menu. */ protected List typeOptions = new ArrayList(); { typeOptions.add( Arrays.asList( new String[] {"w", "the words"})); typeOptions.add( Arrays.asList( new String[] {"p", "the phrase"})); } /** * Ultraseek server uses a Unicode Ellipsis character to separate * passages (snippets) in the description of a <code>SearchResult</code>. * Most browers do not display the Unicode Ellipsis very well, * so the servlet emits a different visual display. * <p> * The default value is <code><pre>"SPACE<b>...</b>SPACE"</pre></code>. * @see SearchRequest#printDescription */ protected static String DESCRIPTION_SEPARATOR_REPLACEMENT = " <b>...</b> "; /** * Represents an HTTP Search Request and Response. * <p> * One instance of <code>SearchRequest</code> is made for each search request. */ protected class SearchRequest { HttpServletRequest req; // The Servlet request HttpServletResponse resp; // The Servlet response HttpSession session; // Determined from req PrintWriter out; // Output for Servlet Response Date queryArrivalTime; // Time to use for query logging Locale locale; // Determined from la and/or accept-language String page_output_charset; // The character set of the result HTML Map textMap; // Translation matrix // Properties set by determineSearchCollection() SearchMenuItem menuItem = null; // Collection(s) being searched SearchServer server; // Determined from col Searchable searchable; // Determined from col SpellServer speller; // Determined from col Searchable quickLinks; // Determined from col // Parameters parsed from HttpServletRequest req by parseQueryParameters() String col; // Collections to search String la; // Language: String fs; // Find Similar: URL to find similar results to String pw; // Page Width 0-100% //String qc; // Which collections are shown (Not Supported) int st; // Starting Hit number (or starting group number) int nh; // Number of hits to show (or number of groups) int qm; // query mode: 0==New Search; 1==Search These Results, 2==internet int rq; // requested query: 0==New Search; 1==Search prior Results, 2==internet int lk; // look of results: 1==With Summary; 2==No Summary int rf; // Relevance filter: 0-relevance, 2-recent-relevance 4-by date, 3-by title int sc; // Site Cluster: 0==don't group; 1==group by location; 2==by topic int pf; // previous results filter (prior value of rf) String qp; // Query prefix: Used for Admin-specified restriction String qs; // Query Suffix: Used for Admin-specified restriction String oq; // Old Query: Used with "search these results" String qt; // Query Text String ql; // Query Level: a==Advanced form; otherwise standard form String ct; // Current Topic String ht; // Home Topic: String ex; // Thesaurus Expansion Terms String style; // Named display style //int si; // Search the Internet (Not supported)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -