| //------------------------------------------------------------------------------ |
| //Copyright (c) 2004, 2007 IBM Corporation. All Rights Reserved. |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.web.servlet; |
| |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.io.StringWriter; |
| import java.util.Locale; |
| import java.util.Properties; |
| |
| import javax.servlet.ServletConfig; |
| import javax.servlet.ServletException; |
| import javax.servlet.ServletOutputStream; |
| import javax.servlet.http.HttpServlet; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import javax.servlet.http.HttpSession; |
| |
| import org.apache.lucene.document.Document; |
| import org.apache.lucene.document.Field; |
| import org.apache.lucene.search.Hits; |
| import org.eclipse.epf.web.search.IndexLoader; |
| import org.eclipse.epf.web.search.IndexSearch; |
| import org.eclipse.epf.web.search.SearchResources; |
| import org.eclipse.epf.web.search.utils.StrUtil; |
| import org.eclipse.epf.web.search.utils.UNCUtil; |
| import org.eclipse.epf.web.search.utils.XMLUtil; |
| import org.eclipse.epf.web.search.utils.XSLTProcessor; |
| |
| public class SearchServlet extends HttpServlet { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private int _hitsPerPage = 10; |
| private static String _indexPath = null; |
| private static String _xslURL; |
| private static String _pathDocumentBase; |
| private static String _siteFolderName = null; |
| private String _currentSearchString; |
| private String _queryString; |
| private String _webAppName; |
| private Hits _hits; |
| private int _numHits; |
| private int _currentPage; |
| private String analyzerName; |
| |
| private HttpServletResponse _response; |
| |
| // Empty HTML. |
| public static final String EMPTY_HTML = "<html></html>"; //$NON-NLS-1$ |
| |
| private Properties xslParams = null; |
| |
| public void init(ServletConfig config) throws ServletException { |
| super.init(config); |
| |
| try { |
| _indexPath = config.getServletContext().getRealPath( |
| config.getInitParameter("searchIndex")); |
| _xslURL = config.getServletContext().getRealPath( |
| config.getInitParameter("xslFile")); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| protected void doGet(HttpServletRequest request, HttpServletResponse response) |
| throws ServletException, IOException { |
| |
| HttpSession session = request.getSession(); |
| |
| response.setContentType("text/html"); |
| PrintWriter out = response.getWriter(); |
| |
| _response = response; |
| request.setCharacterEncoding("UTF-8"); |
| String requestUrl = request.getRequestURL().toString(); |
| _pathDocumentBase = requestUrl.substring(0, requestUrl.lastIndexOf('/')); |
| |
| try { |
| _siteFolderName = IndexLoader.getSiteFolderName(_pathDocumentBase); |
| analyzerName = IndexLoader.getAnalyzerName(); |
| |
| synchronized(session) { |
| String results; |
| String action = request.getParameter("action"); |
| _webAppName = request.getContextPath(); |
| |
| if (action != null && action.length() > 0) { |
| |
| _hits = (Hits) session.getAttribute("hits"); |
| _queryString = (String) session.getAttribute("queryString"); |
| _numHits = ((Integer) session.getAttribute("numHits")).intValue(); |
| _currentPage = ((Integer) session.getAttribute("currentPage")).intValue(); |
| |
| if (action.indexOf("next") > -1) { |
| results = getPageResult(true); |
| session.setAttribute("numHits", new Integer(_numHits)); |
| session.setAttribute("currentPage", new Integer(_currentPage)); |
| out.println(results); |
| } else { |
| results = getPageResult(false); |
| session.setAttribute("numHits", new Integer(_numHits)); |
| session.setAttribute("currentPage", new Integer(_currentPage)); |
| out.println(results); |
| } |
| } else { |
| String searchString = request.getParameter("searchString"); |
| System.out.println("LD> searchString: " + searchString); |
| |
| if (searchString == null || searchString.length() == 0) { |
| response.sendError(HttpServletResponse.SC_NO_CONTENT); |
| return; |
| } |
| //searchString = URLEncoder.encode(searchString, "UTF-8"); |
| |
| String resultsPerPage = request.getParameter("hitsPerPage"); |
| if (resultsPerPage != null && resultsPerPage.length() > 0) { |
| _hitsPerPage = Integer.parseInt(resultsPerPage); |
| } |
| results = runSearch(searchString); |
| session.setAttribute("hits", _hits); |
| session.setAttribute("queryString", _queryString); |
| session.setAttribute("numHits", new Integer(_numHits)); |
| session.setAttribute("currentPage", new Integer(_currentPage)); |
| out.println(results); |
| } |
| } |
| |
| } catch (Exception ex) { |
| // ex.printStackTrace(); |
| writeOutputError(response.getOutputStream(), SearchResources |
| .getString("SearchFailed"), ex); |
| } |
| } |
| |
| /** |
| * Performs the advanced search. |
| */ |
| private String runSearch(final String searchString) { |
| |
| try { |
| |
| _queryString = searchString.replace(':', ' '); // RATLC00251228 |
| |
| _currentSearchString = IndexSearch.detectHyphenated(_queryString); // wordBuffer.toString(); |
| |
| if (_currentSearchString.length() == 0) { |
| return EMPTY_HTML; |
| } |
| |
| boolean safe = runQuery("contents"); |
| |
| String result = updateOutput(safe); |
| |
| return (result == null) ? EMPTY_HTML : result; |
| |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| |
| return EMPTY_HTML; |
| } |
| |
| private boolean runQuery(String searchField) { |
| boolean result = false; |
| //_currentSearchString = "\u57FA\u672C\u539F\u5247"; |
| try { |
| System.out.println("LD> _indexPath: " + _indexPath);//$NON-NLS-1$ |
| System.out.println("LD> _currentSearchString: " + _currentSearchString);//$NON-NLS-1$ |
| if (_currentSearchString != null) { |
| System.out.println("LD> unicodes: " + |
| escapeUnicodeString(_currentSearchString, false));//$NON-NLS-1$ |
| } |
| |
| System.out.println("LD> analyzerName: " + analyzerName);//$NON-NLS-1$ |
| |
| _hits = IndexSearch.search(_indexPath, _currentSearchString, searchField, analyzerName);// new |
| System.out.println("LD> _hits: " + |
| (_hits == null ? "null" : Integer.toString(_hits.length())));//$NON-NLS-1$ //$NON-NLS-2$ |
| |
| // SortedHits(hits); |
| |
| _numHits = _hits.length(); |
| |
| result = true; |
| } catch (Exception e1) { |
| e1.printStackTrace(); |
| _numHits = 0; |
| _hits = null; |
| } |
| _currentPage = 0; |
| |
| return result; |
| } |
| |
| /** |
| * Updates the results panel with the search output. |
| */ |
| private String updateOutput(boolean safe) { |
| String output = null; |
| |
| if (safe) { |
| output = generateOutput(_numHits, _currentPage); |
| } else { |
| _hits = null; |
| } |
| |
| return output; |
| } |
| |
| /** |
| * Generates the HTML representation for the given process search hits. |
| */ |
| private String generateOutput(int numHits, int pageNum) { |
| int init = pageNum * _hitsPerPage; |
| int max = Math.min(numHits, init + _hitsPerPage); |
| boolean nextEnabled = numHits > (_currentPage + 1) * _hitsPerPage; |
| boolean prevEnabled = _currentPage > 0; |
| |
| if (_hits == null) { |
| return null; |
| } |
| try { |
| |
| StringBuffer searchResultXML = new StringBuffer(); |
| |
| // encodeURL is just planning ahead in case this servlet is ever used in |
| // an application that does session tracking. If cookies are turned off, |
| // session tracking is usually accomplished by URL rewriting, so all URLs |
| // returned by servlets should be sent through encodeURL. |
| |
| searchResultXML |
| .append("<SearchResult") //$NON-NLS-1$ |
| .append(" totalHits=\"").append(numHits) //$NON-NLS-1$ |
| .append("\" initPageNum=\"").append((init > 0) ? init + 1 : (numHits < 1) ? 0 : 1) //$NON-NLS-1$ |
| .append("\" maxPageNum=\"").append(max) //$NON-NLS-1$ |
| .append("\" hitsPerPage=\"").append(_hitsPerPage) //$NON-NLS-1$ |
| .append("\" nextEnabled=\"").append(nextEnabled) //$NON-NLS-1$ |
| .append("\" prevEnabled=\"").append(prevEnabled) //$NON-NLS-1$ |
| .append("\" nextText=\"").append(SearchResources.getString("nextActionText")) //$NON-NLS-1$ |
| .append("\" prevText=\"").append(SearchResources.getString("previousActionText")) //$NON-NLS-1$ |
| .append("\" imagePath=\"").append(_pathDocumentBase + "/search/images/") //$NON-NLS-1$ |
| .append("\" searchString=\"").append(XMLUtil.escape(_queryString)) //$NON-NLS-1$ |
| .append("\" nextHref=\"").append(_response.encodeURL(_webAppName + "/SearchServlet?action=next")) //$NON-NLS-1$ |
| .append("\" prevHref=\"").append(_response.encodeURL(_webAppName + "/SearchServlet?action=prev")) //$NON-NLS-1$ |
| .append("\">"); //$NON-NLS-1$ |
| |
| for (int i = init; i < max; i++) { |
| Document doc = _hits.doc(i); |
| Field url = doc.getField("url"); //$NON-NLS-1$ |
| Field title = doc.getField("title"); //$NON-NLS-1$ |
| Field summary = doc.getField("summary"); //$NON-NLS-1$ |
| Field umaType = doc.getField("uma.type"); //$NON-NLS-1$ |
| |
| searchResultXML.append("<SearchHit"); //$NON-NLS-1$ |
| |
| if (url != null) { |
| StringBuffer bufferURL = new StringBuffer(); |
| String strUrl = url.stringValue(); |
| bufferURL.append(_pathDocumentBase).append( |
| strUrl.substring(strUrl.indexOf(_siteFolderName) |
| + _siteFolderName.length())); |
| |
| if (strUrl != null) { |
| strUrl = XMLUtil.escape(strUrl); |
| searchResultXML.append(" url=\"") //$NON-NLS-1$ |
| .append( |
| UNCUtil |
| .convertFilenameToUNC(bufferURL |
| .toString())).append("\""); //$NON-NLS-1$ |
| } |
| } |
| |
| if (title != null) { |
| String strTitle = title.stringValue(); |
| if (strTitle != null) { |
| strTitle = XMLUtil.escape(strTitle); |
| searchResultXML.append(" title=\"") //$NON-NLS-1$ |
| .append(strTitle).append("\""); //$NON-NLS-1$ |
| } |
| } |
| |
| if (summary != null) { |
| String strSummary = summary.stringValue(); |
| if (strSummary != null) { |
| strSummary = XMLUtil.escape(strSummary); |
| searchResultXML.append(" summary=\"") //$NON-NLS-1$ |
| .append(strSummary).append("\""); //$NON-NLS-1$ |
| } |
| } |
| |
| if (umaType != null) { |
| String[] keyWords = { "Product", "Descriptor", "Process", "Pattern", |
| "Type", "Definition", "Asset", "Considerations", "Category", |
| "Material", "Grouping", "Set", "Tool" }; |
| |
| String strUmaType = StrUtil.convertFirstLetterCase(umaType |
| .stringValue(), keyWords); |
| |
| if (strUmaType.equalsIgnoreCase("General_content")) { |
| searchResultXML.append(" icon=\"") //$NON-NLS-1$ |
| .append("Other.gif").append("\""); //$NON-NLS-1$ |
| } else { |
| strUmaType = XMLUtil.escape(strUmaType); |
| searchResultXML.append(" icon=\"") //$NON-NLS-1$ |
| .append(strUmaType).append(".gif").append("\""); //$NON-NLS-1$ |
| } |
| } |
| searchResultXML.append("/>"); //$NON-NLS-1$ |
| } |
| |
| searchResultXML.append("</SearchResult>"); //$NON-NLS-1$ |
| |
| StringWriter result = new StringWriter(); |
| |
| // System.out.println(searchResultXML.toString()); |
| |
| XSLTProcessor.transform(_xslURL, searchResultXML.toString(), xslParams, |
| result); |
| |
| //System.out.println(result.toString()); |
| |
| return result.toString(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| return EMPTY_HTML; |
| } |
| } |
| |
| private String getPageResult(boolean isNext) { |
| if (isNext) |
| _currentPage++; |
| else |
| _currentPage--; |
| String result = updateOutput(true); |
| |
| return (result == null) ? EMPTY_HTML : result; |
| } |
| |
| private void writeOutputError(ServletOutputStream os, String message, Exception ex) |
| throws ServletException { |
| Throwable t = ex; |
| System.out.println("Exceptio: " + ex); |
| if (ex instanceof java.lang.reflect.InvocationTargetException) |
| t = ((java.lang.reflect.InvocationTargetException) ex).getTargetException(); |
| try { |
| os.println("<hr>" + message + "<hr>"); |
| t.printStackTrace(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| //for debug |
| private static String escapeUnicodeString(String str, boolean escapeAscii) { |
| StringBuffer ostr = new StringBuffer(); |
| |
| for (int i = 0; i < str.length(); i++) { |
| |
| char ch = str.charAt(i); |
| |
| if (!escapeAscii && ((ch >= 0x0020) && (ch <= 0x007e))) { |
| ostr.append(ch); |
| } else { |
| |
| ostr.append("\\u") ; //$NON-NLS-1$ |
| |
| String hex = Integer.toHexString(str.charAt(i) & 0xFFFF); |
| for (int j = 0; j < 4 - hex.length(); j++) |
| ostr.append("0");//$NON-NLS-1$) |
| |
| ostr.append(hex.toUpperCase(Locale.ENGLISH)); |
| |
| } |
| |
| } |
| |
| return (new String(ostr)); |
| |
| } |
| |
| } |