xref: /OpenGrok/opengrok-web/src/main/webapp/search.jsp (revision 0d40e9d0d07acb46ebe450cbc6042a9705a36e41)
1*0d40e9d0SAdam Hornáček<%--
2*0d40e9d0SAdam Hornáček$Id$
3*0d40e9d0SAdam Hornáček
4*0d40e9d0SAdam HornáčekCDDL HEADER START
5*0d40e9d0SAdam Hornáček
6*0d40e9d0SAdam HornáčekThe contents of this file are subject to the terms of the
7*0d40e9d0SAdam HornáčekCommon Development and Distribution License (the "License").
8*0d40e9d0SAdam HornáčekYou may not use this file except in compliance with the License.
9*0d40e9d0SAdam Hornáček
10*0d40e9d0SAdam HornáčekSee LICENSE.txt included in this distribution for the specific
11*0d40e9d0SAdam Hornáčeklanguage governing permissions and limitations under the License.
12*0d40e9d0SAdam Hornáček
13*0d40e9d0SAdam HornáčekWhen distributing Covered Code, include this CDDL HEADER in each
14*0d40e9d0SAdam Hornáčekfile and include the License file at LICENSE.txt.
15*0d40e9d0SAdam HornáčekIf applicable, add the following below this CDDL HEADER, with the
16*0d40e9d0SAdam Hornáčekfields enclosed by brackets "[]" replaced with your own identifying
17*0d40e9d0SAdam Hornáčekinformation: Portions Copyright [yyyy] [name of copyright owner]
18*0d40e9d0SAdam Hornáček
19*0d40e9d0SAdam HornáčekCDDL HEADER END
20*0d40e9d0SAdam Hornáček
21*0d40e9d0SAdam HornáčekCopyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
22*0d40e9d0SAdam HornáčekPortions Copyright 2011 Jens Elkner.
23*0d40e9d0SAdam HornáčekPortions Copyright (c) 2017, Chris Fraire <cfraire@me.com>.
24*0d40e9d0SAdam Hornáček
25*0d40e9d0SAdam Hornáček--%>
26*0d40e9d0SAdam Hornáček<%@page import="javax.servlet.http.HttpServletResponse"%>
27*0d40e9d0SAdam Hornáček<%@page session="false" errorPage="error.jsp" import="
28*0d40e9d0SAdam Hornáčekorg.opensolaris.opengrok.search.Results,
29*0d40e9d0SAdam Hornáčekorg.opensolaris.opengrok.web.SearchHelper,
30*0d40e9d0SAdam Hornáčekorg.opensolaris.opengrok.web.SortOrder,
31*0d40e9d0SAdam Hornáčekorg.opensolaris.opengrok.web.Suggestion"
32*0d40e9d0SAdam Hornáček%><%
33*0d40e9d0SAdam Hornáček{
34*0d40e9d0SAdam Hornáček    PageConfig cfg = PageConfig.get(request);
35*0d40e9d0SAdam Hornáček    cfg.checkSourceRootExistence();
36*0d40e9d0SAdam Hornáček}
37*0d40e9d0SAdam Hornáček%><%@
38*0d40e9d0SAdam Hornáček
39*0d40e9d0SAdam Hornáčekinclude file="projects.jspf"
40*0d40e9d0SAdam Hornáček
41*0d40e9d0SAdam Hornáček%><%!
42*0d40e9d0SAdam Hornáček    private StringBuilder createUrl(HttpServletRequest request, SearchHelper sh, boolean menu) {
43*0d40e9d0SAdam Hornáček        StringBuilder url = new StringBuilder(64);
44*0d40e9d0SAdam Hornáček        QueryBuilder qb = sh.builder;
45*0d40e9d0SAdam Hornáček        if (menu) {
46*0d40e9d0SAdam Hornáček            url.append("search?");
47*0d40e9d0SAdam Hornáček        } else {
48*0d40e9d0SAdam Hornáček            Util.appendQuery(url, "sort", sh.order.toString());
49*0d40e9d0SAdam Hornáček        }
50*0d40e9d0SAdam Hornáček        if (qb != null) {
51*0d40e9d0SAdam Hornáček            Util.appendQuery(url, "q", qb.getFreetext());
52*0d40e9d0SAdam Hornáček            Util.appendQuery(url, "defs", qb.getDefs());
53*0d40e9d0SAdam Hornáček            Util.appendQuery(url, "refs", qb.getRefs());
54*0d40e9d0SAdam Hornáček            Util.appendQuery(url, "path", qb.getPath());
55*0d40e9d0SAdam Hornáček            Util.appendQuery(url, "hist", qb.getHist());
56*0d40e9d0SAdam Hornáček            Util.appendQuery(url, "type", qb.getType());
57*0d40e9d0SAdam Hornáček        }
58*0d40e9d0SAdam Hornáček        if (sh.projects != null && sh.projects.size() != 0) {
59*0d40e9d0SAdam Hornáček            Util.appendQuery(url, "project", PageConfig.get(request).getRequestedProjectsAsString());
60*0d40e9d0SAdam Hornáček        }
61*0d40e9d0SAdam Hornáček        return url;
62*0d40e9d0SAdam Hornáček    }
63*0d40e9d0SAdam Hornáček%><%
64*0d40e9d0SAdam Hornáček/* ---------------------- search.jsp start --------------------- */
65*0d40e9d0SAdam Hornáček{
66*0d40e9d0SAdam Hornáček    PageConfig cfg = PageConfig.get(request);
67*0d40e9d0SAdam Hornáček
68*0d40e9d0SAdam Hornáček    long starttime = System.currentTimeMillis();
69*0d40e9d0SAdam Hornáček
70*0d40e9d0SAdam Hornáček    SearchHelper searchHelper = cfg.prepareSearch();
71*0d40e9d0SAdam Hornáček    // N.b. searchHelper.destroy() is called via
72*0d40e9d0SAdam Hornáček    // WebappListener.requestDestroyed() on presence of the following
73*0d40e9d0SAdam Hornáček    // REQUEST_ATTR.
74*0d40e9d0SAdam Hornáček    request.setAttribute(SearchHelper.REQUEST_ATTR, searchHelper);
75*0d40e9d0SAdam Hornáček    request.setAttribute("search.jsp-query-start-time", starttime);
76*0d40e9d0SAdam Hornáček    searchHelper.prepareExec(cfg.getRequestedProjects()).executeQuery().prepareSummary();
77*0d40e9d0SAdam Hornáček    if (searchHelper.redirect != null) {
78*0d40e9d0SAdam Hornáček        response.sendRedirect(searchHelper.redirect);
79*0d40e9d0SAdam Hornáček    }
80*0d40e9d0SAdam Hornáček    if (searchHelper.errorMsg != null) {
81*0d40e9d0SAdam Hornáček        cfg.setTitle("Search Error");
82*0d40e9d0SAdam Hornáček        // Set status to Internal error. This should help to avoid caching
83*0d40e9d0SAdam Hornáček        // the page by some proxies.
84*0d40e9d0SAdam Hornáček        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
85*0d40e9d0SAdam Hornáček    } else {
86*0d40e9d0SAdam Hornáček        cfg.setTitle(cfg.getSearchTitle());
87*0d40e9d0SAdam Hornáček    }
88*0d40e9d0SAdam Hornáček    response.addCookie(new Cookie("OpenGrokSorting", URLEncoder.encode(searchHelper.order.toString(), "utf-8")));
89*0d40e9d0SAdam Hornáček}
90*0d40e9d0SAdam Hornáček%><%@
91*0d40e9d0SAdam Hornáček
92*0d40e9d0SAdam Hornáčekinclude file="httpheader.jspf"
93*0d40e9d0SAdam Hornáček
94*0d40e9d0SAdam Hornáček%><body>
95*0d40e9d0SAdam Hornáček<div id="page">
96*0d40e9d0SAdam Hornáček    <div id="whole_header">
97*0d40e9d0SAdam Hornáček        <div id="header"><%@
98*0d40e9d0SAdam Hornáček
99*0d40e9d0SAdam Hornáčekinclude file="pageheader.jspf"
100*0d40e9d0SAdam Hornáček
101*0d40e9d0SAdam Hornáček%>
102*0d40e9d0SAdam Hornáček        </div>
103*0d40e9d0SAdam Hornáček        <div id="Masthead">
104*0d40e9d0SAdam Hornáček            <a href="<%= request.getContextPath() %>/"><span id="home"></span>Home</a>
105*0d40e9d0SAdam Hornáček            <%-- TODO: jel: IMHO it should be move to menu.jspf as combobox --%>
106*0d40e9d0SAdam Hornáček            <div id="sortfield">
107*0d40e9d0SAdam Hornáček                <label for="sortby">Sort by</label>
108*0d40e9d0SAdam Hornáček                <%
109*0d40e9d0SAdam Hornáček{
110*0d40e9d0SAdam Hornáček    PageConfig cfg = PageConfig.get(request);
111*0d40e9d0SAdam Hornáček    SearchHelper searchHelper = (SearchHelper) request.getAttribute(SearchHelper.REQUEST_ATTR);
112*0d40e9d0SAdam Hornáček    StringBuilder url = createUrl(request, searchHelper, true).append("&amp;sort=");
113*0d40e9d0SAdam Hornáček    int ordcnt = 0;
114*0d40e9d0SAdam Hornáček    for (SortOrder o : SortOrder.values()) {
115*0d40e9d0SAdam Hornáček        if (searchHelper.order == o) {
116*0d40e9d0SAdam Hornáček                    %><span class="active"><%= o.getDesc() %></span><%
117*0d40e9d0SAdam Hornáček        } else {
118*0d40e9d0SAdam Hornáček                    %><a href="<%= url %><%= o %>"><%= o.getDesc() %></a><%
119*0d40e9d0SAdam Hornáček        }
120*0d40e9d0SAdam Hornáček        ordcnt++;
121*0d40e9d0SAdam Hornáček        if (ordcnt != (SortOrder.values().length)) {
122*0d40e9d0SAdam Hornáček            %> | <%
123*0d40e9d0SAdam Hornáček        }
124*0d40e9d0SAdam Hornáček    }
125*0d40e9d0SAdam Hornáček}
126*0d40e9d0SAdam Hornáček                %>
127*0d40e9d0SAdam Hornáček            </div>
128*0d40e9d0SAdam Hornáček        </div>
129*0d40e9d0SAdam Hornáček        <div id="bar">
130*0d40e9d0SAdam Hornáček        </div>
131*0d40e9d0SAdam Hornáček        <div id="menu"><%@
132*0d40e9d0SAdam Hornáček
133*0d40e9d0SAdam Hornáčekinclude file="menu.jspf"
134*0d40e9d0SAdam Hornáček
135*0d40e9d0SAdam Hornáček%>
136*0d40e9d0SAdam Hornáček        </div>
137*0d40e9d0SAdam Hornáček    </div>
138*0d40e9d0SAdam Hornáček
139*0d40e9d0SAdam Hornáček    <div id="results"> <%
140*0d40e9d0SAdam Hornáček{
141*0d40e9d0SAdam Hornáček    PageConfig cfg = PageConfig.get(request);
142*0d40e9d0SAdam Hornáček    SearchHelper searchHelper = (SearchHelper) request.getAttribute(SearchHelper.REQUEST_ATTR);
143*0d40e9d0SAdam Hornáček    Long starttime = (Long) request.getAttribute("search.jsp-query-start-time");
144*0d40e9d0SAdam Hornáček    // TODO spellchecking cycle below is not that great and we only create
145*0d40e9d0SAdam Hornáček    // suggest links for every token in query, not for a query as whole
146*0d40e9d0SAdam Hornáček    if (searchHelper.errorMsg != null) {
147*0d40e9d0SAdam Hornáček        %><h3>Error</h3><p class="pagetitle"><%
148*0d40e9d0SAdam Hornáček        if (searchHelper.errorMsg.startsWith((SearchHelper.PARSE_ERROR_MSG))) {
149*0d40e9d0SAdam Hornáček            %><%= Util.htmlize(SearchHelper.PARSE_ERROR_MSG) %>
150*0d40e9d0SAdam Hornáček            <br/>You might try to enclose your search term in quotes,
151*0d40e9d0SAdam Hornáček            <a href="help.jsp#escaping">escape special characters</a>
152*0d40e9d0SAdam Hornáček            with <b>\</b>, or read the <a href="help.jsp">Help</a>
153*0d40e9d0SAdam Hornáček            on the query language. Error message from parser:<br/>
154*0d40e9d0SAdam Hornáček            <%= Util.htmlize(searchHelper.errorMsg.substring(
155*0d40e9d0SAdam Hornáček                        SearchHelper.PARSE_ERROR_MSG.length())) %><%
156*0d40e9d0SAdam Hornáček        } else {
157*0d40e9d0SAdam Hornáček            %><%= Util.htmlize(searchHelper.errorMsg) %><%
158*0d40e9d0SAdam Hornáček        }%></p><%
159*0d40e9d0SAdam Hornáček    } else if (searchHelper.hits == null) {
160*0d40e9d0SAdam Hornáček        %><p class="pagetitle">No hits</p><%
161*0d40e9d0SAdam Hornáček    } else if (searchHelper.hits.length == 0) {
162*0d40e9d0SAdam Hornáček        List<Suggestion> hints = searchHelper.getSuggestions();
163*0d40e9d0SAdam Hornáček        for (Suggestion hint : hints) {
164*0d40e9d0SAdam Hornáček        %><p class="suggestions"><font color="#cc0000">Did you mean (for <%= hint.name %>)</font>:<%
165*0d40e9d0SAdam Hornáček	  if (hint.freetext!=null) {
166*0d40e9d0SAdam Hornáček	    for (String word : hint.freetext) {
167*0d40e9d0SAdam Hornáček            %> <a href="search?q=<%= Util.URIEncode(word) %>"><%=
168*0d40e9d0SAdam Hornáček                Util.htmlize(word) %></a> &nbsp; <%
169*0d40e9d0SAdam Hornáček	    }
170*0d40e9d0SAdam Hornáček	  }
171*0d40e9d0SAdam Hornáček	  if (hint.refs!=null)  {
172*0d40e9d0SAdam Hornáček	    for (String word : hint.refs) {
173*0d40e9d0SAdam Hornáček            %> <a href="search?refs=<%= Util.URIEncode(word) %>"><%=
174*0d40e9d0SAdam Hornáček                Util.htmlize(word) %></a> &nbsp; <%
175*0d40e9d0SAdam Hornáček	    }
176*0d40e9d0SAdam Hornáček	  }
177*0d40e9d0SAdam Hornáček	  if (hint.defs!=null) {
178*0d40e9d0SAdam Hornáček	    for (String word : hint.defs) {
179*0d40e9d0SAdam Hornáček            %> <a href="search?defs=<%= Util.URIEncode(word) %>"><%=
180*0d40e9d0SAdam Hornáček                Util.htmlize(word) %></a> &nbsp; <%
181*0d40e9d0SAdam Hornáček            }
182*0d40e9d0SAdam Hornáček	  }
183*0d40e9d0SAdam Hornáček        %></p><%
184*0d40e9d0SAdam Hornáček        }
185*0d40e9d0SAdam Hornáček        %>
186*0d40e9d0SAdam Hornáček        <p class="pagetitle"> Your search <b><%
187*0d40e9d0SAdam Hornáček            Util.htmlize(searchHelper.query.toString(), out); %></b>
188*0d40e9d0SAdam Hornáček            did not match any files.
189*0d40e9d0SAdam Hornáček            <br/> Suggestions:<br/>
190*0d40e9d0SAdam Hornáček        </p>
191*0d40e9d0SAdam Hornáček        <ul>
192*0d40e9d0SAdam Hornáček            <li>Make sure all terms are spelled correctly.</li>
193*0d40e9d0SAdam Hornáček            <li>Try different keywords.</li>
194*0d40e9d0SAdam Hornáček            <li>Try more general keywords.</li>
195*0d40e9d0SAdam Hornáček            <li>Use 'wil*' cards if you are looking for partial match.</li>
196*0d40e9d0SAdam Hornáček        </ul>
197*0d40e9d0SAdam Hornáček        <p><b>Completed in <%= System.currentTimeMillis() - starttime
198*0d40e9d0SAdam Hornáček            %> milliseconds</b></p>
199*0d40e9d0SAdam Hornáček	<%
200*0d40e9d0SAdam Hornáček    } else {
201*0d40e9d0SAdam Hornáček        int start = searchHelper.start;
202*0d40e9d0SAdam Hornáček        int max = searchHelper.maxItems;
203*0d40e9d0SAdam Hornáček        long totalHits = searchHelper.totalHits;
204*0d40e9d0SAdam Hornáček        long thispage = Math.min(totalHits - start, max);  // number of items to display on the current page
205*0d40e9d0SAdam Hornáček        // We have a lots of results to show: create a slider for
206*0d40e9d0SAdam Hornáček        String slider = Util.createSlider(start, max, totalHits, request);
207*0d40e9d0SAdam Hornáček        %>
208*0d40e9d0SAdam Hornáček        <p class="pagetitle">Searched <b><%
209*0d40e9d0SAdam Hornáček            Util.htmlize(searchHelper.query.toString(), out);
210*0d40e9d0SAdam Hornáček            %></b> (Results <b> <%= start + 1 %> - <%= thispage + start
211*0d40e9d0SAdam Hornáček            %></b> of <b><%= totalHits %></b>) sorted by <%=
212*0d40e9d0SAdam Hornáček            searchHelper.order.getDesc() %></p><%
213*0d40e9d0SAdam Hornáček        if (slider.length() > 0) {
214*0d40e9d0SAdam Hornáček        %>
215*0d40e9d0SAdam Hornáček        <p class="slider"><%= slider %></p><%
216*0d40e9d0SAdam Hornáček        }
217*0d40e9d0SAdam Hornáček        %>
218*0d40e9d0SAdam Hornáček        <table><%
219*0d40e9d0SAdam Hornáček        Results.prettyPrint(out, searchHelper, start, start + thispage);
220*0d40e9d0SAdam Hornáček        %>
221*0d40e9d0SAdam Hornáček        </table>
222*0d40e9d0SAdam Hornáček        <p><b>Completed in <%= System.currentTimeMillis() - starttime
223*0d40e9d0SAdam Hornáček            %> milliseconds</b></p><%
224*0d40e9d0SAdam Hornáček        if (slider.length() > 0) {
225*0d40e9d0SAdam Hornáček        %>
226*0d40e9d0SAdam Hornáček        <p class="slider"><%= slider %></p><%
227*0d40e9d0SAdam Hornáček        }
228*0d40e9d0SAdam Hornáček        %>
229*0d40e9d0SAdam Hornáček    </div><%
230*0d40e9d0SAdam Hornáček    }
231*0d40e9d0SAdam Hornáček    // Note that searchHelper.destroy() is called via WebappListener.requestDestroyed().
232*0d40e9d0SAdam Hornáček}
233*0d40e9d0SAdam Hornáček/* ---------------------- search.jsp end --------------------- */
234*0d40e9d0SAdam Hornáček%><%@
235*0d40e9d0SAdam Hornáček
236*0d40e9d0SAdam Hornáčekinclude file="foot.jspf"
237*0d40e9d0SAdam Hornáček
238*0d40e9d0SAdam Hornáček%>
239